old mode 100644new mode 100755| .. | .. |
|---|
| 469 | 469 | iter_cnt_to_send -= cnt; |
|---|
| 470 | 470 | cache->tot_consumed += cnt; |
|---|
| 471 | 471 | /* Push the data to the skb */ |
|---|
| 472 | | -#ifdef ANDROID13_KERNEL515_BKPORT |
|---|
| 473 | | - nla_put_nohdr(skb, cnt * sizeof(wifi_gscan_result_t), ptr); |
|---|
| 474 | | -#else |
|---|
| 475 | 472 | nla_append(skb, cnt * sizeof(wifi_gscan_result_t), ptr); |
|---|
| 476 | | -#endif |
|---|
| 477 | 473 | if (cache->tot_consumed == cache->tot_count) { |
|---|
| 478 | 474 | cache = cache->next; |
|---|
| 479 | 475 | } |
|---|
| .. | .. |
|---|
| 1214 | 1210 | { |
|---|
| 1215 | 1211 | int err = 0, type, band; |
|---|
| 1216 | 1212 | struct bcm_cfg80211 *cfg = wiphy_priv(wiphy); |
|---|
| 1217 | | - uint32 *reply = NULL; |
|---|
| 1213 | + uint16 *reply = NULL; |
|---|
| 1218 | 1214 | uint32 reply_len = 0, num_channels, mem_needed; |
|---|
| 1219 | 1215 | struct sk_buff *skb; |
|---|
| 1220 | 1216 | dhd_pub_t *dhdp; |
|---|
| .. | .. |
|---|
| 2812 | 2808 | |
|---|
| 2813 | 2809 | ret = dhd_cfgvendor_priv_string_handler(cfg, wdev, nlioc, buf); |
|---|
| 2814 | 2810 | if (ret) { |
|---|
| 2815 | | - WL_ERR(("dhd_cfgvendor returned error %d\n", ret)); |
|---|
| 2811 | + WL_ERR(("dhd_cfgvendor returned error %d", ret)); |
|---|
| 2816 | 2812 | vfree(buf); |
|---|
| 2817 | 2813 | return ret; |
|---|
| 2818 | 2814 | } |
|---|
| .. | .. |
|---|
| 7149 | 7145 | dtoh32(cca_result->secs[0].congest_obss), |
|---|
| 7150 | 7146 | dtoh32(cca_result->secs[0].interference))); |
|---|
| 7151 | 7147 | } else { |
|---|
| 7152 | | - WL_INFORM(("cca_get_stats is unsupported \n")); |
|---|
| 7148 | + WL_ERR(("cca_get_stats is unsupported \n")); |
|---|
| 7153 | 7149 | } |
|---|
| 7154 | 7150 | |
|---|
| 7155 | 7151 | /* If cca_get_stats is unsupported, cca_busy_time has zero value as initial value */ |
|---|
| .. | .. |
|---|
| 9046 | 9042 | } |
|---|
| 9047 | 9043 | #endif /* WL_SAR_TX_POWER */ |
|---|
| 9048 | 9044 | |
|---|
| 9049 | | -#if !defined(WL_TWT) && defined(WL_TWT_HAL_IF) |
|---|
| 9050 | | -static int |
|---|
| 9051 | | -wl_cfgvendor_twt_setup(struct wiphy *wiphy, |
|---|
| 9052 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9053 | | -{ |
|---|
| 9054 | | - wl_twt_config_t val; |
|---|
| 9055 | | - s32 bw; |
|---|
| 9056 | | - s32 type, rem_attr; |
|---|
| 9057 | | - u8 mybuf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9058 | | - u8 resp_buf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9059 | | - const struct nlattr *iter; |
|---|
| 9060 | | - uint8 *rem = mybuf; |
|---|
| 9061 | | - uint16 rem_len = sizeof(mybuf); |
|---|
| 9062 | | - |
|---|
| 9063 | | - bzero(&val, sizeof(val)); |
|---|
| 9064 | | - val.version = WL_TWT_SETUP_VER; |
|---|
| 9065 | | - val.length = sizeof(val.version) + sizeof(val.length); |
|---|
| 9066 | | - |
|---|
| 9067 | | - /* Default values, Override Below */ |
|---|
| 9068 | | - val.desc.flow_flags = 0; |
|---|
| 9069 | | - val.desc.wake_time_h = 0xFFFFFFFF; |
|---|
| 9070 | | - val.desc.wake_time_l = 0xFFFFFFFF; |
|---|
| 9071 | | - val.desc.wake_int_min = 0xFFFFFFFF; |
|---|
| 9072 | | - val.desc.wake_int_max = 0xFFFFFFFF; |
|---|
| 9073 | | - val.desc.wake_dur_min = 0xFFFFFFFF; |
|---|
| 9074 | | - val.desc.wake_dur_max = 0xFFFFFFFF; |
|---|
| 9075 | | - val.desc.avg_pkt_num = 0xFFFFFFFF; |
|---|
| 9076 | | - val.desc.avg_pkt_size = 0xFFFFFFFF; |
|---|
| 9077 | | - |
|---|
| 9078 | | - nla_for_each_attr(iter, data, len, rem_attr) { |
|---|
| 9079 | | - type = nla_type(iter); |
|---|
| 9080 | | - switch (type) { |
|---|
| 9081 | | - case ANDR_TWT_ATTR_CONFIG_ID: |
|---|
| 9082 | | - /* Config ID */ |
|---|
| 9083 | | - val.desc.configID = nla_get_u8(iter); |
|---|
| 9084 | | - break; |
|---|
| 9085 | | - case ANDR_TWT_ATTR_NEGOTIATION_TYPE: |
|---|
| 9086 | | - /* negotiation_type */ |
|---|
| 9087 | | - val.desc.negotiation_type = nla_get_u8(iter); |
|---|
| 9088 | | - break; |
|---|
| 9089 | | - case ANDR_TWT_ATTR_TRIGGER_TYPE: |
|---|
| 9090 | | - /* Trigger Type */ |
|---|
| 9091 | | - if (nla_get_u8(iter) == 1) { |
|---|
| 9092 | | - val.desc.flow_flags |= WL_TWT_FLOW_FLAG_TRIGGER; |
|---|
| 9093 | | - } |
|---|
| 9094 | | - break; |
|---|
| 9095 | | - case ANDR_TWT_ATTR_WAKE_DURATION: |
|---|
| 9096 | | - /* Wake Duration */ |
|---|
| 9097 | | - val.desc.wake_dur = nla_get_u32(iter); |
|---|
| 9098 | | - break; |
|---|
| 9099 | | - case ANDR_TWT_ATTR_WAKE_INTERVAL: |
|---|
| 9100 | | - /* Wake interval */ |
|---|
| 9101 | | - val.desc.wake_int = nla_get_u32(iter); |
|---|
| 9102 | | - break; |
|---|
| 9103 | | - case ANDR_TWT_ATTR_WAKETIME_OFFSET: |
|---|
| 9104 | | - /* Wake Time parameter */ |
|---|
| 9105 | | - val.desc.wake_time_h = 0; |
|---|
| 9106 | | - val.desc.wake_time_l = nla_get_u32(iter); |
|---|
| 9107 | | - break; |
|---|
| 9108 | | - case ANDR_TWT_ATTR_WAKE_INTERVAL_MIN: |
|---|
| 9109 | | - /* Minimum allowed Wake interval */ |
|---|
| 9110 | | - val.desc.wake_int_min = nla_get_u32(iter); |
|---|
| 9111 | | - break; |
|---|
| 9112 | | - case ANDR_TWT_ATTR_WAKE_INTERVAL_MAX: |
|---|
| 9113 | | - /* Max Allowed Wake interval */ |
|---|
| 9114 | | - val.desc.wake_int_max = nla_get_u32(iter); |
|---|
| 9115 | | - break; |
|---|
| 9116 | | - case ANDR_TWT_ATTR_WAKE_DURATION_MIN: |
|---|
| 9117 | | - /* Minimum allowed Wake duration */ |
|---|
| 9118 | | - val.desc.wake_dur_min = nla_get_u32(iter); |
|---|
| 9119 | | - break; |
|---|
| 9120 | | - case ANDR_TWT_ATTR_WAKE_DURATION_MAX: |
|---|
| 9121 | | - /* Maximum allowed Wake duration */ |
|---|
| 9122 | | - val.desc.wake_dur_max = nla_get_u32(iter); |
|---|
| 9123 | | - break; |
|---|
| 9124 | | - case ANDR_TWT_ATTR_AVG_PKT_NUM: |
|---|
| 9125 | | - /* Average number of packets */ |
|---|
| 9126 | | - val.desc.avg_pkt_num = nla_get_u32(iter); |
|---|
| 9127 | | - break; |
|---|
| 9128 | | - case ANDR_TWT_ATTR_AVG_PKT_SIZE: |
|---|
| 9129 | | - /* Average packets size */ |
|---|
| 9130 | | - val.desc.avg_pkt_size = nla_get_u32(iter); |
|---|
| 9131 | | - break; |
|---|
| 9132 | | - default: |
|---|
| 9133 | | - WL_ERR(("Invalid setup attribute type %d\n", type)); |
|---|
| 9134 | | - break; |
|---|
| 9135 | | - } |
|---|
| 9136 | | - } |
|---|
| 9137 | | - |
|---|
| 9138 | | - bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_CONFIG, |
|---|
| 9139 | | - sizeof(val), (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32); |
|---|
| 9140 | | - if (bw != BCME_OK) { |
|---|
| 9141 | | - goto exit; |
|---|
| 9142 | | - } |
|---|
| 9143 | | - |
|---|
| 9144 | | - bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", |
|---|
| 9145 | | - mybuf, sizeof(mybuf) - rem_len, resp_buf, WLC_IOCTL_SMLEN, NULL); |
|---|
| 9146 | | - if (bw < 0) { |
|---|
| 9147 | | - WL_ERR(("twt config set failed. ret:%d\n", bw)); |
|---|
| 9148 | | - } else { |
|---|
| 9149 | | - WL_INFORM(("twt config setup succeeded, config ID %d " |
|---|
| 9150 | | - "Negotiation type %d flow flags %d\n", val.desc.configID, |
|---|
| 9151 | | - val.desc.negotiation_type, val.desc.flow_flags)); |
|---|
| 9152 | | - } |
|---|
| 9153 | | - |
|---|
| 9154 | | -exit: |
|---|
| 9155 | | - return bw; |
|---|
| 9156 | | -} |
|---|
| 9157 | | - |
|---|
| 9158 | | -static int |
|---|
| 9159 | | -wl_cfgvendor_twt_teardown(struct wiphy *wiphy, |
|---|
| 9160 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9161 | | -{ |
|---|
| 9162 | | - wl_twt_teardown_t val; |
|---|
| 9163 | | - s32 bw; |
|---|
| 9164 | | - s32 type, rem_attr; |
|---|
| 9165 | | - u8 mybuf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9166 | | - u8 res_buf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9167 | | - const struct nlattr *iter; |
|---|
| 9168 | | - uint8 *rem = mybuf; |
|---|
| 9169 | | - uint16 rem_len = sizeof(mybuf); |
|---|
| 9170 | | - |
|---|
| 9171 | | - bzero(&val, sizeof(val)); |
|---|
| 9172 | | - val.version = WL_TWT_TEARDOWN_VER; |
|---|
| 9173 | | - val.length = sizeof(val.version) + sizeof(val.length); |
|---|
| 9174 | | - |
|---|
| 9175 | | - /* Default values, Override Below */ |
|---|
| 9176 | | - val.teardesc.flow_id = 0xFF; |
|---|
| 9177 | | - val.teardesc.bid = 0xFF; |
|---|
| 9178 | | - |
|---|
| 9179 | | - nla_for_each_attr(iter, data, len, rem_attr) { |
|---|
| 9180 | | - type = nla_type(iter); |
|---|
| 9181 | | - switch (type) { |
|---|
| 9182 | | - case ANDR_TWT_ATTR_CONFIG_ID: |
|---|
| 9183 | | - /* Config ID */ |
|---|
| 9184 | | - val.configID = nla_get_u8(iter); |
|---|
| 9185 | | - break; |
|---|
| 9186 | | - case ANDR_TWT_ATTR_NEGOTIATION_TYPE: |
|---|
| 9187 | | - /* negotiation_type */ |
|---|
| 9188 | | - val.teardesc.negotiation_type = nla_get_u8(iter); |
|---|
| 9189 | | - break; |
|---|
| 9190 | | - case ANDR_TWT_ATTR_ALL_TWT: |
|---|
| 9191 | | - /* all twt */ |
|---|
| 9192 | | - val.teardesc.alltwt = nla_get_u8(iter); |
|---|
| 9193 | | - break; |
|---|
| 9194 | | - default: |
|---|
| 9195 | | - WL_ERR(("Invalid teardown attribute type %d\n", type)); |
|---|
| 9196 | | - break; |
|---|
| 9197 | | - } |
|---|
| 9198 | | - } |
|---|
| 9199 | | - |
|---|
| 9200 | | - bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_TEARDOWN, |
|---|
| 9201 | | - sizeof(val), (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32); |
|---|
| 9202 | | - if (bw != BCME_OK) { |
|---|
| 9203 | | - goto exit; |
|---|
| 9204 | | - } |
|---|
| 9205 | | - |
|---|
| 9206 | | - bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", |
|---|
| 9207 | | - mybuf, sizeof(mybuf) - rem_len, res_buf, WLC_IOCTL_SMLEN, NULL); |
|---|
| 9208 | | - if (bw < 0) { |
|---|
| 9209 | | - WL_ERR(("twt teardown failed. ret:%d\n", bw)); |
|---|
| 9210 | | - } else { |
|---|
| 9211 | | - WL_INFORM(("twt teardown succeeded, config ID %d " |
|---|
| 9212 | | - "Negotiation type %d alltwt %d\n", val.configID, |
|---|
| 9213 | | - val.teardesc.negotiation_type, val.teardesc.alltwt)); |
|---|
| 9214 | | - } |
|---|
| 9215 | | - |
|---|
| 9216 | | -exit: |
|---|
| 9217 | | - return bw; |
|---|
| 9218 | | -} |
|---|
| 9219 | | - |
|---|
| 9220 | | -static int |
|---|
| 9221 | | -wl_cfgvendor_twt_info_frame(struct wiphy *wiphy, |
|---|
| 9222 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9223 | | -{ |
|---|
| 9224 | | - wl_twt_info_t val; |
|---|
| 9225 | | - int bw; |
|---|
| 9226 | | - s32 type, rem_attr; |
|---|
| 9227 | | - const struct nlattr *iter; |
|---|
| 9228 | | - u8 mybuf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9229 | | - u8 res_buf[WLC_IOCTL_SMLEN] = {0}; |
|---|
| 9230 | | - uint8 *rem = mybuf; |
|---|
| 9231 | | - uint16 rem_len = sizeof(mybuf); |
|---|
| 9232 | | - uint32 val32 = 0; |
|---|
| 9233 | | - |
|---|
| 9234 | | - bzero(&val, sizeof(val)); |
|---|
| 9235 | | - val.version = WL_TWT_INFO_VER; |
|---|
| 9236 | | - val.length = sizeof(val.version) + sizeof(val.length); |
|---|
| 9237 | | - |
|---|
| 9238 | | - /* Default values, Override Below */ |
|---|
| 9239 | | - val.infodesc.flow_id = 0xFF; |
|---|
| 9240 | | - val.desc.next_twt_h = 0xFFFFFFFF; |
|---|
| 9241 | | - val.desc.next_twt_l = 0xFFFFFFFF; |
|---|
| 9242 | | - |
|---|
| 9243 | | - nla_for_each_attr(iter, data, len, rem_attr) { |
|---|
| 9244 | | - type = nla_type(iter); |
|---|
| 9245 | | - if (type == ANDR_TWT_ATTR_CONFIG_ID) { |
|---|
| 9246 | | - /* Config ID */ |
|---|
| 9247 | | - val.configID = nla_get_u8(iter); |
|---|
| 9248 | | - } else if (type == ANDR_TWT_ATTR_RESUME_TIME) { |
|---|
| 9249 | | - /* Resume offset */ |
|---|
| 9250 | | - val32 = nla_get_u32(iter); |
|---|
| 9251 | | - if (!((val32 == 0) || (val32 == -1))) { |
|---|
| 9252 | | - val.infodesc.next_twt_h = 0; |
|---|
| 9253 | | - val.infodesc.next_twt_l = val32; |
|---|
| 9254 | | - val.infodesc.flow_flags |= WL_TWT_INFO_FLAG_RESUME; |
|---|
| 9255 | | - } |
|---|
| 9256 | | - } else if (type == ANDR_TWT_ATTR_ALL_TWT) { |
|---|
| 9257 | | - /* all twt */ |
|---|
| 9258 | | - val32 = (uint32)nla_get_u8(iter); |
|---|
| 9259 | | - if (val32) { |
|---|
| 9260 | | - val.infodesc.flow_flags |= WL_TWT_INFO_FLAG_ALL_TWT; |
|---|
| 9261 | | - } |
|---|
| 9262 | | - } else { |
|---|
| 9263 | | - WL_ERR(("Invalid info frame attribute type %d\n", type)); |
|---|
| 9264 | | - } |
|---|
| 9265 | | - } |
|---|
| 9266 | | - |
|---|
| 9267 | | - bw = bcm_pack_xtlv_entry(&rem, &rem_len, WL_TWT_CMD_INFO, |
|---|
| 9268 | | - sizeof(val), (uint8 *)&val, BCM_XTLV_OPTION_ALIGN32); |
|---|
| 9269 | | - if (bw != BCME_OK) { |
|---|
| 9270 | | - goto exit; |
|---|
| 9271 | | - } |
|---|
| 9272 | | - |
|---|
| 9273 | | - bw = wldev_iovar_setbuf(wdev_to_ndev(wdev), "twt", |
|---|
| 9274 | | - mybuf, sizeof(mybuf) - rem_len, res_buf, WLC_IOCTL_SMLEN, NULL); |
|---|
| 9275 | | - if (bw < 0) { |
|---|
| 9276 | | - WL_ERR(("twt info frame failed. ret:%d\n", bw)); |
|---|
| 9277 | | - } else { |
|---|
| 9278 | | - WL_INFORM(("twt info frame succeeded, config ID %d\n", val.configID)); |
|---|
| 9279 | | - } |
|---|
| 9280 | | - |
|---|
| 9281 | | -exit: |
|---|
| 9282 | | - return bw; |
|---|
| 9283 | | -} |
|---|
| 9284 | | - |
|---|
| 9285 | | -static int |
|---|
| 9286 | | -wl_cfgvendor_twt_stats_update_v2(struct wiphy *wiphy, wl_twt_stats_v2_t *stats) |
|---|
| 9287 | | -{ |
|---|
| 9288 | | - u32 i; |
|---|
| 9289 | | - wl_twt_peer_stats_v2_t *peer_stats; |
|---|
| 9290 | | - struct sk_buff *skb; |
|---|
| 9291 | | - int32 mem_needed; |
|---|
| 9292 | | - int ret = BCME_OK; |
|---|
| 9293 | | - |
|---|
| 9294 | | - mem_needed = BRCM_TWT_HAL_VENDOR_EVENT_BUF_LEN; |
|---|
| 9295 | | - |
|---|
| 9296 | | - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); |
|---|
| 9297 | | - if (unlikely(!skb)) { |
|---|
| 9298 | | - WL_ERR(("%s: can't allocate %d bytes\n", __FUNCTION__, mem_needed)); |
|---|
| 9299 | | - ret = -ENOMEM; |
|---|
| 9300 | | - goto fail; |
|---|
| 9301 | | - } |
|---|
| 9302 | | - |
|---|
| 9303 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_NUM_PEER_STATS, stats->num_stats); |
|---|
| 9304 | | - if (ret < 0) { |
|---|
| 9305 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_NUM_PEER_STATS, ret:%d\n", ret)); |
|---|
| 9306 | | - goto fail; |
|---|
| 9307 | | - } |
|---|
| 9308 | | - |
|---|
| 9309 | | - for (i = 0; i < stats->num_stats; i++) { |
|---|
| 9310 | | - peer_stats = &stats->peer_stats_list[i]; |
|---|
| 9311 | | - |
|---|
| 9312 | | - WL_INFORM_MEM(("%u %u %u %u %u", |
|---|
| 9313 | | - peer_stats->eosp_dur_avg, peer_stats->tx_pkts_avg, peer_stats->rx_pkts_avg, |
|---|
| 9314 | | - peer_stats->tx_pkt_sz_avg, peer_stats->rx_pkt_sz_avg)); |
|---|
| 9315 | | - ret = nla_put_u8(skb, ANDR_TWT_ATTR_CONFIG_ID, peer_stats->configID); |
|---|
| 9316 | | - if (ret < 0) { |
|---|
| 9317 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_CONFIG_ID, ret:%d\n", ret)); |
|---|
| 9318 | | - goto fail; |
|---|
| 9319 | | - } |
|---|
| 9320 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_AVG_PKT_NUM_TX, peer_stats->tx_pkts_avg); |
|---|
| 9321 | | - if (ret < 0) { |
|---|
| 9322 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_AVG_PKT_NUM_TX, ret:%d\n", ret)); |
|---|
| 9323 | | - goto fail; |
|---|
| 9324 | | - } |
|---|
| 9325 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_AVG_PKT_SIZE_TX, peer_stats->tx_pkt_sz_avg); |
|---|
| 9326 | | - if (ret < 0) { |
|---|
| 9327 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_AVG_PKT_SIZE_TX, ret:%d\n", ret)); |
|---|
| 9328 | | - goto fail; |
|---|
| 9329 | | - } |
|---|
| 9330 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_AVG_PKT_NUM_RX, peer_stats->rx_pkts_avg); |
|---|
| 9331 | | - if (ret < 0) { |
|---|
| 9332 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_AVG_PKT_NUM_RX, ret:%d\n", ret)); |
|---|
| 9333 | | - goto fail; |
|---|
| 9334 | | - } |
|---|
| 9335 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_AVG_PKT_SIZE_RX, peer_stats->rx_pkt_sz_avg); |
|---|
| 9336 | | - if (ret < 0) { |
|---|
| 9337 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_AVG_PKT_SIZE_RX, ret:%d\n", ret)); |
|---|
| 9338 | | - goto fail; |
|---|
| 9339 | | - } |
|---|
| 9340 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_AVG_EOSP_DUR, peer_stats->eosp_dur_avg); |
|---|
| 9341 | | - if (ret < 0) { |
|---|
| 9342 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_AVG_EOSP_DUR, ret:%d\n", ret)); |
|---|
| 9343 | | - goto fail; |
|---|
| 9344 | | - } |
|---|
| 9345 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_EOSP_CNT, peer_stats->eosp_count); |
|---|
| 9346 | | - if (ret < 0) { |
|---|
| 9347 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_EOSP_CNT, ret:%d\n", ret)); |
|---|
| 9348 | | - goto fail; |
|---|
| 9349 | | - } |
|---|
| 9350 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_NUM_SP, peer_stats->sp_seq); |
|---|
| 9351 | | - if (ret < 0) { |
|---|
| 9352 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_NUM_SP, ret:%d\n", ret)); |
|---|
| 9353 | | - goto fail; |
|---|
| 9354 | | - } |
|---|
| 9355 | | - } |
|---|
| 9356 | | - |
|---|
| 9357 | | - ret = cfg80211_vendor_cmd_reply(skb); |
|---|
| 9358 | | - if (unlikely(ret)) { |
|---|
| 9359 | | - WL_ERR(("vendor command reply failed, ret=%d\n", ret)); |
|---|
| 9360 | | - } |
|---|
| 9361 | | - return ret; |
|---|
| 9362 | | - |
|---|
| 9363 | | -fail: |
|---|
| 9364 | | - /* Free skb for failure cases */ |
|---|
| 9365 | | - if (skb) { |
|---|
| 9366 | | - kfree_skb(skb); |
|---|
| 9367 | | - } |
|---|
| 9368 | | - return ret; |
|---|
| 9369 | | -} |
|---|
| 9370 | | - |
|---|
| 9371 | | -static int |
|---|
| 9372 | | -wl_cfgvendor_twt_stats(struct wiphy *wiphy, |
|---|
| 9373 | | - struct wireless_dev *wdev, const void *data, int len, bool clear_stats) |
|---|
| 9374 | | -{ |
|---|
| 9375 | | - wl_twt_stats_cmd_v1_t query; |
|---|
| 9376 | | - wl_twt_stats_v2_t stats_v2; |
|---|
| 9377 | | - s32 type, rem_attr; |
|---|
| 9378 | | - const struct nlattr *iter; |
|---|
| 9379 | | - int ret = BCME_OK; |
|---|
| 9380 | | - char iovbuf[WLC_IOCTL_SMLEN] = {0, }; |
|---|
| 9381 | | - uint8 *pxtlv = NULL; |
|---|
| 9382 | | - uint8 *iovresp = NULL; |
|---|
| 9383 | | - uint16 buflen = 0, bufstart = 0; |
|---|
| 9384 | | - struct bcm_cfg80211 *cfg = wl_get_cfg(wdev_to_ndev(wdev)); |
|---|
| 9385 | | - |
|---|
| 9386 | | - bzero(&query, sizeof(query)); |
|---|
| 9387 | | - query.version = WL_TWT_STATS_CMD_VERSION_1; |
|---|
| 9388 | | - query.length = sizeof(query) - OFFSETOF(wl_twt_stats_cmd_v1_t, peer); |
|---|
| 9389 | | - |
|---|
| 9390 | | - /* Default values, Override Below */ |
|---|
| 9391 | | - query.num_bid = 0xFF; |
|---|
| 9392 | | - query.num_fid = 0xFF; |
|---|
| 9393 | | - |
|---|
| 9394 | | - if (clear_stats) { |
|---|
| 9395 | | - query.flags |= WL_TWT_STATS_CMD_FLAGS_RESET; |
|---|
| 9396 | | - } |
|---|
| 9397 | | - nla_for_each_attr(iter, data, len, rem_attr) { |
|---|
| 9398 | | - type = nla_type(iter); |
|---|
| 9399 | | - if (type == ANDR_TWT_ATTR_CONFIG_ID) { |
|---|
| 9400 | | - /* Config ID */ |
|---|
| 9401 | | - query.configID = nla_get_u8(iter); |
|---|
| 9402 | | - } else { |
|---|
| 9403 | | - WL_ERR(("Invalid TWT stats attribute type %d\n", type)); |
|---|
| 9404 | | - } |
|---|
| 9405 | | - } |
|---|
| 9406 | | - |
|---|
| 9407 | | - iovresp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
|---|
| 9408 | | - if (iovresp == NULL) { |
|---|
| 9409 | | - WL_ERR(("%s: iov resp memory alloc exited\n", __FUNCTION__)); |
|---|
| 9410 | | - goto exit; |
|---|
| 9411 | | - } |
|---|
| 9412 | | - |
|---|
| 9413 | | - buflen = bufstart = WLC_IOCTL_SMLEN; |
|---|
| 9414 | | - pxtlv = (uint8 *)iovbuf; |
|---|
| 9415 | | - ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_TWT_CMD_STATS, |
|---|
| 9416 | | - sizeof(query), (uint8 *)&query, BCM_XTLV_OPTION_ALIGN32); |
|---|
| 9417 | | - if (ret != BCME_OK) { |
|---|
| 9418 | | - WL_ERR(("%s : Error return during pack xtlv :%d\n", __FUNCTION__, ret)); |
|---|
| 9419 | | - goto exit; |
|---|
| 9420 | | - } |
|---|
| 9421 | | - |
|---|
| 9422 | | - if ((ret = wldev_iovar_getbuf(wdev_to_ndev(wdev), "twt", iovbuf, bufstart-buflen, |
|---|
| 9423 | | - iovresp, WLC_IOCTL_MEDLEN, NULL))) { |
|---|
| 9424 | | - WL_ERR(("twt status failed with err=%d \n", ret)); |
|---|
| 9425 | | - goto exit; |
|---|
| 9426 | | - } |
|---|
| 9427 | | - |
|---|
| 9428 | | - (void)memcpy_s(&stats_v2, sizeof(stats_v2), iovresp, sizeof(stats_v2)); |
|---|
| 9429 | | - |
|---|
| 9430 | | - if (dtoh16(stats_v2.version) == WL_TWT_STATS_VERSION_2) { |
|---|
| 9431 | | - if (!clear_stats) { |
|---|
| 9432 | | - WL_ERR(("stats query ver %d, \n", dtoh16(stats_v2.version))); |
|---|
| 9433 | | - ret = wl_cfgvendor_twt_stats_update_v2(wiphy, (wl_twt_stats_v2_t*)iovresp); |
|---|
| 9434 | | - } |
|---|
| 9435 | | - } else { |
|---|
| 9436 | | - ret = BCME_UNSUPPORTED; |
|---|
| 9437 | | - WL_ERR(("Version 1 unsupported. ver %d, \n", dtoh16(stats_v2.version))); |
|---|
| 9438 | | - goto exit; |
|---|
| 9439 | | - } |
|---|
| 9440 | | - |
|---|
| 9441 | | -exit: |
|---|
| 9442 | | - if (iovresp) { |
|---|
| 9443 | | - MFREE(cfg->osh, iovresp, WLC_IOCTL_MEDLEN); |
|---|
| 9444 | | - } |
|---|
| 9445 | | - |
|---|
| 9446 | | - return ret; |
|---|
| 9447 | | -} |
|---|
| 9448 | | - |
|---|
| 9449 | | -static int |
|---|
| 9450 | | -wl_cfgvendor_twt_get_stats(struct wiphy *wiphy, |
|---|
| 9451 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9452 | | -{ |
|---|
| 9453 | | - return wl_cfgvendor_twt_stats(wiphy, wdev, data, len, false); |
|---|
| 9454 | | -} |
|---|
| 9455 | | - |
|---|
| 9456 | | -static int |
|---|
| 9457 | | -wl_cfgvendor_twt_clear_stats(struct wiphy *wiphy, |
|---|
| 9458 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9459 | | -{ |
|---|
| 9460 | | - return wl_cfgvendor_twt_stats(wiphy, wdev, data, len, true); |
|---|
| 9461 | | -} |
|---|
| 9462 | | - |
|---|
| 9463 | | -static int |
|---|
| 9464 | | -wl_cfgvendor_twt_update_cap(struct wiphy *wiphy, wl_twt_cap_t *result) |
|---|
| 9465 | | -{ |
|---|
| 9466 | | - struct sk_buff *skb; |
|---|
| 9467 | | - int32 mem_needed; |
|---|
| 9468 | | - int ret = BCME_OK; |
|---|
| 9469 | | - |
|---|
| 9470 | | - WL_INFORM_MEM(("TWT Capabilites Device,Peer 0x%04x 0x%04x\n", |
|---|
| 9471 | | - result->device_cap, result->peer_cap)); |
|---|
| 9472 | | - |
|---|
| 9473 | | - mem_needed = VENDOR_REPLY_OVERHEAD + (ATTRIBUTE_U32_LEN * 2); |
|---|
| 9474 | | - |
|---|
| 9475 | | - skb = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, mem_needed); |
|---|
| 9476 | | - if (unlikely(!skb)) { |
|---|
| 9477 | | - WL_ERR(("%s: can't allocate %d bytes\n", __FUNCTION__, mem_needed)); |
|---|
| 9478 | | - ret = -ENOMEM; |
|---|
| 9479 | | - goto fail; |
|---|
| 9480 | | - } |
|---|
| 9481 | | - |
|---|
| 9482 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_DEVICE_CAP, result->device_cap); |
|---|
| 9483 | | - if (ret < 0) { |
|---|
| 9484 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_DEVICE_CAP, ret:%d\n", ret)); |
|---|
| 9485 | | - goto fail; |
|---|
| 9486 | | - } |
|---|
| 9487 | | - ret = nla_put_u32(skb, ANDR_TWT_ATTR_PEER_CAP, result->peer_cap); |
|---|
| 9488 | | - if (ret < 0) { |
|---|
| 9489 | | - WL_ERR(("Failed to put ANDR_TWT_ATTR_PEER_CAP, ret:%d\n", ret)); |
|---|
| 9490 | | - goto fail; |
|---|
| 9491 | | - } |
|---|
| 9492 | | - |
|---|
| 9493 | | - ret = cfg80211_vendor_cmd_reply(skb); |
|---|
| 9494 | | - if (unlikely(ret)) { |
|---|
| 9495 | | - WL_ERR(("vendor command reply failed, ret=%d\n", ret)); |
|---|
| 9496 | | - } |
|---|
| 9497 | | - return ret; |
|---|
| 9498 | | - |
|---|
| 9499 | | -fail: |
|---|
| 9500 | | - /* Free skb for failure cases */ |
|---|
| 9501 | | - if (skb) { |
|---|
| 9502 | | - kfree_skb(skb); |
|---|
| 9503 | | - } |
|---|
| 9504 | | - return ret; |
|---|
| 9505 | | -} |
|---|
| 9506 | | - |
|---|
| 9507 | | -static int |
|---|
| 9508 | | -wl_cfgvendor_twt_cap(struct wiphy *wiphy, |
|---|
| 9509 | | - struct wireless_dev *wdev, const void *data, int len) |
|---|
| 9510 | | -{ |
|---|
| 9511 | | - int ret = BCME_OK; |
|---|
| 9512 | | - char iovbuf[WLC_IOCTL_SMLEN] = {0, }; |
|---|
| 9513 | | - uint8 *pxtlv = NULL; |
|---|
| 9514 | | - uint8 *iovresp = NULL; |
|---|
| 9515 | | - wl_twt_cap_cmd_t cmd_cap; |
|---|
| 9516 | | - wl_twt_cap_t result; |
|---|
| 9517 | | - |
|---|
| 9518 | | - uint16 buflen = 0, bufstart = 0; |
|---|
| 9519 | | - struct bcm_cfg80211 *cfg = wl_get_cfg(wdev_to_ndev(wdev)); |
|---|
| 9520 | | - |
|---|
| 9521 | | - bzero(&cmd_cap, sizeof(cmd_cap)); |
|---|
| 9522 | | - |
|---|
| 9523 | | - cmd_cap.version = WL_TWT_CAP_CMD_VERSION_1; |
|---|
| 9524 | | - cmd_cap.length = sizeof(cmd_cap) - OFFSETOF(wl_twt_cap_cmd_t, peer); |
|---|
| 9525 | | - |
|---|
| 9526 | | - iovresp = (uint8 *)MALLOCZ(cfg->osh, WLC_IOCTL_MEDLEN); |
|---|
| 9527 | | - if (iovresp == NULL) { |
|---|
| 9528 | | - WL_ERR(("%s: iov resp memory alloc exited\n", __FUNCTION__)); |
|---|
| 9529 | | - goto exit; |
|---|
| 9530 | | - } |
|---|
| 9531 | | - |
|---|
| 9532 | | - buflen = bufstart = WLC_IOCTL_SMLEN; |
|---|
| 9533 | | - pxtlv = (uint8 *)iovbuf; |
|---|
| 9534 | | - |
|---|
| 9535 | | - ret = bcm_pack_xtlv_entry(&pxtlv, &buflen, WL_TWT_CMD_CAP, |
|---|
| 9536 | | - sizeof(cmd_cap), (uint8 *)&cmd_cap, BCM_XTLV_OPTION_ALIGN32); |
|---|
| 9537 | | - if (ret != BCME_OK) { |
|---|
| 9538 | | - WL_ERR(("%s : Error return during pack xtlv :%d\n", __FUNCTION__, ret)); |
|---|
| 9539 | | - goto exit; |
|---|
| 9540 | | - } |
|---|
| 9541 | | - |
|---|
| 9542 | | - if ((ret = wldev_iovar_getbuf(wdev_to_ndev(wdev), "twt", iovbuf, bufstart-buflen, |
|---|
| 9543 | | - iovresp, WLC_IOCTL_MEDLEN, NULL))) { |
|---|
| 9544 | | - WL_ERR(("Getting twt status failed with err=%d \n", ret)); |
|---|
| 9545 | | - goto exit; |
|---|
| 9546 | | - } |
|---|
| 9547 | | - |
|---|
| 9548 | | - (void)memcpy_s(&result, sizeof(result), iovresp, sizeof(result)); |
|---|
| 9549 | | - |
|---|
| 9550 | | - if (dtoh16(result.version) == WL_TWT_CAP_CMD_VERSION_1) { |
|---|
| 9551 | | - WL_ERR(("capability ver %d, \n", dtoh16(result.version))); |
|---|
| 9552 | | - ret = wl_cfgvendor_twt_update_cap(wiphy, &result); |
|---|
| 9553 | | - return ret; |
|---|
| 9554 | | - } else { |
|---|
| 9555 | | - ret = BCME_UNSUPPORTED; |
|---|
| 9556 | | - WL_ERR(("Version 1 unsupported. ver %d, \n", dtoh16(result.version))); |
|---|
| 9557 | | - goto exit; |
|---|
| 9558 | | - } |
|---|
| 9559 | | - |
|---|
| 9560 | | -exit: |
|---|
| 9561 | | - if (iovresp) { |
|---|
| 9562 | | - MFREE(cfg->osh, iovresp, WLC_IOCTL_MEDLEN); |
|---|
| 9563 | | - } |
|---|
| 9564 | | - |
|---|
| 9565 | | - return ret; |
|---|
| 9566 | | -} |
|---|
| 9567 | | - |
|---|
| 9568 | | -static int |
|---|
| 9569 | | -wl_cfgvendor_twt_update_setup_response(struct sk_buff *skb, void *event_data) |
|---|
| 9570 | | -{ |
|---|
| 9571 | | - s32 err = BCME_OK; |
|---|
| 9572 | | - const wl_twt_setup_cplt_t *setup_cplt = (wl_twt_setup_cplt_t *)event_data; |
|---|
| 9573 | | - const wl_twt_sdesc_t *sdesc = (const wl_twt_sdesc_t *)&setup_cplt[1]; |
|---|
| 9574 | | - |
|---|
| 9575 | | - WL_DBG(("TWT_SETUP: status %d, reason %d, configID %d, setup_cmd %d, flow_flags 0x%x," |
|---|
| 9576 | | - " flow_id %d, channel %d, negotiation_type %d, wake_time_h %u, wake_time_l %u," |
|---|
| 9577 | | - " wake_dur %u, wake_int %u\n", |
|---|
| 9578 | | - (int)setup_cplt->status, (int)setup_cplt->reason_code, (int)setup_cplt->configID, |
|---|
| 9579 | | - (int)sdesc->setup_cmd, sdesc->flow_flags, (int)sdesc->flow_id, (int)sdesc->channel, |
|---|
| 9580 | | - (int)sdesc->negotiation_type, sdesc->wake_time_h, sdesc->wake_time_l, |
|---|
| 9581 | | - sdesc->wake_dur, sdesc->wake_int)); |
|---|
| 9582 | | - |
|---|
| 9583 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_SUB_EVENT, ANDR_TWT_EVENT_SETUP); |
|---|
| 9584 | | - if (unlikely(err)) { |
|---|
| 9585 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_SUB_EVENT failed\n")); |
|---|
| 9586 | | - goto fail; |
|---|
| 9587 | | - } |
|---|
| 9588 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_CONFIG_ID, setup_cplt->configID); |
|---|
| 9589 | | - if (unlikely(err)) { |
|---|
| 9590 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_CONFIG_ID failed\n")); |
|---|
| 9591 | | - goto fail; |
|---|
| 9592 | | - } |
|---|
| 9593 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_REASON_CODE, setup_cplt->reason_code); |
|---|
| 9594 | | - if (unlikely(err)) { |
|---|
| 9595 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_REASON_CODE failed\n")); |
|---|
| 9596 | | - goto fail; |
|---|
| 9597 | | - } |
|---|
| 9598 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_STATUS, !!(setup_cplt->status)); |
|---|
| 9599 | | - if (unlikely(err)) { |
|---|
| 9600 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_STATUS failed\n")); |
|---|
| 9601 | | - goto fail; |
|---|
| 9602 | | - } |
|---|
| 9603 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_NEGOTIATION_TYPE, sdesc->negotiation_type); |
|---|
| 9604 | | - if (unlikely(err)) { |
|---|
| 9605 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_NEGOTIATION_TYPE failed\n")); |
|---|
| 9606 | | - goto fail; |
|---|
| 9607 | | - } |
|---|
| 9608 | | - err = nla_put_u32(skb, ANDR_TWT_ATTR_WAKE_DURATION, sdesc->wake_dur); |
|---|
| 9609 | | - if (unlikely(err)) { |
|---|
| 9610 | | - WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKE_DURATION failed\n")); |
|---|
| 9611 | | - goto fail; |
|---|
| 9612 | | - } |
|---|
| 9613 | | - err = nla_put_u32(skb, ANDR_TWT_ATTR_WAKE_INTERVAL, sdesc->wake_int); |
|---|
| 9614 | | - if (unlikely(err)) { |
|---|
| 9615 | | - WL_ERR(("nla_put_u32 WIFI_TWT_ATTR_WAKE_INTERVAL failed\n")); |
|---|
| 9616 | | - goto fail; |
|---|
| 9617 | | - } |
|---|
| 9618 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_TRIGGER_TYPE, |
|---|
| 9619 | | - !!(sdesc->flow_flags & WL_TWT_FLOW_FLAG_TRIGGER)); |
|---|
| 9620 | | - if (unlikely(err)) { |
|---|
| 9621 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_TRIGGER_TYPE failed\n")); |
|---|
| 9622 | | - goto fail; |
|---|
| 9623 | | - } |
|---|
| 9624 | | - |
|---|
| 9625 | | -fail: |
|---|
| 9626 | | - return err; |
|---|
| 9627 | | -} |
|---|
| 9628 | | - |
|---|
| 9629 | | -static int |
|---|
| 9630 | | -wl_cfgvendor_twt_update_teardown_response(struct sk_buff *skb, void *event_data) |
|---|
| 9631 | | -{ |
|---|
| 9632 | | - s32 err = BCME_OK; |
|---|
| 9633 | | - const wl_twt_teardown_cplt_t *td_cplt = (wl_twt_teardown_cplt_t *)event_data; |
|---|
| 9634 | | - const wl_twt_teardesc_t *teardesc = (const wl_twt_teardesc_t *)&td_cplt[1]; |
|---|
| 9635 | | - |
|---|
| 9636 | | - WL_DBG(("TWT_TEARDOWN: status %d, reason %d, configID %d, flow_id %d, negotiation_type %d," |
|---|
| 9637 | | - " bid %d, alltwt %d\n", (int)td_cplt->status, (int)td_cplt->reason_code, |
|---|
| 9638 | | - (int)td_cplt->configID, (int)teardesc->flow_id, (int)teardesc->negotiation_type, |
|---|
| 9639 | | - (int)teardesc->bid, (int)teardesc->alltwt)); |
|---|
| 9640 | | - |
|---|
| 9641 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_SUB_EVENT, ANDR_TWT_EVENT_TEARDOWN); |
|---|
| 9642 | | - if (unlikely(err)) { |
|---|
| 9643 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_SUB_EVENT failed\n")); |
|---|
| 9644 | | - goto fail; |
|---|
| 9645 | | - } |
|---|
| 9646 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_REASON_CODE, td_cplt->reason_code); |
|---|
| 9647 | | - if (unlikely(err)) { |
|---|
| 9648 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_REASON_CODE failed\n")); |
|---|
| 9649 | | - goto fail; |
|---|
| 9650 | | - } |
|---|
| 9651 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_STATUS, !!(td_cplt->status)); |
|---|
| 9652 | | - if (unlikely(err)) { |
|---|
| 9653 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_STATUS failed\n")); |
|---|
| 9654 | | - goto fail; |
|---|
| 9655 | | - } |
|---|
| 9656 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_CONFIG_ID, td_cplt->configID); |
|---|
| 9657 | | - if (unlikely(err)) { |
|---|
| 9658 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_CONFIG_ID failed\n")); |
|---|
| 9659 | | - goto fail; |
|---|
| 9660 | | - } |
|---|
| 9661 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_ALL_TWT, teardesc->alltwt); |
|---|
| 9662 | | - if (unlikely(err)) { |
|---|
| 9663 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_ALL_TWT failed\n")); |
|---|
| 9664 | | - goto fail; |
|---|
| 9665 | | - } |
|---|
| 9666 | | - |
|---|
| 9667 | | -fail: |
|---|
| 9668 | | - return err; |
|---|
| 9669 | | -} |
|---|
| 9670 | | - |
|---|
| 9671 | | -static int |
|---|
| 9672 | | -wl_cfgvendor_twt_update_infoframe_response(struct sk_buff *skb, void *event_data) |
|---|
| 9673 | | -{ |
|---|
| 9674 | | - s32 err = BCME_OK; |
|---|
| 9675 | | - const wl_twt_info_cplt_t *info_cplt = (wl_twt_info_cplt_t *)event_data; |
|---|
| 9676 | | - const wl_twt_infodesc_t *infodesc = (const wl_twt_infodesc_t *)&info_cplt[1]; |
|---|
| 9677 | | - |
|---|
| 9678 | | - WL_DBG(("TWT_INFOFRM: status %d, reason %d, configID %d, flow_flags 0x%x, flow_id %d," |
|---|
| 9679 | | - " next_twt_h %u, next_twt_l %u\n", (int)info_cplt->status, |
|---|
| 9680 | | - (int)info_cplt->reason_code, (int)info_cplt->configID, infodesc->flow_flags, |
|---|
| 9681 | | - (int)infodesc->flow_id, infodesc->next_twt_h, infodesc->next_twt_l)); |
|---|
| 9682 | | - |
|---|
| 9683 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_SUB_EVENT, ANDR_TWT_EVENT_INFO_FRM); |
|---|
| 9684 | | - if (unlikely(err)) { |
|---|
| 9685 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_SUB_EVENT failed\n")); |
|---|
| 9686 | | - goto fail; |
|---|
| 9687 | | - } |
|---|
| 9688 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_REASON_CODE, info_cplt->reason_code); |
|---|
| 9689 | | - if (unlikely(err)) { |
|---|
| 9690 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_REASON_CODE failed\n")); |
|---|
| 9691 | | - goto fail; |
|---|
| 9692 | | - } |
|---|
| 9693 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_STATUS, !!(info_cplt->status)); |
|---|
| 9694 | | - if (unlikely(err)) { |
|---|
| 9695 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_STATUS failed\n")); |
|---|
| 9696 | | - goto fail; |
|---|
| 9697 | | - } |
|---|
| 9698 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_CONFIG_ID, info_cplt->configID); |
|---|
| 9699 | | - if (unlikely(err)) { |
|---|
| 9700 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_CONFIG_ID failed\n")); |
|---|
| 9701 | | - goto fail; |
|---|
| 9702 | | - } |
|---|
| 9703 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_ALL_TWT, |
|---|
| 9704 | | - !!(infodesc->flow_flags & WL_TWT_INFO_FLAG_ALL_TWT)); |
|---|
| 9705 | | - if (unlikely(err)) { |
|---|
| 9706 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_TWT_RESUMED failed\n")); |
|---|
| 9707 | | - goto fail; |
|---|
| 9708 | | - } |
|---|
| 9709 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_TWT_RESUMED, |
|---|
| 9710 | | - !!(infodesc->flow_flags & WL_TWT_INFO_FLAG_RESUME)); |
|---|
| 9711 | | - if (unlikely(err)) { |
|---|
| 9712 | | - WL_ERR(("nla_put_u8 ANDR_TWT_ATTR_TWT_RESUMED failed\n")); |
|---|
| 9713 | | - goto fail; |
|---|
| 9714 | | - } |
|---|
| 9715 | | - |
|---|
| 9716 | | -fail: |
|---|
| 9717 | | - return err; |
|---|
| 9718 | | -} |
|---|
| 9719 | | - |
|---|
| 9720 | | -static int |
|---|
| 9721 | | -wl_cfgvendor_twt_update_notify_response(struct sk_buff *skb, void *event_data) |
|---|
| 9722 | | -{ |
|---|
| 9723 | | - s32 err = BCME_OK; |
|---|
| 9724 | | - const wl_twt_notify_t *notif_cplt = (wl_twt_notify_t *)event_data; |
|---|
| 9725 | | - |
|---|
| 9726 | | - WL_DBG(("TWT_NOTIFY: notification %d\n", (int)notif_cplt->notification)); |
|---|
| 9727 | | - |
|---|
| 9728 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_SUB_EVENT, ANDR_TWT_EVENT_NOTIFY); |
|---|
| 9729 | | - if (unlikely(err)) { |
|---|
| 9730 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_SUB_EVENT failed\n")); |
|---|
| 9731 | | - goto fail; |
|---|
| 9732 | | - } |
|---|
| 9733 | | - |
|---|
| 9734 | | - err = nla_put_u8(skb, ANDR_TWT_ATTR_TWT_NOTIFICATION, notif_cplt->notification); |
|---|
| 9735 | | - if (unlikely(err)) { |
|---|
| 9736 | | - WL_ERR(("nla_put_u8 WIFI_TWT_ATTR_NOTIFICATION failed\n")); |
|---|
| 9737 | | - goto fail; |
|---|
| 9738 | | - } |
|---|
| 9739 | | - |
|---|
| 9740 | | -fail: |
|---|
| 9741 | | - return err; |
|---|
| 9742 | | -} |
|---|
| 9743 | | - |
|---|
| 9744 | | -s32 |
|---|
| 9745 | | -wl_cfgvendor_notify_twt_event(struct bcm_cfg80211 *cfg, |
|---|
| 9746 | | - bcm_struct_cfgdev *cfgdev, const wl_event_msg_t *e, void *data) |
|---|
| 9747 | | -{ |
|---|
| 9748 | | - struct sk_buff *skb = NULL; |
|---|
| 9749 | | - gfp_t kflags; |
|---|
| 9750 | | - struct wiphy *wiphy = bcmcfg_to_wiphy(cfg); |
|---|
| 9751 | | - int err = BCME_OK; |
|---|
| 9752 | | - struct net_device *ndev = bcmcfg_to_prmry_ndev(cfg); |
|---|
| 9753 | | - const wl_twt_event_t *twt_event = (wl_twt_event_t *)data; |
|---|
| 9754 | | - |
|---|
| 9755 | | - kflags = in_atomic() ? GFP_ATOMIC : GFP_KERNEL; |
|---|
| 9756 | | - skb = CFG80211_VENDOR_EVENT_ALLOC(wiphy, ndev_to_wdev(ndev), |
|---|
| 9757 | | - BRCM_TWT_HAL_VENDOR_EVENT_BUF_LEN, BRCM_VENDOR_EVENT_TWT, kflags); |
|---|
| 9758 | | - if (!skb) { |
|---|
| 9759 | | - WL_ERR(("skb alloc failed")); |
|---|
| 9760 | | - err = BCME_NOMEM; |
|---|
| 9761 | | - goto fail; |
|---|
| 9762 | | - } |
|---|
| 9763 | | - |
|---|
| 9764 | | - switch (twt_event->event_type) { |
|---|
| 9765 | | - case WL_TWT_EVENT_SETUP: |
|---|
| 9766 | | - err = wl_cfgvendor_twt_update_setup_response(skb, |
|---|
| 9767 | | - (void*)twt_event->event_info); |
|---|
| 9768 | | - break; |
|---|
| 9769 | | - case WL_TWT_EVENT_TEARDOWN: |
|---|
| 9770 | | - err = wl_cfgvendor_twt_update_teardown_response(skb, |
|---|
| 9771 | | - (void*)twt_event->event_info); |
|---|
| 9772 | | - break; |
|---|
| 9773 | | - case WL_TWT_EVENT_INFOFRM: |
|---|
| 9774 | | - err = wl_cfgvendor_twt_update_infoframe_response(skb, |
|---|
| 9775 | | - (void*)twt_event->event_info); |
|---|
| 9776 | | - break; |
|---|
| 9777 | | - case WL_TWT_EVENT_NOTIFY: |
|---|
| 9778 | | - err = wl_cfgvendor_twt_update_notify_response(skb, |
|---|
| 9779 | | - (void*)twt_event->event_info); |
|---|
| 9780 | | - break; |
|---|
| 9781 | | - default: |
|---|
| 9782 | | - WL_ERR(("Invalid TWT sub event type %d", twt_event->event_type)); |
|---|
| 9783 | | - err = BCME_UNSUPPORTED; |
|---|
| 9784 | | - break; |
|---|
| 9785 | | - } |
|---|
| 9786 | | - |
|---|
| 9787 | | - if (err) { |
|---|
| 9788 | | - goto fail; |
|---|
| 9789 | | - } |
|---|
| 9790 | | - |
|---|
| 9791 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) |
|---|
| 9792 | | - cfg80211_vendor_event(skb, kflags); |
|---|
| 9793 | | -#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0) */ |
|---|
| 9794 | | - WL_ERR(("Successfully sent TWT vendor event type %d\n", twt_event->event_type)); |
|---|
| 9795 | | - return BCME_OK; |
|---|
| 9796 | | - |
|---|
| 9797 | | -fail: |
|---|
| 9798 | | - /* Free skb for failure cases */ |
|---|
| 9799 | | - if (skb) { |
|---|
| 9800 | | - kfree_skb(skb); |
|---|
| 9801 | | - } |
|---|
| 9802 | | - |
|---|
| 9803 | | - return err; |
|---|
| 9804 | | -} |
|---|
| 9805 | | -#endif /* !WL_TWT && WL_TWT_HAL_IF */ |
|---|
| 9806 | | - |
|---|
| 9807 | 9045 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 9808 | 9046 | const struct nla_policy andr_wifi_attr_policy[ANDR_WIFI_ATTRIBUTE_MAX] = { |
|---|
| 9809 | 9047 | [ANDR_WIFI_ATTRIBUTE_NUM_FEATURE_SET] = { .type = NLA_U32 }, |
|---|
| .. | .. |
|---|
| 10102 | 9340 | [DEBUG_ATTRIBUTE_PKT_FATE_DATA] = { .type = NLA_U64 }, |
|---|
| 10103 | 9341 | [DEBUG_ATTRIBUTE_HANG_REASON] = { .type = NLA_BINARY }, |
|---|
| 10104 | 9342 | }; |
|---|
| 10105 | | - |
|---|
| 10106 | | -#if !defined(WL_TWT) && defined(WL_TWT_HAL_IF) |
|---|
| 10107 | | -const struct nla_policy andr_twt_attr_policy[ANDR_TWT_ATTR_MAX] = { |
|---|
| 10108 | | - [ANDR_TWT_ATTR_NONE] = { .strict_start_type = 0 }, |
|---|
| 10109 | | - [ANDR_TWT_ATTR_CONFIG_ID] = { .type = NLA_U8 }, |
|---|
| 10110 | | - [ANDR_TWT_ATTR_NEGOTIATION_TYPE] = { .type = NLA_U8 }, |
|---|
| 10111 | | - [ANDR_TWT_ATTR_TRIGGER_TYPE] = { .type = NLA_U8 }, |
|---|
| 10112 | | - [ANDR_TWT_ATTR_WAKE_DURATION] = { .type = NLA_U32 }, |
|---|
| 10113 | | - [ANDR_TWT_ATTR_WAKE_INTERVAL] = { .type = NLA_U32 }, |
|---|
| 10114 | | - [ANDR_TWT_ATTR_WAKE_INTERVAL_MIN] = { .type = NLA_U32 }, |
|---|
| 10115 | | - [ANDR_TWT_ATTR_WAKE_INTERVAL_MAX] = { .type = NLA_U32 }, |
|---|
| 10116 | | - [ANDR_TWT_ATTR_WAKE_DURATION_MIN] = { .type = NLA_U32 }, |
|---|
| 10117 | | - [ANDR_TWT_ATTR_WAKE_DURATION_MAX] = { .type = NLA_U32 }, |
|---|
| 10118 | | - [ANDR_TWT_ATTR_AVG_PKT_SIZE] = { .type = NLA_U32 }, |
|---|
| 10119 | | - [ANDR_TWT_ATTR_AVG_PKT_NUM] = { .type = NLA_U32 }, |
|---|
| 10120 | | - [ANDR_TWT_ATTR_WAKETIME_OFFSET] = { .type = NLA_U32 }, |
|---|
| 10121 | | - [ANDR_TWT_ATTR_ALL_TWT] = { .type = NLA_U8 }, |
|---|
| 10122 | | - [ANDR_TWT_ATTR_RESUME_TIME] = { .type = NLA_U32 }, |
|---|
| 10123 | | - [ANDR_TWT_ATTR_AVG_EOSP_DUR] = { .type = NLA_U32 }, |
|---|
| 10124 | | - [ANDR_TWT_ATTR_EOSP_CNT] = { .type = NLA_U32 }, |
|---|
| 10125 | | - [ANDR_TWT_ATTR_NUM_SP] = { .type = NLA_U32 }, |
|---|
| 10126 | | - [ANDR_TWT_ATTR_DEVICE_CAP] = { .type = NLA_U32 }, |
|---|
| 10127 | | - [ANDR_TWT_ATTR_PEER_CAP] = { .type = NLA_U32 }, |
|---|
| 10128 | | - [ANDR_TWT_ATTR_STATUS] = { .type = NLA_U8 }, |
|---|
| 10129 | | - [ANDR_TWT_ATTR_REASON_CODE] = { .type = NLA_U8 }, |
|---|
| 10130 | | - [ANDR_TWT_ATTR_TWT_RESUMED] = { .type = NLA_U8 }, |
|---|
| 10131 | | - [ANDR_TWT_ATTR_TWT_NOTIFICATION] = { .type = NLA_U8 }, |
|---|
| 10132 | | - [ANDR_TWT_ATTR_SUB_EVENT] = { .type = NLA_U8 }, |
|---|
| 10133 | | - [ANDR_TWT_ATTR_NUM_PEER_STATS] = { .type = NLA_U8 }, |
|---|
| 10134 | | - [ANDR_TWT_ATTR_AVG_PKT_NUM_TX] = { .type = NLA_U32 }, |
|---|
| 10135 | | - [ANDR_TWT_ATTR_AVG_PKT_SIZE_TX] = { .type = NLA_U32 }, |
|---|
| 10136 | | - [ANDR_TWT_ATTR_AVG_PKT_NUM_RX] = { .type = NLA_U32 }, |
|---|
| 10137 | | - [ANDR_TWT_ATTR_AVG_PKT_SIZE_RX] = { .type = NLA_U32 }, |
|---|
| 10138 | | -}; |
|---|
| 10139 | | -#endif /* !WL_TWT && WL_TWT_HAL_IF */ |
|---|
| 10140 | | - |
|---|
| 10141 | 9343 | #endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 10142 | 9344 | |
|---|
| 10143 | 9345 | static struct wiphy_vendor_command wl_vendor_cmds [] = { |
|---|
| .. | .. |
|---|
| 11064 | 10266 | #endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11065 | 10267 | } |
|---|
| 11066 | 10268 | #endif /* WL_SAR_TX_POWER */ |
|---|
| 11067 | | -#if !defined(WL_TWT) && defined(WL_TWT_HAL_IF) |
|---|
| 11068 | | - { |
|---|
| 11069 | | - { |
|---|
| 11070 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11071 | | - .subcmd = ANDR_TWT_SUBCMD_SETUP |
|---|
| 11072 | | - }, |
|---|
| 11073 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11074 | | - .doit = wl_cfgvendor_twt_setup, |
|---|
| 11075 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11076 | | - .policy = andr_twt_attr_policy, |
|---|
| 11077 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11078 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11079 | | - }, |
|---|
| 11080 | | - { |
|---|
| 11081 | | - { |
|---|
| 11082 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11083 | | - .subcmd = ANDR_TWT_SUBCMD_TEARDOWN |
|---|
| 11084 | | - }, |
|---|
| 11085 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11086 | | - .doit = wl_cfgvendor_twt_teardown, |
|---|
| 11087 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11088 | | - .policy = andr_twt_attr_policy, |
|---|
| 11089 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11090 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11091 | | - }, |
|---|
| 11092 | | - { |
|---|
| 11093 | | - { |
|---|
| 11094 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11095 | | - .subcmd = ANDR_TWT_SUBCMD_INFO_FRAME |
|---|
| 11096 | | - }, |
|---|
| 11097 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11098 | | - .doit = wl_cfgvendor_twt_info_frame, |
|---|
| 11099 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11100 | | - .policy = andr_twt_attr_policy, |
|---|
| 11101 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11102 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11103 | | - }, |
|---|
| 11104 | | - { |
|---|
| 11105 | | - { |
|---|
| 11106 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11107 | | - .subcmd = ANDR_TWT_SUBCMD_GET_CAP |
|---|
| 11108 | | - }, |
|---|
| 11109 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11110 | | - .doit = wl_cfgvendor_twt_cap, |
|---|
| 11111 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11112 | | - .policy = andr_twt_attr_policy, |
|---|
| 11113 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11114 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11115 | | - }, |
|---|
| 11116 | | - { |
|---|
| 11117 | | - { |
|---|
| 11118 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11119 | | - .subcmd = ANDR_TWT_SUBCMD_GET_STATS |
|---|
| 11120 | | - }, |
|---|
| 11121 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11122 | | - .doit = wl_cfgvendor_twt_get_stats, |
|---|
| 11123 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11124 | | - .policy = andr_twt_attr_policy, |
|---|
| 11125 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11126 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11127 | | - }, |
|---|
| 11128 | | - { |
|---|
| 11129 | | - { |
|---|
| 11130 | | - .vendor_id = OUI_GOOGLE, |
|---|
| 11131 | | - .subcmd = ANDR_TWT_SUBCMD_CLR_STATS |
|---|
| 11132 | | - }, |
|---|
| 11133 | | - .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV, |
|---|
| 11134 | | - .doit = wl_cfgvendor_twt_clear_stats, |
|---|
| 11135 | | -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|
| 11136 | | - .policy = andr_twt_attr_policy, |
|---|
| 11137 | | - .maxattr = ANDR_TWT_ATTR_MAX |
|---|
| 11138 | | -#endif /* LINUX_VERSION >= 5.3 */ |
|---|
| 11139 | | - }, |
|---|
| 11140 | | -#endif /* !WL_TWT && WL_TWT_HAL_IF */ |
|---|
| 11141 | 10269 | |
|---|
| 11142 | 10270 | }; |
|---|
| 11143 | 10271 | |
|---|
| .. | .. |
|---|
| 11183 | 10311 | { OUI_BRCM, BRCM_VENDOR_EVENT_CU}, |
|---|
| 11184 | 10312 | { OUI_BRCM, BRCM_VENDOR_EVENT_WIPS}, |
|---|
| 11185 | 10313 | { OUI_GOOGLE, NAN_ASYNC_RESPONSE_DISABLED}, |
|---|
| 11186 | | - { OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO}, |
|---|
| 11187 | | - {OUI_BRCM, BRCM_VENDOR_EVENT_TWT} |
|---|
| 10314 | + { OUI_BRCM, BRCM_VENDOR_EVENT_RCC_INFO} |
|---|
| 11188 | 10315 | }; |
|---|
| 11189 | 10316 | |
|---|
| 11190 | 10317 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)) |
|---|