diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-12-09 15:30:27 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-12-09 15:30:27 -0500 |
commit | 145babc68eebc4d72cd1a92d92e91739b905b7df (patch) | |
tree | 192088d4211b3f60c1aaa231029b519bf2fbc591 /drivers/net/wireless/ath/ath10k/wmi.c | |
parent | e08fd975bf26aa8063cadd245817e042f570472d (diff) | |
parent | cfb27d29b61cc32c0bb75f741aeabb9c6e6af742 (diff) |
Merge tag 'for-linville-20131203' of git://github.com/kvalo/ath
Conflicts:
drivers/net/wireless/ath/ath10k/htc.c
drivers/net/wireless/ath/ath10k/mac.c
Diffstat (limited to 'drivers/net/wireless/ath/ath10k/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath10k/wmi.c | 302 |
1 files changed, 286 insertions, 16 deletions
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c index ccf3597fd9e2..1260a8d15dc3 100644 --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c | |||
@@ -674,10 +674,8 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) | |||
674 | 674 | ||
675 | /* Send the management frame buffer to the target */ | 675 | /* Send the management frame buffer to the target */ |
676 | ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); | 676 | ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); |
677 | if (ret) { | 677 | if (ret) |
678 | dev_kfree_skb_any(skb); | ||
679 | return ret; | 678 | return ret; |
680 | } | ||
681 | 679 | ||
682 | /* TODO: report tx status to mac80211 - temporary just ACK */ | 680 | /* TODO: report tx status to mac80211 - temporary just ACK */ |
683 | info->flags |= IEEE80211_TX_STAT_ACK; | 681 | info->flags |= IEEE80211_TX_STAT_ACK; |
@@ -909,6 +907,11 @@ static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) | |||
909 | ath10k_dbg(ATH10K_DBG_MGMT, | 907 | ath10k_dbg(ATH10K_DBG_MGMT, |
910 | "event mgmt rx status %08x\n", rx_status); | 908 | "event mgmt rx status %08x\n", rx_status); |
911 | 909 | ||
910 | if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { | ||
911 | dev_kfree_skb(skb); | ||
912 | return 0; | ||
913 | } | ||
914 | |||
912 | if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) { | 915 | if (rx_status & WMI_RX_STATUS_ERR_DECRYPT) { |
913 | dev_kfree_skb(skb); | 916 | dev_kfree_skb(skb); |
914 | return 0; | 917 | return 0; |
@@ -1383,9 +1386,259 @@ static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, | |||
1383 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); | 1386 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); |
1384 | } | 1387 | } |
1385 | 1388 | ||
1389 | static void ath10k_dfs_radar_report(struct ath10k *ar, | ||
1390 | struct wmi_single_phyerr_rx_event *event, | ||
1391 | struct phyerr_radar_report *rr, | ||
1392 | u64 tsf) | ||
1393 | { | ||
1394 | u32 reg0, reg1, tsf32l; | ||
1395 | struct pulse_event pe; | ||
1396 | u64 tsf64; | ||
1397 | u8 rssi, width; | ||
1398 | |||
1399 | reg0 = __le32_to_cpu(rr->reg0); | ||
1400 | reg1 = __le32_to_cpu(rr->reg1); | ||
1401 | |||
1402 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1403 | "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n", | ||
1404 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP), | ||
1405 | MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH), | ||
1406 | MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN), | ||
1407 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF)); | ||
1408 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1409 | "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n", | ||
1410 | MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK), | ||
1411 | MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX), | ||
1412 | MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID), | ||
1413 | MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN), | ||
1414 | MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK)); | ||
1415 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1416 | "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n", | ||
1417 | MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET), | ||
1418 | MS(reg1, RADAR_REPORT_REG1_PULSE_DUR)); | ||
1419 | |||
1420 | if (!ar->dfs_detector) | ||
1421 | return; | ||
1422 | |||
1423 | /* report event to DFS pattern detector */ | ||
1424 | tsf32l = __le32_to_cpu(event->hdr.tsf_timestamp); | ||
1425 | tsf64 = tsf & (~0xFFFFFFFFULL); | ||
1426 | tsf64 |= tsf32l; | ||
1427 | |||
1428 | width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR); | ||
1429 | rssi = event->hdr.rssi_combined; | ||
1430 | |||
1431 | /* hardware store this as 8 bit signed value, | ||
1432 | * set to zero if negative number | ||
1433 | */ | ||
1434 | if (rssi & 0x80) | ||
1435 | rssi = 0; | ||
1436 | |||
1437 | pe.ts = tsf64; | ||
1438 | pe.freq = ar->hw->conf.chandef.chan->center_freq; | ||
1439 | pe.width = width; | ||
1440 | pe.rssi = rssi; | ||
1441 | |||
1442 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1443 | "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", | ||
1444 | pe.freq, pe.width, pe.rssi, pe.ts); | ||
1445 | |||
1446 | ATH10K_DFS_STAT_INC(ar, pulses_detected); | ||
1447 | |||
1448 | if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) { | ||
1449 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1450 | "dfs no pulse pattern detected, yet\n"); | ||
1451 | return; | ||
1452 | } | ||
1453 | |||
1454 | ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs radar detected\n"); | ||
1455 | ATH10K_DFS_STAT_INC(ar, radar_detected); | ||
1456 | |||
1457 | /* Control radar events reporting in debugfs file | ||
1458 | dfs_block_radar_events */ | ||
1459 | if (ar->dfs_block_radar_events) { | ||
1460 | ath10k_info("DFS Radar detected, but ignored as requested\n"); | ||
1461 | return; | ||
1462 | } | ||
1463 | |||
1464 | ieee80211_radar_detected(ar->hw); | ||
1465 | } | ||
1466 | |||
1467 | static int ath10k_dfs_fft_report(struct ath10k *ar, | ||
1468 | struct wmi_single_phyerr_rx_event *event, | ||
1469 | struct phyerr_fft_report *fftr, | ||
1470 | u64 tsf) | ||
1471 | { | ||
1472 | u32 reg0, reg1; | ||
1473 | u8 rssi, peak_mag; | ||
1474 | |||
1475 | reg0 = __le32_to_cpu(fftr->reg0); | ||
1476 | reg1 = __le32_to_cpu(fftr->reg1); | ||
1477 | rssi = event->hdr.rssi_combined; | ||
1478 | |||
1479 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1480 | "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", | ||
1481 | MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB), | ||
1482 | MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB), | ||
1483 | MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX), | ||
1484 | MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX)); | ||
1485 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1486 | "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n", | ||
1487 | MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB), | ||
1488 | MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB), | ||
1489 | MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG), | ||
1490 | MS(reg1, SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB)); | ||
1491 | |||
1492 | peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); | ||
1493 | |||
1494 | /* false event detection */ | ||
1495 | if (rssi == DFS_RSSI_POSSIBLY_FALSE && | ||
1496 | peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) { | ||
1497 | ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); | ||
1498 | ATH10K_DFS_STAT_INC(ar, pulses_discarded); | ||
1499 | return -EINVAL; | ||
1500 | } | ||
1501 | |||
1502 | return 0; | ||
1503 | } | ||
1504 | |||
1505 | static void ath10k_wmi_event_dfs(struct ath10k *ar, | ||
1506 | struct wmi_single_phyerr_rx_event *event, | ||
1507 | u64 tsf) | ||
1508 | { | ||
1509 | int buf_len, tlv_len, res, i = 0; | ||
1510 | struct phyerr_tlv *tlv; | ||
1511 | struct phyerr_radar_report *rr; | ||
1512 | struct phyerr_fft_report *fftr; | ||
1513 | u8 *tlv_buf; | ||
1514 | |||
1515 | buf_len = __le32_to_cpu(event->hdr.buf_len); | ||
1516 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1517 | "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", | ||
1518 | event->hdr.phy_err_code, event->hdr.rssi_combined, | ||
1519 | __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len); | ||
1520 | |||
1521 | /* Skip event if DFS disabled */ | ||
1522 | if (!config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) | ||
1523 | return; | ||
1524 | |||
1525 | ATH10K_DFS_STAT_INC(ar, pulses_total); | ||
1526 | |||
1527 | while (i < buf_len) { | ||
1528 | if (i + sizeof(*tlv) > buf_len) { | ||
1529 | ath10k_warn("too short buf for tlv header (%d)\n", i); | ||
1530 | return; | ||
1531 | } | ||
1532 | |||
1533 | tlv = (struct phyerr_tlv *)&event->bufp[i]; | ||
1534 | tlv_len = __le16_to_cpu(tlv->len); | ||
1535 | tlv_buf = &event->bufp[i + sizeof(*tlv)]; | ||
1536 | ath10k_dbg(ATH10K_DBG_REGULATORY, | ||
1537 | "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", | ||
1538 | tlv_len, tlv->tag, tlv->sig); | ||
1539 | |||
1540 | switch (tlv->tag) { | ||
1541 | case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY: | ||
1542 | if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) { | ||
1543 | ath10k_warn("too short radar pulse summary (%d)\n", | ||
1544 | i); | ||
1545 | return; | ||
1546 | } | ||
1547 | |||
1548 | rr = (struct phyerr_radar_report *)tlv_buf; | ||
1549 | ath10k_dfs_radar_report(ar, event, rr, tsf); | ||
1550 | break; | ||
1551 | case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: | ||
1552 | if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { | ||
1553 | ath10k_warn("too short fft report (%d)\n", i); | ||
1554 | return; | ||
1555 | } | ||
1556 | |||
1557 | fftr = (struct phyerr_fft_report *)tlv_buf; | ||
1558 | res = ath10k_dfs_fft_report(ar, event, fftr, tsf); | ||
1559 | if (res) | ||
1560 | return; | ||
1561 | break; | ||
1562 | } | ||
1563 | |||
1564 | i += sizeof(*tlv) + tlv_len; | ||
1565 | } | ||
1566 | } | ||
1567 | |||
1568 | static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, | ||
1569 | struct wmi_single_phyerr_rx_event *event, | ||
1570 | u64 tsf) | ||
1571 | { | ||
1572 | ath10k_dbg(ATH10K_DBG_WMI, "wmi event spectral scan\n"); | ||
1573 | } | ||
1574 | |||
1386 | static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) | 1575 | static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) |
1387 | { | 1576 | { |
1388 | ath10k_dbg(ATH10K_DBG_WMI, "WMI_PHYERR_EVENTID\n"); | 1577 | struct wmi_comb_phyerr_rx_event *comb_event; |
1578 | struct wmi_single_phyerr_rx_event *event; | ||
1579 | u32 count, i, buf_len, phy_err_code; | ||
1580 | u64 tsf; | ||
1581 | int left_len = skb->len; | ||
1582 | |||
1583 | ATH10K_DFS_STAT_INC(ar, phy_errors); | ||
1584 | |||
1585 | /* Check if combined event available */ | ||
1586 | if (left_len < sizeof(*comb_event)) { | ||
1587 | ath10k_warn("wmi phyerr combined event wrong len\n"); | ||
1588 | return; | ||
1589 | } | ||
1590 | |||
1591 | left_len -= sizeof(*comb_event); | ||
1592 | |||
1593 | /* Check number of included events */ | ||
1594 | comb_event = (struct wmi_comb_phyerr_rx_event *)skb->data; | ||
1595 | count = __le32_to_cpu(comb_event->hdr.num_phyerr_events); | ||
1596 | |||
1597 | tsf = __le32_to_cpu(comb_event->hdr.tsf_u32); | ||
1598 | tsf <<= 32; | ||
1599 | tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32); | ||
1600 | |||
1601 | ath10k_dbg(ATH10K_DBG_WMI, | ||
1602 | "wmi event phyerr count %d tsf64 0x%llX\n", | ||
1603 | count, tsf); | ||
1604 | |||
1605 | event = (struct wmi_single_phyerr_rx_event *)comb_event->bufp; | ||
1606 | for (i = 0; i < count; i++) { | ||
1607 | /* Check if we can read event header */ | ||
1608 | if (left_len < sizeof(*event)) { | ||
1609 | ath10k_warn("single event (%d) wrong head len\n", i); | ||
1610 | return; | ||
1611 | } | ||
1612 | |||
1613 | left_len -= sizeof(*event); | ||
1614 | |||
1615 | buf_len = __le32_to_cpu(event->hdr.buf_len); | ||
1616 | phy_err_code = event->hdr.phy_err_code; | ||
1617 | |||
1618 | if (left_len < buf_len) { | ||
1619 | ath10k_warn("single event (%d) wrong buf len\n", i); | ||
1620 | return; | ||
1621 | } | ||
1622 | |||
1623 | left_len -= buf_len; | ||
1624 | |||
1625 | switch (phy_err_code) { | ||
1626 | case PHY_ERROR_RADAR: | ||
1627 | ath10k_wmi_event_dfs(ar, event, tsf); | ||
1628 | break; | ||
1629 | case PHY_ERROR_SPECTRAL_SCAN: | ||
1630 | ath10k_wmi_event_spectral_scan(ar, event, tsf); | ||
1631 | break; | ||
1632 | case PHY_ERROR_FALSE_RADAR_EXT: | ||
1633 | ath10k_wmi_event_dfs(ar, event, tsf); | ||
1634 | ath10k_wmi_event_spectral_scan(ar, event, tsf); | ||
1635 | break; | ||
1636 | default: | ||
1637 | break; | ||
1638 | } | ||
1639 | |||
1640 | event += sizeof(*event) + buf_len; | ||
1641 | } | ||
1389 | } | 1642 | } |
1390 | 1643 | ||
1391 | static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) | 1644 | static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) |
@@ -2062,6 +2315,7 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | |||
2062 | { | 2315 | { |
2063 | struct wmi_set_channel_cmd *cmd; | 2316 | struct wmi_set_channel_cmd *cmd; |
2064 | struct sk_buff *skb; | 2317 | struct sk_buff *skb; |
2318 | u32 ch_flags = 0; | ||
2065 | 2319 | ||
2066 | if (arg->passive) | 2320 | if (arg->passive) |
2067 | return -EINVAL; | 2321 | return -EINVAL; |
@@ -2070,10 +2324,14 @@ int ath10k_wmi_pdev_set_channel(struct ath10k *ar, | |||
2070 | if (!skb) | 2324 | if (!skb) |
2071 | return -ENOMEM; | 2325 | return -ENOMEM; |
2072 | 2326 | ||
2327 | if (arg->chan_radar) | ||
2328 | ch_flags |= WMI_CHAN_FLAG_DFS; | ||
2329 | |||
2073 | cmd = (struct wmi_set_channel_cmd *)skb->data; | 2330 | cmd = (struct wmi_set_channel_cmd *)skb->data; |
2074 | cmd->chan.mhz = __cpu_to_le32(arg->freq); | 2331 | cmd->chan.mhz = __cpu_to_le32(arg->freq); |
2075 | cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq); | 2332 | cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq); |
2076 | cmd->chan.mode = arg->mode; | 2333 | cmd->chan.mode = arg->mode; |
2334 | cmd->chan.flags |= __cpu_to_le32(ch_flags); | ||
2077 | cmd->chan.min_power = arg->min_power; | 2335 | cmd->chan.min_power = arg->min_power; |
2078 | cmd->chan.max_power = arg->max_power; | 2336 | cmd->chan.max_power = arg->max_power; |
2079 | cmd->chan.reg_power = arg->max_reg_power; | 2337 | cmd->chan.reg_power = arg->max_reg_power; |
@@ -2211,7 +2469,7 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2211 | } | 2469 | } |
2212 | 2470 | ||
2213 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", | 2471 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", |
2214 | __cpu_to_le32(ar->wmi.num_mem_chunks)); | 2472 | ar->wmi.num_mem_chunks); |
2215 | 2473 | ||
2216 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); | 2474 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); |
2217 | 2475 | ||
@@ -2224,10 +2482,10 @@ static int ath10k_wmi_main_cmd_init(struct ath10k *ar) | |||
2224 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); | 2482 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); |
2225 | 2483 | ||
2226 | ath10k_dbg(ATH10K_DBG_WMI, | 2484 | ath10k_dbg(ATH10K_DBG_WMI, |
2227 | "wmi chunk %d len %d requested, addr 0x%x\n", | 2485 | "wmi chunk %d len %d requested, addr 0x%llx\n", |
2228 | i, | 2486 | i, |
2229 | cmd->host_mem_chunks[i].size, | 2487 | ar->wmi.mem_chunks[i].len, |
2230 | cmd->host_mem_chunks[i].ptr); | 2488 | (unsigned long long)ar->wmi.mem_chunks[i].paddr); |
2231 | } | 2489 | } |
2232 | out: | 2490 | out: |
2233 | memcpy(&cmd->resource_config, &config, sizeof(config)); | 2491 | memcpy(&cmd->resource_config, &config, sizeof(config)); |
@@ -2302,7 +2560,7 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2302 | } | 2560 | } |
2303 | 2561 | ||
2304 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", | 2562 | ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", |
2305 | __cpu_to_le32(ar->wmi.num_mem_chunks)); | 2563 | ar->wmi.num_mem_chunks); |
2306 | 2564 | ||
2307 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); | 2565 | cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); |
2308 | 2566 | ||
@@ -2315,10 +2573,10 @@ static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) | |||
2315 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); | 2573 | __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); |
2316 | 2574 | ||
2317 | ath10k_dbg(ATH10K_DBG_WMI, | 2575 | ath10k_dbg(ATH10K_DBG_WMI, |
2318 | "wmi chunk %d len %d requested, addr 0x%x\n", | 2576 | "wmi chunk %d len %d requested, addr 0x%llx\n", |
2319 | i, | 2577 | i, |
2320 | cmd->host_mem_chunks[i].size, | 2578 | ar->wmi.mem_chunks[i].len, |
2321 | cmd->host_mem_chunks[i].ptr); | 2579 | (unsigned long long)ar->wmi.mem_chunks[i].paddr); |
2322 | } | 2580 | } |
2323 | out: | 2581 | out: |
2324 | memcpy(&cmd->resource_config, &config, sizeof(config)); | 2582 | memcpy(&cmd->resource_config, &config, sizeof(config)); |
@@ -2622,6 +2880,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
2622 | struct sk_buff *skb; | 2880 | struct sk_buff *skb; |
2623 | const char *cmdname; | 2881 | const char *cmdname; |
2624 | u32 flags = 0; | 2882 | u32 flags = 0; |
2883 | u32 ch_flags = 0; | ||
2625 | 2884 | ||
2626 | if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && | 2885 | if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && |
2627 | cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) | 2886 | cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) |
@@ -2648,6 +2907,8 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
2648 | flags |= WMI_VDEV_START_HIDDEN_SSID; | 2907 | flags |= WMI_VDEV_START_HIDDEN_SSID; |
2649 | if (arg->pmf_enabled) | 2908 | if (arg->pmf_enabled) |
2650 | flags |= WMI_VDEV_START_PMF_ENABLED; | 2909 | flags |= WMI_VDEV_START_PMF_ENABLED; |
2910 | if (arg->channel.chan_radar) | ||
2911 | ch_flags |= WMI_CHAN_FLAG_DFS; | ||
2651 | 2912 | ||
2652 | cmd = (struct wmi_vdev_start_request_cmd *)skb->data; | 2913 | cmd = (struct wmi_vdev_start_request_cmd *)skb->data; |
2653 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); | 2914 | cmd->vdev_id = __cpu_to_le32(arg->vdev_id); |
@@ -2669,6 +2930,7 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
2669 | __cpu_to_le32(arg->channel.band_center_freq1); | 2930 | __cpu_to_le32(arg->channel.band_center_freq1); |
2670 | 2931 | ||
2671 | cmd->chan.mode = arg->channel.mode; | 2932 | cmd->chan.mode = arg->channel.mode; |
2933 | cmd->chan.flags |= __cpu_to_le32(ch_flags); | ||
2672 | cmd->chan.min_power = arg->channel.min_power; | 2934 | cmd->chan.min_power = arg->channel.min_power; |
2673 | cmd->chan.max_power = arg->channel.max_power; | 2935 | cmd->chan.max_power = arg->channel.max_power; |
2674 | cmd->chan.reg_power = arg->channel.max_reg_power; | 2936 | cmd->chan.reg_power = arg->channel.max_reg_power; |
@@ -2676,9 +2938,10 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, | |||
2676 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; | 2938 | cmd->chan.antenna_max = arg->channel.max_antenna_gain; |
2677 | 2939 | ||
2678 | ath10k_dbg(ATH10K_DBG_WMI, | 2940 | ath10k_dbg(ATH10K_DBG_WMI, |
2679 | "wmi vdev %s id 0x%x freq %d, mode %d, ch_flags: 0x%0X," | 2941 | "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, " |
2680 | "max_power: %d\n", cmdname, arg->vdev_id, arg->channel.freq, | 2942 | "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id, |
2681 | arg->channel.mode, flags, arg->channel.max_power); | 2943 | flags, arg->channel.freq, arg->channel.mode, |
2944 | cmd->chan.flags, arg->channel.max_power); | ||
2682 | 2945 | ||
2683 | return ath10k_wmi_cmd_send(ar, skb, cmd_id); | 2946 | return ath10k_wmi_cmd_send(ar, skb, cmd_id); |
2684 | } | 2947 | } |
@@ -3012,6 +3275,8 @@ int ath10k_wmi_scan_chan_list(struct ath10k *ar, | |||
3012 | flags |= WMI_CHAN_FLAG_ALLOW_VHT; | 3275 | flags |= WMI_CHAN_FLAG_ALLOW_VHT; |
3013 | if (ch->ht40plus) | 3276 | if (ch->ht40plus) |
3014 | flags |= WMI_CHAN_FLAG_HT40_PLUS; | 3277 | flags |= WMI_CHAN_FLAG_HT40_PLUS; |
3278 | if (ch->chan_radar) | ||
3279 | flags |= WMI_CHAN_FLAG_DFS; | ||
3015 | 3280 | ||
3016 | ci->mhz = __cpu_to_le32(ch->freq); | 3281 | ci->mhz = __cpu_to_le32(ch->freq); |
3017 | ci->band_center_freq1 = __cpu_to_le32(ch->freq); | 3282 | ci->band_center_freq1 = __cpu_to_le32(ch->freq); |
@@ -3094,6 +3359,7 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, | |||
3094 | { | 3359 | { |
3095 | struct wmi_bcn_tx_cmd *cmd; | 3360 | struct wmi_bcn_tx_cmd *cmd; |
3096 | struct sk_buff *skb; | 3361 | struct sk_buff *skb; |
3362 | int ret; | ||
3097 | 3363 | ||
3098 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len); | 3364 | skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->bcn_len); |
3099 | if (!skb) | 3365 | if (!skb) |
@@ -3106,7 +3372,11 @@ int ath10k_wmi_beacon_send_nowait(struct ath10k *ar, | |||
3106 | cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); | 3372 | cmd->hdr.bcn_len = __cpu_to_le32(arg->bcn_len); |
3107 | memcpy(cmd->bcn, arg->bcn, arg->bcn_len); | 3373 | memcpy(cmd->bcn, arg->bcn, arg->bcn_len); |
3108 | 3374 | ||
3109 | return ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid); | 3375 | ret = ath10k_wmi_cmd_send_nowait(ar, skb, ar->wmi.cmd->bcn_tx_cmdid); |
3376 | if (ret) | ||
3377 | dev_kfree_skb(skb); | ||
3378 | |||
3379 | return ret; | ||
3110 | } | 3380 | } |
3111 | 3381 | ||
3112 | static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, | 3382 | static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, |