1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Firmware I/O code for mac80211 Prism54 drivers 4 * 5 * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> 6 * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de> 7 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net> 8 * 9 * Based on: 10 * - the islsm (softmac prism54) driver, which is: 11 * Copyright 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al. 12 * - stlc45xx driver 13 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies). 14 */ 15 16 #include <linux/slab.h> 17 #include <linux/firmware.h> 18 #include <linux/etherdevice.h> 19 #include <linux/export.h> 20 21 #include <net/mac80211.h> 22 23 #include "p54.h" 24 #include "eeprom.h" 25 #include "lmac.h" 26 27 int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw) 28 { 29 struct p54_common *priv = dev->priv; 30 struct exp_if *exp_if; 31 struct bootrec *bootrec; 32 u32 *data = (u32 *)fw->data; 33 u32 *end_data = (u32 *)fw->data + (fw->size >> 2); 34 u8 *fw_version = NULL; 35 size_t len; 36 int i; 37 int maxlen; 38 39 if (priv->rx_start) 40 return 0; 41 42 while (data < end_data && *data) 43 data++; 44 45 while (data < end_data && !*data) 46 data++; 47 48 bootrec = (struct bootrec *) data; 49 50 while (bootrec->data <= end_data && (bootrec->data + 51 (len = le32_to_cpu(bootrec->len))) <= end_data) { 52 u32 code = le32_to_cpu(bootrec->code); 53 switch (code) { 54 case BR_CODE_COMPONENT_ID: 55 if (len < sizeof(struct bootrec_comp_id) / 56 sizeof(*bootrec->data)) { 57 wiphy_err(priv->hw->wiphy, 58 "firmware component ID is too short\n"); 59 return -EINVAL; 60 } 61 62 priv->fw_interface = be32_to_cpup((__be32 *) 63 bootrec->data); 64 switch (priv->fw_interface) { 65 case FW_LM86: 66 case FW_LM20: 67 case FW_LM87: { 68 char *iftype = (char *)bootrec->data; 69 wiphy_info(priv->hw->wiphy, 70 "p54 detected a LM%c%c firmware\n", 71 iftype[2], iftype[3]); 72 break; 73 } 74 case FW_FMAC: 75 default: 76 wiphy_err(priv->hw->wiphy, 77 "unsupported firmware\n"); 78 return -ENODEV; 79 } 80 break; 81 case BR_CODE_COMPONENT_VERSION: 82 if (len < DIV_ROUND_UP(sizeof(struct bootrec_comp_ver), 83 sizeof(*bootrec->data))) { 84 wiphy_err(priv->hw->wiphy, 85 "firmware component version is too short\n"); 86 return -EINVAL; 87 } 88 89 /* 24 bytes should be enough for all firmwares */ 90 if (strnlen((unsigned char *)bootrec->data, 91 sizeof(struct bootrec_comp_ver)) < 92 sizeof(struct bootrec_comp_ver)) 93 fw_version = (unsigned char *)bootrec->data; 94 break; 95 case BR_CODE_DESCR: { 96 struct bootrec_desc *desc = 97 (struct bootrec_desc *)bootrec->data; 98 u32 rx_start, rx_end; 99 100 /* 0xa is the shortest descriptor in supported firmware. */ 101 if (len < 0xa) { 102 wiphy_err(priv->hw->wiphy, 103 "firmware descriptor is too short\n"); 104 return -EINVAL; 105 } 106 107 rx_start = le32_to_cpu(desc->rx_start); 108 rx_end = le32_to_cpu(desc->rx_end); 109 if (rx_end < 0x3500 || rx_end - 0x3500 <= rx_start) { 110 wiphy_err(priv->hw->wiphy, 111 "firmware descriptor has invalid RX range\n"); 112 return -EINVAL; 113 } 114 115 priv->rx_start = rx_start; 116 priv->rx_end = rx_end - 0x3500; 117 priv->headroom = desc->headroom; 118 priv->tailroom = desc->tailroom; 119 priv->privacy_caps = desc->privacy_caps; 120 priv->rx_keycache_size = desc->rx_keycache_size; 121 if (le32_to_cpu(bootrec->len) == 11) 122 priv->rx_mtu = le16_to_cpu(desc->rx_mtu); 123 else 124 priv->rx_mtu = (size_t) 125 0x620 - priv->tx_hdr_len; 126 maxlen = priv->tx_hdr_len + /* USB devices */ 127 sizeof(struct p54_rx_data) + 128 4 + /* rx alignment */ 129 IEEE80211_MAX_FRAG_THRESHOLD; 130 if (priv->rx_mtu > maxlen && PAGE_SIZE == 4096) { 131 printk(KERN_INFO "p54: rx_mtu reduced from %d " 132 "to %d\n", priv->rx_mtu, maxlen); 133 priv->rx_mtu = maxlen; 134 } 135 break; 136 } 137 case BR_CODE_EXPOSED_IF: 138 exp_if = (struct exp_if *) bootrec->data; 139 for (i = 0; i < (len * sizeof(*exp_if) / 4); i++) 140 if (exp_if[i].if_id == cpu_to_le16(IF_ID_LMAC)) 141 priv->fw_var = le16_to_cpu(exp_if[i].variant); 142 break; 143 case BR_CODE_DEPENDENT_IF: 144 break; 145 case BR_CODE_END_OF_BRA: 146 case LEGACY_BR_CODE_END_OF_BRA: 147 end_data = NULL; 148 break; 149 default: 150 break; 151 } 152 bootrec = (struct bootrec *)&bootrec->data[len]; 153 } 154 155 if (fw_version) { 156 wiphy_info(priv->hw->wiphy, 157 "FW rev %s - Softmac protocol %x.%x\n", 158 fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); 159 snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version), 160 "%.19s - %x.%x", fw_version, 161 priv->fw_var >> 8, priv->fw_var & 0xff); 162 } 163 164 if (priv->fw_var < 0x500) 165 wiphy_info(priv->hw->wiphy, 166 "you are using an obsolete firmware. visit https://wireless.docs.kernel.org/en/latest/en/users/drivers/p54.html and grab one for \"kernel >= 2.6.28\"!\n"); 167 168 if (priv->fw_var >= 0x300) { 169 /* Firmware supports QoS, use it! */ 170 171 if (priv->fw_var >= 0x500) { 172 priv->tx_stats[P54_QUEUE_AC_VO].limit = 16; 173 priv->tx_stats[P54_QUEUE_AC_VI].limit = 16; 174 priv->tx_stats[P54_QUEUE_AC_BE].limit = 16; 175 priv->tx_stats[P54_QUEUE_AC_BK].limit = 16; 176 } else { 177 priv->tx_stats[P54_QUEUE_AC_VO].limit = 3; 178 priv->tx_stats[P54_QUEUE_AC_VI].limit = 4; 179 priv->tx_stats[P54_QUEUE_AC_BE].limit = 3; 180 priv->tx_stats[P54_QUEUE_AC_BK].limit = 2; 181 } 182 priv->hw->queues = P54_QUEUE_AC_NUM; 183 } 184 185 wiphy_info(priv->hw->wiphy, 186 "cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n", 187 (priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no", 188 (priv->privacy_caps & 189 (BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL)) 190 ? "YES" : "no", 191 (priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) 192 ? "YES" : "no"); 193 194 if (priv->rx_keycache_size) { 195 /* 196 * NOTE: 197 * 198 * The firmware provides at most 255 (0 - 254) slots 199 * for keys which are then used to offload decryption. 200 * As a result the 255 entry (aka 0xff) can be used 201 * safely by the driver to mark keys that didn't fit 202 * into the full cache. This trick saves us from 203 * keeping a extra list for uploaded keys. 204 */ 205 206 priv->used_rxkeys = bitmap_zalloc(priv->rx_keycache_size, 207 GFP_KERNEL); 208 if (!priv->used_rxkeys) 209 return -ENOMEM; 210 } 211 212 return 0; 213 } 214 EXPORT_SYMBOL_GPL(p54_parse_firmware); 215 216 static struct sk_buff *p54_alloc_skb(struct p54_common *priv, u16 hdr_flags, 217 u16 payload_len, u16 type, gfp_t memflags) 218 { 219 struct p54_hdr *hdr; 220 struct sk_buff *skb; 221 size_t frame_len = sizeof(*hdr) + payload_len; 222 223 if (frame_len > P54_MAX_CTRL_FRAME_LEN) 224 return NULL; 225 226 if (unlikely(skb_queue_len(&priv->tx_pending) > 64)) 227 return NULL; 228 229 skb = __dev_alloc_skb(priv->tx_hdr_len + frame_len, memflags); 230 if (!skb) 231 return NULL; 232 skb_reserve(skb, priv->tx_hdr_len); 233 234 hdr = skb_put(skb, sizeof(*hdr)); 235 hdr->flags = cpu_to_le16(hdr_flags); 236 hdr->len = cpu_to_le16(payload_len); 237 hdr->type = cpu_to_le16(type); 238 hdr->tries = hdr->rts_tries = 0; 239 return skb; 240 } 241 242 int p54_download_eeprom(struct p54_common *priv, void *buf, 243 u16 offset, u16 len) 244 { 245 struct p54_eeprom_lm86 *eeprom_hdr; 246 struct sk_buff *skb; 247 size_t eeprom_hdr_size; 248 int ret = 0; 249 long time_left; 250 251 if (priv->fw_var >= 0x509) 252 eeprom_hdr_size = sizeof(*eeprom_hdr); 253 else 254 eeprom_hdr_size = 0x4; 255 256 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, eeprom_hdr_size + 257 len, P54_CONTROL_TYPE_EEPROM_READBACK, 258 GFP_KERNEL); 259 if (unlikely(!skb)) 260 return -ENOMEM; 261 262 mutex_lock(&priv->eeprom_mutex); 263 priv->eeprom = buf; 264 priv->eeprom_slice_size = len; 265 eeprom_hdr = skb_put(skb, eeprom_hdr_size + len); 266 267 if (priv->fw_var < 0x509) { 268 eeprom_hdr->v1.offset = cpu_to_le16(offset); 269 eeprom_hdr->v1.len = cpu_to_le16(len); 270 } else { 271 eeprom_hdr->v2.offset = cpu_to_le32(offset); 272 eeprom_hdr->v2.len = cpu_to_le16(len); 273 eeprom_hdr->v2.magic2 = 0xf; 274 memcpy(eeprom_hdr->v2.magic, (const char *)"LOCK", 4); 275 } 276 277 p54_tx(priv, skb); 278 279 time_left = wait_for_completion_interruptible_timeout( 280 &priv->eeprom_comp, HZ); 281 if (time_left <= 0) { 282 wiphy_err(priv->hw->wiphy, 283 "device does not respond or signal received!\n"); 284 ret = -EBUSY; 285 } 286 priv->eeprom = NULL; 287 priv->eeprom_slice_size = 0; 288 mutex_unlock(&priv->eeprom_mutex); 289 return ret; 290 } 291 292 int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set) 293 { 294 struct sk_buff *skb; 295 struct p54_tim *tim; 296 297 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*tim), 298 P54_CONTROL_TYPE_TIM, GFP_ATOMIC); 299 if (unlikely(!skb)) 300 return -ENOMEM; 301 302 tim = skb_put(skb, sizeof(*tim)); 303 tim->count = 1; 304 tim->entry[0] = cpu_to_le16(set ? (aid | 0x8000) : aid); 305 p54_tx(priv, skb); 306 return 0; 307 } 308 309 int p54_sta_unlock(struct p54_common *priv, u8 *addr) 310 { 311 struct sk_buff *skb; 312 struct p54_sta_unlock *sta; 313 314 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*sta), 315 P54_CONTROL_TYPE_PSM_STA_UNLOCK, GFP_ATOMIC); 316 if (unlikely(!skb)) 317 return -ENOMEM; 318 319 sta = skb_put(skb, sizeof(*sta)); 320 memcpy(sta->addr, addr, ETH_ALEN); 321 p54_tx(priv, skb); 322 return 0; 323 } 324 325 int p54_tx_cancel(struct p54_common *priv, __le32 req_id) 326 { 327 struct sk_buff *skb; 328 struct p54_txcancel *cancel; 329 u32 _req_id = le32_to_cpu(req_id); 330 331 if (unlikely(_req_id < priv->rx_start || _req_id > priv->rx_end)) 332 return -EINVAL; 333 334 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*cancel), 335 P54_CONTROL_TYPE_TXCANCEL, GFP_ATOMIC); 336 if (unlikely(!skb)) 337 return -ENOMEM; 338 339 cancel = skb_put(skb, sizeof(*cancel)); 340 cancel->req_id = req_id; 341 p54_tx(priv, skb); 342 return 0; 343 } 344 345 int p54_setup_mac(struct p54_common *priv) 346 { 347 struct sk_buff *skb; 348 struct p54_setup_mac *setup; 349 u16 mode; 350 351 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*setup), 352 P54_CONTROL_TYPE_SETUP, GFP_ATOMIC); 353 if (!skb) 354 return -ENOMEM; 355 356 setup = skb_put(skb, sizeof(*setup)); 357 if (!(priv->hw->conf.flags & IEEE80211_CONF_IDLE)) { 358 switch (priv->mode) { 359 case NL80211_IFTYPE_STATION: 360 mode = P54_FILTER_TYPE_STATION; 361 break; 362 case NL80211_IFTYPE_AP: 363 mode = P54_FILTER_TYPE_AP; 364 break; 365 case NL80211_IFTYPE_ADHOC: 366 case NL80211_IFTYPE_MESH_POINT: 367 mode = P54_FILTER_TYPE_IBSS; 368 break; 369 case NL80211_IFTYPE_MONITOR: 370 mode = P54_FILTER_TYPE_PROMISCUOUS; 371 break; 372 default: 373 mode = P54_FILTER_TYPE_HIBERNATE; 374 break; 375 } 376 377 /* 378 * "TRANSPARENT and PROMISCUOUS are mutually exclusive" 379 * STSW45X0C LMAC API - page 12 380 */ 381 if (priv->filter_flags & FIF_OTHER_BSS && 382 (mode != P54_FILTER_TYPE_PROMISCUOUS)) 383 mode |= P54_FILTER_TYPE_TRANSPARENT; 384 } else { 385 mode = P54_FILTER_TYPE_HIBERNATE; 386 } 387 388 setup->mac_mode = cpu_to_le16(mode); 389 memcpy(setup->mac_addr, priv->mac_addr, ETH_ALEN); 390 memcpy(setup->bssid, priv->bssid, ETH_ALEN); 391 setup->rx_antenna = 2 & priv->rx_diversity_mask; /* automatic */ 392 setup->rx_align = 0; 393 if (priv->fw_var < 0x500) { 394 setup->v1.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); 395 memset(setup->v1.rts_rates, 0, 8); 396 setup->v1.rx_addr = cpu_to_le32(priv->rx_end); 397 setup->v1.max_rx = cpu_to_le16(priv->rx_mtu); 398 setup->v1.rxhw = cpu_to_le16(priv->rxhw); 399 setup->v1.wakeup_timer = cpu_to_le16(priv->wakeup_timer); 400 setup->v1.unalloc0 = cpu_to_le16(0); 401 } else { 402 setup->v2.rx_addr = cpu_to_le32(priv->rx_end); 403 setup->v2.max_rx = cpu_to_le16(priv->rx_mtu); 404 setup->v2.rxhw = cpu_to_le16(priv->rxhw); 405 setup->v2.timer = cpu_to_le16(priv->wakeup_timer); 406 setup->v2.truncate = cpu_to_le16(48896); 407 setup->v2.basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); 408 setup->v2.sbss_offset = 0; 409 setup->v2.mcast_window = 0; 410 setup->v2.rx_rssi_threshold = 0; 411 setup->v2.rx_ed_threshold = 0; 412 setup->v2.ref_clock = cpu_to_le32(644245094); 413 setup->v2.lpf_bandwidth = cpu_to_le16(65535); 414 setup->v2.osc_start_delay = cpu_to_le16(65535); 415 } 416 p54_tx(priv, skb); 417 priv->phy_idle = mode == P54_FILTER_TYPE_HIBERNATE; 418 return 0; 419 } 420 421 int p54_scan(struct p54_common *priv, u16 mode, u16 dwell) 422 { 423 struct sk_buff *skb; 424 struct p54_hdr *hdr; 425 struct p54_scan_head *head; 426 struct p54_iq_autocal_entry *iq_autocal; 427 union p54_scan_body_union *body; 428 struct p54_scan_tail_rate *rate; 429 struct pda_rssi_cal_entry *rssi; 430 struct p54_rssi_db_entry *rssi_data; 431 unsigned int i; 432 void *entry; 433 __le16 freq = cpu_to_le16(priv->hw->conf.chandef.chan->center_freq); 434 435 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + 436 2 + sizeof(*iq_autocal) + sizeof(*body) + 437 sizeof(*rate) + 2 * sizeof(*rssi), 438 P54_CONTROL_TYPE_SCAN, GFP_ATOMIC); 439 if (!skb) 440 return -ENOMEM; 441 442 head = skb_put(skb, sizeof(*head)); 443 memset(head->scan_params, 0, sizeof(head->scan_params)); 444 head->mode = cpu_to_le16(mode); 445 head->dwell = cpu_to_le16(dwell); 446 head->freq = freq; 447 448 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { 449 __le16 *pa_power_points = skb_put(skb, 2); 450 *pa_power_points = cpu_to_le16(0x0c); 451 } 452 453 iq_autocal = skb_put(skb, sizeof(*iq_autocal)); 454 for (i = 0; i < priv->iq_autocal_len; i++) { 455 if (priv->iq_autocal[i].freq != freq) 456 continue; 457 458 memcpy(iq_autocal, &priv->iq_autocal[i].params, 459 sizeof(struct p54_iq_autocal_entry)); 460 break; 461 } 462 if (i == priv->iq_autocal_len) 463 goto err; 464 465 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) 466 body = skb_put(skb, sizeof(body->longbow)); 467 else 468 body = skb_put(skb, sizeof(body->normal)); 469 470 for (i = 0; i < priv->output_limit->entries; i++) { 471 __le16 *entry_freq = (void *) (priv->output_limit->data + 472 priv->output_limit->entry_size * i); 473 474 if (*entry_freq != freq) 475 continue; 476 477 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { 478 memcpy(&body->longbow.power_limits, 479 (void *) entry_freq + sizeof(__le16), 480 priv->output_limit->entry_size); 481 } else { 482 struct pda_channel_output_limit *limits = 483 (void *) entry_freq; 484 485 body->normal.val_barker = 0x38; 486 body->normal.val_bpsk = body->normal.dup_bpsk = 487 limits->val_bpsk; 488 body->normal.val_qpsk = body->normal.dup_qpsk = 489 limits->val_qpsk; 490 body->normal.val_16qam = body->normal.dup_16qam = 491 limits->val_16qam; 492 body->normal.val_64qam = body->normal.dup_64qam = 493 limits->val_64qam; 494 } 495 break; 496 } 497 if (i == priv->output_limit->entries) 498 goto err; 499 500 entry = (void *)(priv->curve_data->data + priv->curve_data->offset); 501 for (i = 0; i < priv->curve_data->entries; i++) { 502 if (*((__le16 *)entry) != freq) { 503 entry += priv->curve_data->entry_size; 504 continue; 505 } 506 507 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { 508 memcpy(&body->longbow.curve_data, 509 entry + sizeof(__le16), 510 priv->curve_data->entry_size); 511 } else { 512 struct p54_scan_body *chan = &body->normal; 513 struct pda_pa_curve_data *curve_data = 514 (void *) priv->curve_data->data; 515 516 entry += sizeof(__le16); 517 chan->pa_points_per_curve = 8; 518 memset(chan->curve_data, 0, sizeof(chan->curve_data)); 519 memcpy(chan->curve_data, entry, 520 sizeof(struct p54_pa_curve_data_sample) * 521 min((u8)8, curve_data->points_per_channel)); 522 } 523 break; 524 } 525 if (i == priv->curve_data->entries) 526 goto err; 527 528 if ((priv->fw_var >= 0x500) && (priv->fw_var < 0x509)) { 529 rate = skb_put(skb, sizeof(*rate)); 530 rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); 531 for (i = 0; i < sizeof(rate->rts_rates); i++) 532 rate->rts_rates[i] = i; 533 } 534 535 rssi = skb_put(skb, sizeof(*rssi)); 536 rssi_data = p54_rssi_find(priv, le16_to_cpu(freq)); 537 rssi->mul = cpu_to_le16(rssi_data->mul); 538 rssi->add = cpu_to_le16(rssi_data->add); 539 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { 540 /* Longbow frontend needs ever more */ 541 rssi = skb_put(skb, sizeof(*rssi)); 542 rssi->mul = cpu_to_le16(rssi_data->longbow_unkn); 543 rssi->add = cpu_to_le16(rssi_data->longbow_unk2); 544 } 545 546 if (priv->fw_var >= 0x509) { 547 rate = skb_put(skb, sizeof(*rate)); 548 rate->basic_rate_mask = cpu_to_le32(priv->basic_rate_mask); 549 for (i = 0; i < sizeof(rate->rts_rates); i++) 550 rate->rts_rates[i] = i; 551 } 552 553 hdr = (struct p54_hdr *) skb->data; 554 hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); 555 556 p54_tx(priv, skb); 557 priv->cur_rssi = rssi_data; 558 return 0; 559 560 err: 561 wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n", 562 ieee80211_frequency_to_channel( 563 priv->hw->conf.chandef.chan->center_freq)); 564 565 dev_kfree_skb_any(skb); 566 return -EINVAL; 567 } 568 569 int p54_set_leds(struct p54_common *priv) 570 { 571 struct sk_buff *skb; 572 struct p54_led *led; 573 574 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*led), 575 P54_CONTROL_TYPE_LED, GFP_ATOMIC); 576 if (unlikely(!skb)) 577 return -ENOMEM; 578 579 led = skb_put(skb, sizeof(*led)); 580 led->flags = cpu_to_le16(0x0003); 581 led->mask[0] = led->mask[1] = cpu_to_le16(priv->softled_state); 582 led->delay[0] = cpu_to_le16(1); 583 led->delay[1] = cpu_to_le16(0); 584 p54_tx(priv, skb); 585 return 0; 586 } 587 588 int p54_set_edcf(struct p54_common *priv) 589 { 590 struct sk_buff *skb; 591 struct p54_edcf *edcf; 592 u8 rtd; 593 594 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf), 595 P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC); 596 if (unlikely(!skb)) 597 return -ENOMEM; 598 599 edcf = skb_put(skb, sizeof(*edcf)); 600 if (priv->use_short_slot) { 601 edcf->slottime = 9; 602 edcf->sifs = 0x10; 603 edcf->eofpad = 0x00; 604 } else { 605 edcf->slottime = 20; 606 edcf->sifs = 0x0a; 607 edcf->eofpad = 0x06; 608 } 609 /* 610 * calculate the extra round trip delay according to the 611 * formula from 802.11-2007 17.3.8.6. 612 */ 613 rtd = 3 * priv->coverage_class; 614 edcf->slottime += rtd; 615 edcf->round_trip_delay = cpu_to_le16(rtd); 616 /* (see prism54/isl_oid.h for further details) */ 617 edcf->frameburst = cpu_to_le16(0); 618 edcf->flags = 0; 619 memset(edcf->mapping, 0, sizeof(edcf->mapping)); 620 memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue)); 621 p54_tx(priv, skb); 622 return 0; 623 } 624 625 int p54_set_ps(struct p54_common *priv) 626 { 627 struct sk_buff *skb; 628 struct p54_psm *psm; 629 unsigned int i; 630 u16 mode; 631 632 if (priv->hw->conf.flags & IEEE80211_CONF_PS && 633 !priv->powersave_override) 634 mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM | 635 P54_PSM_CHECKSUM | P54_PSM_MCBC; 636 else 637 mode = P54_PSM_CAM; 638 639 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*psm), 640 P54_CONTROL_TYPE_PSM, GFP_ATOMIC); 641 if (!skb) 642 return -ENOMEM; 643 644 psm = skb_put(skb, sizeof(*psm)); 645 psm->mode = cpu_to_le16(mode); 646 psm->aid = cpu_to_le16(priv->aid); 647 for (i = 0; i < ARRAY_SIZE(psm->intervals); i++) { 648 psm->intervals[i].interval = 649 cpu_to_le16(priv->hw->conf.listen_interval); 650 psm->intervals[i].periods = cpu_to_le16(1); 651 } 652 653 psm->beacon_rssi_skip_max = 200; 654 psm->rssi_delta_threshold = 0; 655 psm->nr = 1; 656 psm->exclude[0] = WLAN_EID_TIM; 657 658 p54_tx(priv, skb); 659 priv->phy_ps = mode != P54_PSM_CAM; 660 return 0; 661 } 662 663 int p54_init_xbow_synth(struct p54_common *priv) 664 { 665 struct sk_buff *skb; 666 struct p54_xbow_synth *xbow; 667 668 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*xbow), 669 P54_CONTROL_TYPE_XBOW_SYNTH_CFG, GFP_KERNEL); 670 if (unlikely(!skb)) 671 return -ENOMEM; 672 673 xbow = skb_put(skb, sizeof(*xbow)); 674 xbow->magic1 = cpu_to_le16(0x1); 675 xbow->magic2 = cpu_to_le16(0x2); 676 xbow->freq = cpu_to_le16(5390); 677 memset(xbow->padding, 0, sizeof(xbow->padding)); 678 p54_tx(priv, skb); 679 return 0; 680 } 681 682 int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len, 683 u8 *addr, u8* key) 684 { 685 struct sk_buff *skb; 686 struct p54_keycache *rxkey; 687 688 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*rxkey), 689 P54_CONTROL_TYPE_RX_KEYCACHE, GFP_KERNEL); 690 if (unlikely(!skb)) 691 return -ENOMEM; 692 693 rxkey = skb_put(skb, sizeof(*rxkey)); 694 rxkey->entry = slot; 695 rxkey->key_id = idx; 696 rxkey->key_type = algo; 697 if (addr) 698 memcpy(rxkey->mac, addr, ETH_ALEN); 699 else 700 eth_broadcast_addr(rxkey->mac); 701 702 switch (algo) { 703 case P54_CRYPTO_WEP: 704 case P54_CRYPTO_AESCCMP: 705 rxkey->key_len = min_t(u8, 16, len); 706 memcpy(rxkey->key, key, rxkey->key_len); 707 break; 708 709 case P54_CRYPTO_TKIPMICHAEL: 710 rxkey->key_len = 24; 711 memcpy(rxkey->key, key, 16); 712 memcpy(&(rxkey->key[16]), &(key 713 [NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY]), 8); 714 break; 715 716 case P54_CRYPTO_NONE: 717 rxkey->key_len = 0; 718 memset(rxkey->key, 0, sizeof(rxkey->key)); 719 break; 720 721 default: 722 wiphy_err(priv->hw->wiphy, 723 "invalid cryptographic algorithm: %d\n", algo); 724 dev_kfree_skb(skb); 725 return -EINVAL; 726 } 727 728 p54_tx(priv, skb); 729 return 0; 730 } 731 732 int p54_fetch_statistics(struct p54_common *priv) 733 { 734 struct ieee80211_tx_info *txinfo; 735 struct p54_tx_info *p54info; 736 struct sk_buff *skb; 737 738 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, 739 sizeof(struct p54_statistics), 740 P54_CONTROL_TYPE_STAT_READBACK, GFP_KERNEL); 741 if (!skb) 742 return -ENOMEM; 743 744 /* 745 * The statistic feedback causes some extra headaches here, if it 746 * is not to crash/corrupt the firmware data structures. 747 * 748 * Unlike all other Control Get OIDs we can not use helpers like 749 * skb_put to reserve the space for the data we're requesting. 750 * Instead the extra frame length -which will hold the results later- 751 * will only be told to the p54_assign_address, so that following 752 * frames won't be placed into the allegedly empty area. 753 */ 754 txinfo = IEEE80211_SKB_CB(skb); 755 p54info = (void *) txinfo->rate_driver_data; 756 p54info->extra_len = sizeof(struct p54_statistics); 757 758 p54_tx(priv, skb); 759 return 0; 760 } 761 762 int p54_set_groupfilter(struct p54_common *priv) 763 { 764 struct p54_group_address_table *grp; 765 struct sk_buff *skb; 766 bool on = false; 767 768 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp), 769 P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL); 770 if (!skb) 771 return -ENOMEM; 772 773 grp = skb_put(skb, sizeof(*grp)); 774 775 on = !(priv->filter_flags & FIF_ALLMULTI) && 776 (priv->mc_maclist_num > 0 && 777 priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM); 778 779 if (on) { 780 grp->filter_enable = cpu_to_le16(1); 781 grp->num_address = cpu_to_le16(priv->mc_maclist_num); 782 memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list)); 783 } else { 784 grp->filter_enable = cpu_to_le16(0); 785 grp->num_address = cpu_to_le16(0); 786 memset(grp->mac_list, 0, sizeof(grp->mac_list)); 787 } 788 789 p54_tx(priv, skb); 790 return 0; 791 } 792