data_rx.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Datapath implementation.
  4. *
  5. * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
  6. * Copyright (c) 2010, ST-Ericsson
  7. */
  8. #include <linux/etherdevice.h>
  9. #include <net/mac80211.h>
  10. #include "data_rx.h"
  11. #include "wfx.h"
  12. #include "bh.h"
  13. #include "sta.h"
  14. static void wfx_rx_handle_ba(struct wfx_vif *wvif, struct ieee80211_mgmt *mgmt)
  15. {
  16. int params, tid;
  17. if (wfx_api_older_than(wvif->wdev, 3, 6))
  18. return;
  19. switch (mgmt->u.action.u.addba_req.action_code) {
  20. case WLAN_ACTION_ADDBA_REQ:
  21. params = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
  22. tid = (params & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
  23. ieee80211_start_rx_ba_session_offl(wvif->vif, mgmt->sa, tid);
  24. break;
  25. case WLAN_ACTION_DELBA:
  26. params = le16_to_cpu(mgmt->u.action.u.delba.params);
  27. tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
  28. ieee80211_stop_rx_ba_session_offl(wvif->vif, mgmt->sa, tid);
  29. break;
  30. }
  31. }
  32. void wfx_rx_cb(struct wfx_vif *wvif,
  33. const struct hif_ind_rx *arg, struct sk_buff *skb)
  34. {
  35. struct ieee80211_rx_status *hdr = IEEE80211_SKB_RXCB(skb);
  36. struct ieee80211_hdr *frame = (struct ieee80211_hdr *)skb->data;
  37. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
  38. memset(hdr, 0, sizeof(*hdr));
  39. if (arg->status == HIF_STATUS_RX_FAIL_MIC)
  40. hdr->flag |= RX_FLAG_MMIC_ERROR | RX_FLAG_IV_STRIPPED;
  41. else if (arg->status)
  42. goto drop;
  43. if (skb->len < sizeof(struct ieee80211_pspoll)) {
  44. dev_warn(wvif->wdev->dev, "malformed SDU received\n");
  45. goto drop;
  46. }
  47. hdr->band = NL80211_BAND_2GHZ;
  48. hdr->freq = ieee80211_channel_to_frequency(arg->channel_number,
  49. hdr->band);
  50. if (arg->rxed_rate >= 14) {
  51. hdr->encoding = RX_ENC_HT;
  52. hdr->rate_idx = arg->rxed_rate - 14;
  53. } else if (arg->rxed_rate >= 4) {
  54. hdr->rate_idx = arg->rxed_rate - 2;
  55. } else {
  56. hdr->rate_idx = arg->rxed_rate;
  57. }
  58. if (!arg->rcpi_rssi) {
  59. hdr->flag |= RX_FLAG_NO_SIGNAL_VAL;
  60. dev_info(wvif->wdev->dev, "received frame without RSSI data\n");
  61. }
  62. hdr->signal = arg->rcpi_rssi / 2 - 110;
  63. hdr->antenna = 0;
  64. if (arg->encryp)
  65. hdr->flag |= RX_FLAG_DECRYPTED;
  66. // Block ack negotiation is offloaded by the firmware. However,
  67. // re-ordering must be done by the mac80211.
  68. if (ieee80211_is_action(frame->frame_control) &&
  69. mgmt->u.action.category == WLAN_CATEGORY_BACK &&
  70. skb->len > IEEE80211_MIN_ACTION_SIZE) {
  71. wfx_rx_handle_ba(wvif, mgmt);
  72. goto drop;
  73. }
  74. ieee80211_rx_irqsafe(wvif->wdev->hw, skb);
  75. return;
  76. drop:
  77. dev_kfree_skb(skb);
  78. }