--- zzzz-none-000/linux-3.10.107/drivers/net/wireless/ath/ath6kl/wmi.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/net/wireless/ath/ath6kl/wmi.c 2021-02-04 17:41:59.000000000 +0000 @@ -59,6 +59,55 @@ {0, 0} }; +static const s32 wmi_rate_tbl_mcs15[][2] = { + /* {W/O SGI, with SGI} */ + {1000, 1000}, + {2000, 2000}, + {5500, 5500}, + {11000, 11000}, + {6000, 6000}, + {9000, 9000}, + {12000, 12000}, + {18000, 18000}, + {24000, 24000}, + {36000, 36000}, + {48000, 48000}, + {54000, 54000}, + {6500, 7200}, /* HT 20, MCS 0 */ + {13000, 14400}, + {19500, 21700}, + {26000, 28900}, + {39000, 43300}, + {52000, 57800}, + {58500, 65000}, + {65000, 72200}, + {13000, 14400}, /* HT 20, MCS 8 */ + {26000, 28900}, + {39000, 43300}, + {52000, 57800}, + {78000, 86700}, + {104000, 115600}, + {117000, 130000}, + {130000, 144400}, /* HT 20, MCS 15 */ + {13500, 15000}, /*HT 40, MCS 0 */ + {27000, 30000}, + {40500, 45000}, + {54000, 60000}, + {81000, 90000}, + {108000, 120000}, + {121500, 135000}, + {135000, 150000}, + {27000, 30000}, /*HT 40, MCS 8 */ + {54000, 60000}, + {81000, 90000}, + {108000, 120000}, + {162000, 180000}, + {216000, 240000}, + {243000, 270000}, + {270000, 300000}, /*HT 40, MCS 15 */ + {0, 0} +}; + /* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ static const u8 up_to_ac[] = { WMM_AC_BE, @@ -105,7 +154,7 @@ } /* Performs DIX to 802.3 encapsulation for transmit packets. - * Assumes the entire DIX header is contigous and that there is + * Assumes the entire DIX header is contiguous and that there is * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. */ int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb) @@ -289,8 +338,9 @@ ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) + sizeof(struct ath6kl_llc_snap_hdr), layer2_priority); - } else + } else { usr_pri = layer2_priority & 0x7; + } /* * Queue the EAPOL frames in the same WMM_AC_VO queue @@ -359,8 +409,9 @@ hdr_size = roundup(sizeof(struct ieee80211_qos_hdr), sizeof(u32)); skb_pull(skb, hdr_size); - } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA)) + } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA)) { skb_pull(skb, sizeof(struct ieee80211_hdr_3addr)); + } datap = skb->data; llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap); @@ -398,7 +449,7 @@ /* * Performs 802.3 to DIX encapsulation for received packets. - * Assumes the entire 802.3 header is contigous. + * Assumes the entire 802.3 header is contiguous. */ int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb) { @@ -568,8 +619,7 @@ dlen, freq, vif->probe_req_report); if (vif->probe_req_report || vif->nw_type == AP_NETWORK) - cfg80211_rx_mgmt(&vif->wdev, freq, 0, - ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0); return 0; } @@ -608,8 +658,7 @@ return -EINVAL; } ath6kl_dbg(ATH6KL_DBG_WMI, "rx_action: len=%u freq=%u\n", dlen, freq); - cfg80211_rx_mgmt(&vif->wdev, freq, 0, - ev->data, dlen, GFP_ATOMIC); + cfg80211_rx_mgmt(&vif->wdev, freq, 0, ev->data, dlen, 0); return 0; } @@ -915,7 +964,7 @@ return NULL; for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { - if (regDomainPairs[i].regDmnEnum == regdmn) + if (regDomainPairs[i].reg_domain == regdmn) return ®DomainPairs[i]; } @@ -937,7 +986,6 @@ static void ath6kl_wmi_regdomain_event(struct wmi *wmi, u8 *datap, int len) { - struct ath6kl_wmi_regdomain *ev; struct country_code_to_enum_rd *country = NULL; struct reg_dmn_pair_mapping *regpair = NULL; @@ -947,15 +995,14 @@ ev = (struct ath6kl_wmi_regdomain *) datap; reg_code = le32_to_cpu(ev->reg_code); - if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG) + if ((reg_code >> ATH6KL_COUNTRY_RD_SHIFT) & COUNTRY_ERD_FLAG) { country = ath6kl_regd_find_country((u16) reg_code); - else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) { - + } else if (!(((u16) reg_code & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)) { regpair = ath6kl_get_regpair((u16) reg_code); country = ath6kl_regd_find_country_by_rd((u16) reg_code); if (regpair) ath6kl_dbg(ATH6KL_DBG_WMI, "Regpair used: 0x%0x\n", - regpair->regDmnEnum); + regpair->reg_domain); else ath6kl_warn("Regpair not found reg_code 0x%0x\n", reg_code); @@ -1045,7 +1092,6 @@ u8 *buf; struct ieee80211_channel *channel; struct ath6kl *ar = wmi->parent_dev; - struct ieee80211_mgmt *mgmt; struct cfg80211_bss *bss; if (len <= sizeof(struct wmi_bss_info_hdr2)) @@ -1091,39 +1137,15 @@ } } - /* - * In theory, use of cfg80211_inform_bss() would be more natural here - * since we do not have the full frame. However, at least for now, - * cfg80211 can only distinguish Beacon and Probe Response frames from - * each other when using cfg80211_inform_bss_frame(), so let's build a - * fake IEEE 802.11 header to be able to take benefit of this. - */ - mgmt = kmalloc(24 + len, GFP_ATOMIC); - if (mgmt == NULL) - return -EINVAL; - - if (bih->frame_type == BEACON_FTYPE) { - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_BEACON); - memset(mgmt->da, 0xff, ETH_ALEN); - } else { - struct net_device *dev = vif->ndev; - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_PROBE_RESP); - memcpy(mgmt->da, dev->dev_addr, ETH_ALEN); - } - mgmt->duration = cpu_to_le16(0); - memcpy(mgmt->sa, bih->bssid, ETH_ALEN); - memcpy(mgmt->bssid, bih->bssid, ETH_ALEN); - mgmt->seq_ctrl = cpu_to_le16(0); - - memcpy(&mgmt->u.beacon, buf, len); - - bss = cfg80211_inform_bss_frame(ar->wiphy, channel, mgmt, - 24 + len, (bih->snr - 95) * 100, - GFP_ATOMIC); - kfree(mgmt); + bss = cfg80211_inform_bss(ar->wiphy, channel, + bih->frame_type == BEACON_FTYPE ? + CFG80211_BSS_FTYPE_BEACON : + CFG80211_BSS_FTYPE_PRESP, + bih->bssid, get_unaligned_le64((__le64 *)buf), + get_unaligned_le16(((__le16 *)buf) + 5), + get_unaligned_le16(((__le16 *)buf) + 4), + buf + 8 + 2 + 2, len - 8 - 2 - 2, + (bih->snr - 95) * 100, GFP_ATOMIC); if (bss == NULL) return -ENOMEM; cfg80211_put_bss(ar->wiphy, bss); @@ -1500,7 +1522,6 @@ if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) && (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) { - ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion); tsinfo = le16_to_cpu(ts->tsinfo); tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) & @@ -1531,7 +1552,6 @@ * for delete qos stream from AP */ else if (reply->cac_indication == CAC_INDICATION_DELETE) { - ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion); tsinfo = le16_to_cpu(ts->tsinfo); ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) & @@ -2323,7 +2343,7 @@ return ret; } -int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, u8 *krk) +int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 if_idx, const u8 *krk) { struct sk_buff *skb; struct wmi_add_krk_cmd *cmd; @@ -2480,7 +2500,6 @@ goto free_data_skb; for (index = 0; index < num_pri_streams; index++) { - if (WARN_ON(!data_sync_bufs[index].skb)) goto free_data_skb; @@ -2705,7 +2724,6 @@ for (i = 0; i < WMM_NUM_AC; i++) { if (stream_exist & (1 << i)) { - /* * FIXME: Is this lock & unlock inside * for loop correct? may need rework. @@ -2755,9 +2773,9 @@ mask->control[band].legacy << 4; /* copy mcs rate mask */ - mcsrate = mask->control[band].mcs[1]; + mcsrate = mask->control[band].ht_mcs[1]; mcsrate <<= 8; - mcsrate |= mask->control[band].mcs[0]; + mcsrate |= mask->control[band].ht_mcs[0]; ratemask[band] |= mcsrate << 12; ratemask[band] |= mcsrate << 28; } @@ -2807,7 +2825,7 @@ mask->control[band].legacy << 4; /* copy mcs rate mask */ - mcsrate = mask->control[band].mcs[0]; + mcsrate = mask->control[band].ht_mcs[0]; ratemask[band] |= mcsrate << 12; ratemask[band] |= mcsrate << 20; } @@ -2843,7 +2861,8 @@ { struct ath6kl *ar = wmi->parent_dev; - if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) + if (test_bit(ATH6KL_FW_CAPABILITY_64BIT_RATES, + ar->fw_capabilities)) return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); else return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); @@ -2871,8 +2890,9 @@ if (host_mode == ATH6KL_HOST_MODE_ASLEEP) { ath6kl_wmi_relinquish_implicit_pstream_credits(wmi); cmd->asleep = cpu_to_le32(1); - } else + } else { cmd->awake = cpu_to_le32(1); + } ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_HOST_SLEEP_MODE_CMDID, @@ -3283,9 +3303,11 @@ NO_SYNC_WMIFLAG); } -s32 ath6kl_wmi_get_rate(s8 rate_index) +s32 ath6kl_wmi_get_rate(struct wmi *wmi, s8 rate_index) { + struct ath6kl *ar = wmi->parent_dev; u8 sgi = 0; + s32 ret; if (rate_index == RATE_AUTO) return 0; @@ -3296,10 +3318,20 @@ sgi = 1; } - if (WARN_ON(rate_index > RATE_MCS_7_40)) - rate_index = RATE_MCS_7_40; + if (test_bit(ATH6KL_FW_CAPABILITY_RATETABLE_MCS15, + ar->fw_capabilities)) { + if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl_mcs15))) + return 0; + + ret = wmi_rate_tbl_mcs15[(u32) rate_index][sgi]; + } else { + if (WARN_ON(rate_index >= ARRAY_SIZE(wmi_rate_tbl))) + return 0; + + ret = wmi_rate_tbl[(u32) rate_index][sgi]; + } - return wmi_rate_tbl[(u32) rate_index][sgi]; + return ret; } static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,