diff options
| author | David S. Miller <davem@davemloft.net> | 2016-05-10 01:02:51 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2016-05-10 01:02:51 -0400 |
| commit | 5e769ada93b2111010d3ca96213fc0b37c95afc8 (patch) | |
| tree | d9e7f009a0e061d6bb3bc26724667573a3d13867 | |
| parent | adc0a8bfdc52cbbfe76730b166a17cb0d5cbc0f4 (diff) | |
| parent | cbbba30f1ac95a04aae9c61a55aebe5e6fdf29f0 (diff) | |
Merge tag 'wireless-drivers-for-davem-2016-05-09' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers
Kalle Valo says:
====================
wireless-drivers fixes for 4.6
iwlwifi
* fix P2P rates (and possibly other issues)
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | drivers/net/wireless/intel/iwlwifi/mvm/tx.c | 83 |
1 files changed, 48 insertions, 35 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c index 75870e68a7c3..34731e29c589 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c | |||
| @@ -105,6 +105,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 105 | struct iwl_tx_cmd *tx_cmd, | 105 | struct iwl_tx_cmd *tx_cmd, |
| 106 | struct ieee80211_tx_info *info, u8 sta_id) | 106 | struct ieee80211_tx_info *info, u8 sta_id) |
| 107 | { | 107 | { |
| 108 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); | ||
| 108 | struct ieee80211_hdr *hdr = (void *)skb->data; | 109 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 109 | __le16 fc = hdr->frame_control; | 110 | __le16 fc = hdr->frame_control; |
| 110 | u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); | 111 | u32 tx_flags = le32_to_cpu(tx_cmd->tx_flags); |
| @@ -185,7 +186,7 @@ void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 185 | tx_cmd->tx_flags = cpu_to_le32(tx_flags); | 186 | tx_cmd->tx_flags = cpu_to_le32(tx_flags); |
| 186 | /* Total # bytes to be transmitted */ | 187 | /* Total # bytes to be transmitted */ |
| 187 | tx_cmd->len = cpu_to_le16((u16)skb->len + | 188 | tx_cmd->len = cpu_to_le16((u16)skb->len + |
| 188 | (uintptr_t)info->driver_data[0]); | 189 | (uintptr_t)skb_info->driver_data[0]); |
| 189 | tx_cmd->next_frame_len = 0; | 190 | tx_cmd->next_frame_len = 0; |
| 190 | tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); | 191 | tx_cmd->life_time = cpu_to_le32(TX_CMD_LIFE_TIME_INFINITE); |
| 191 | tx_cmd->sta_id = sta_id; | 192 | tx_cmd->sta_id = sta_id; |
| @@ -327,10 +328,11 @@ static void iwl_mvm_set_tx_cmd_crypto(struct iwl_mvm *mvm, | |||
| 327 | */ | 328 | */ |
| 328 | static struct iwl_device_cmd * | 329 | static struct iwl_device_cmd * |
| 329 | iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, | 330 | iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, |
| 330 | int hdrlen, struct ieee80211_sta *sta, u8 sta_id) | 331 | struct ieee80211_tx_info *info, int hdrlen, |
| 332 | struct ieee80211_sta *sta, u8 sta_id) | ||
| 331 | { | 333 | { |
| 332 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 334 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 333 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 335 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); |
| 334 | struct iwl_device_cmd *dev_cmd; | 336 | struct iwl_device_cmd *dev_cmd; |
| 335 | struct iwl_tx_cmd *tx_cmd; | 337 | struct iwl_tx_cmd *tx_cmd; |
| 336 | 338 | ||
| @@ -350,10 +352,10 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 350 | 352 | ||
| 351 | iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control); | 353 | iwl_mvm_set_tx_cmd_rate(mvm, tx_cmd, info, sta, hdr->frame_control); |
| 352 | 354 | ||
| 353 | memset(&info->status, 0, sizeof(info->status)); | 355 | memset(&skb_info->status, 0, sizeof(skb_info->status)); |
| 354 | memset(info->driver_data, 0, sizeof(info->driver_data)); | 356 | memset(skb_info->driver_data, 0, sizeof(skb_info->driver_data)); |
| 355 | 357 | ||
| 356 | info->driver_data[1] = dev_cmd; | 358 | skb_info->driver_data[1] = dev_cmd; |
| 357 | 359 | ||
| 358 | return dev_cmd; | 360 | return dev_cmd; |
| 359 | } | 361 | } |
| @@ -361,22 +363,25 @@ iwl_mvm_set_tx_params(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 361 | int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | 363 | int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) |
| 362 | { | 364 | { |
| 363 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 365 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
| 364 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 366 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); |
| 367 | struct ieee80211_tx_info info; | ||
| 365 | struct iwl_device_cmd *dev_cmd; | 368 | struct iwl_device_cmd *dev_cmd; |
| 366 | struct iwl_tx_cmd *tx_cmd; | 369 | struct iwl_tx_cmd *tx_cmd; |
| 367 | u8 sta_id; | 370 | u8 sta_id; |
| 368 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); | 371 | int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
| 369 | 372 | ||
| 370 | if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_AMPDU)) | 373 | memcpy(&info, skb->cb, sizeof(info)); |
| 374 | |||
| 375 | if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_AMPDU)) | ||
| 371 | return -1; | 376 | return -1; |
| 372 | 377 | ||
| 373 | if (WARN_ON_ONCE(info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && | 378 | if (WARN_ON_ONCE(info.flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM && |
| 374 | (!info->control.vif || | 379 | (!info.control.vif || |
| 375 | info->hw_queue != info->control.vif->cab_queue))) | 380 | info.hw_queue != info.control.vif->cab_queue))) |
| 376 | return -1; | 381 | return -1; |
| 377 | 382 | ||
| 378 | /* This holds the amsdu headers length */ | 383 | /* This holds the amsdu headers length */ |
| 379 | info->driver_data[0] = (void *)(uintptr_t)0; | 384 | skb_info->driver_data[0] = (void *)(uintptr_t)0; |
| 380 | 385 | ||
| 381 | /* | 386 | /* |
| 382 | * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used | 387 | * IWL_MVM_OFFCHANNEL_QUEUE is used for ROC packets that can be used |
| @@ -385,7 +390,7 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
| 385 | * and hence needs to be sent on the aux queue | 390 | * and hence needs to be sent on the aux queue |
| 386 | */ | 391 | */ |
| 387 | if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && | 392 | if (IEEE80211_SKB_CB(skb)->hw_queue == IWL_MVM_OFFCHANNEL_QUEUE && |
| 388 | info->control.vif->type == NL80211_IFTYPE_STATION) | 393 | info.control.vif->type == NL80211_IFTYPE_STATION) |
| 389 | IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue; | 394 | IEEE80211_SKB_CB(skb)->hw_queue = mvm->aux_queue; |
| 390 | 395 | ||
| 391 | /* | 396 | /* |
| @@ -398,14 +403,14 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
| 398 | * AUX station. | 403 | * AUX station. |
| 399 | */ | 404 | */ |
| 400 | sta_id = mvm->aux_sta.sta_id; | 405 | sta_id = mvm->aux_sta.sta_id; |
| 401 | if (info->control.vif) { | 406 | if (info.control.vif) { |
| 402 | struct iwl_mvm_vif *mvmvif = | 407 | struct iwl_mvm_vif *mvmvif = |
| 403 | iwl_mvm_vif_from_mac80211(info->control.vif); | 408 | iwl_mvm_vif_from_mac80211(info.control.vif); |
| 404 | 409 | ||
| 405 | if (info->control.vif->type == NL80211_IFTYPE_P2P_DEVICE || | 410 | if (info.control.vif->type == NL80211_IFTYPE_P2P_DEVICE || |
| 406 | info->control.vif->type == NL80211_IFTYPE_AP) | 411 | info.control.vif->type == NL80211_IFTYPE_AP) |
| 407 | sta_id = mvmvif->bcast_sta.sta_id; | 412 | sta_id = mvmvif->bcast_sta.sta_id; |
| 408 | else if (info->control.vif->type == NL80211_IFTYPE_STATION && | 413 | else if (info.control.vif->type == NL80211_IFTYPE_STATION && |
| 409 | is_multicast_ether_addr(hdr->addr1)) { | 414 | is_multicast_ether_addr(hdr->addr1)) { |
| 410 | u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id); | 415 | u8 ap_sta_id = ACCESS_ONCE(mvmvif->ap_sta_id); |
| 411 | 416 | ||
| @@ -414,19 +419,18 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
| 414 | } | 419 | } |
| 415 | } | 420 | } |
| 416 | 421 | ||
| 417 | IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info->hw_queue); | 422 | IWL_DEBUG_TX(mvm, "station Id %d, queue=%d\n", sta_id, info.hw_queue); |
| 418 | 423 | ||
| 419 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, hdrlen, NULL, sta_id); | 424 | dev_cmd = iwl_mvm_set_tx_params(mvm, skb, &info, hdrlen, NULL, sta_id); |
| 420 | if (!dev_cmd) | 425 | if (!dev_cmd) |
| 421 | return -1; | 426 | return -1; |
| 422 | 427 | ||
| 423 | /* From now on, we cannot access info->control */ | ||
| 424 | tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; | 428 | tx_cmd = (struct iwl_tx_cmd *)dev_cmd->payload; |
| 425 | 429 | ||
| 426 | /* Copy MAC header from skb into command buffer */ | 430 | /* Copy MAC header from skb into command buffer */ |
| 427 | memcpy(tx_cmd->hdr, hdr, hdrlen); | 431 | memcpy(tx_cmd->hdr, hdr, hdrlen); |
| 428 | 432 | ||
| 429 | if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info->hw_queue)) { | 433 | if (iwl_trans_tx(mvm->trans, skb, dev_cmd, info.hw_queue)) { |
| 430 | iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); | 434 | iwl_trans_free_tx_cmd(mvm->trans, dev_cmd); |
| 431 | return -1; | 435 | return -1; |
| 432 | } | 436 | } |
| @@ -445,11 +449,11 @@ int iwl_mvm_tx_skb_non_sta(struct iwl_mvm *mvm, struct sk_buff *skb) | |||
| 445 | 449 | ||
| 446 | #ifdef CONFIG_INET | 450 | #ifdef CONFIG_INET |
| 447 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | 451 | static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, |
| 452 | struct ieee80211_tx_info *info, | ||
| 448 | struct ieee80211_sta *sta, | 453 | struct ieee80211_sta *sta, |
| 449 | struct sk_buff_head *mpdus_skb) | 454 | struct sk_buff_head *mpdus_skb) |
| 450 | { | 455 | { |
| 451 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); | 456 | struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); |
| 452 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
| 453 | struct ieee80211_hdr *hdr = (void *)skb->data; | 457 | struct ieee80211_hdr *hdr = (void *)skb->data; |
| 454 | unsigned int mss = skb_shinfo(skb)->gso_size; | 458 | unsigned int mss = skb_shinfo(skb)->gso_size; |
| 455 | struct sk_buff *tmp, *next; | 459 | struct sk_buff *tmp, *next; |
| @@ -544,6 +548,8 @@ static int iwl_mvm_tx_tso(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 544 | 548 | ||
| 545 | /* This skb fits in one single A-MSDU */ | 549 | /* This skb fits in one single A-MSDU */ |
| 546 | if (num_subframes * mss >= tcp_payload_len) { | 550 | if (num_subframes * mss >= tcp_payload_len) { |
| 551 | struct ieee80211_tx_info *skb_info = IEEE80211_SKB_CB(skb); | ||
| 552 | |||
| 547 | /* | ||
