net:wireless:Support eswin usb wifi ECR6600U
[platform/kernel/linux-starfive.git] / drivers / net / wireless / eswin / ecrnx_bfmer.c
1 /**
2  ******************************************************************************
3  *
4  * @file ecrnx_bfmer.c
5  *
6  * @brief VHT Beamformer function definitions
7  *
8  * Copyright (C) ESWIN 2015-2020
9  *
10  ******************************************************************************
11  */
12
13 /**
14  * INCLUDE FILES
15  ******************************************************************************
16  */
17
18 #include <linux/slab.h>
19 #include "ecrnx_bfmer.h"
20
21 /**
22  * FUNCTION DEFINITIONS
23  ******************************************************************************
24  */
25
26 int ecrnx_bfmer_report_add(struct ecrnx_hw *ecrnx_hw, struct ecrnx_sta *ecrnx_sta,
27                           unsigned int length)
28 {
29     gfp_t flags;
30     struct ecrnx_bfmer_report *bfm_report ;
31
32     if (in_softirq())
33         flags = GFP_ATOMIC;
34     else
35         flags = GFP_KERNEL;
36
37     /* Allocate a structure that will contain the beamforming report */
38     bfm_report = kmalloc(sizeof(*bfm_report) + length, flags);
39
40
41     /* Check report allocation */
42     if (!bfm_report) {
43         /* Do not use beamforming */
44         return -1;
45     }
46
47     /* Store report length */
48     bfm_report->length = length;
49
50     /*
51      * Need to provide a Virtual Address to the MAC so that it can
52      * upload the received Beamforming Report in driver memory
53      */
54     bfm_report->dma_addr = dma_map_single(ecrnx_hw->dev, &bfm_report->report[0],
55                                           length, DMA_FROM_DEVICE);
56
57     /* Check DMA mapping result */
58     if (dma_mapping_error(ecrnx_hw->dev, bfm_report->dma_addr)) {
59         /* Free allocated report */
60         kfree(bfm_report);
61         /* And leave */
62         return -1;
63     }
64
65     /* Store report structure */
66     ecrnx_sta->bfm_report = bfm_report;
67
68     return 0;
69 }
70
71 void ecrnx_bfmer_report_del(struct ecrnx_hw *ecrnx_hw, struct ecrnx_sta *ecrnx_sta)
72 {
73     /* Verify if a report has been allocated */
74     if (ecrnx_sta->bfm_report) {
75         struct ecrnx_bfmer_report *bfm_report = ecrnx_sta->bfm_report;
76
77         /* Unmap DMA region */
78         dma_unmap_single(ecrnx_hw->dev, bfm_report->dma_addr,
79                          bfm_report->length, DMA_BIDIRECTIONAL);
80
81         /* Free allocated report structure and clean the pointer */
82         kfree(bfm_report);
83         ecrnx_sta->bfm_report = NULL;
84     }
85 }
86
87 #ifdef CONFIG_ECRNX_FULLMAC
88 u8 ecrnx_bfmer_get_rx_nss(const struct ieee80211_vht_cap *vht_capa)
89 {
90     int i;
91     u8 rx_nss = 0;
92     u16 rx_mcs_map = le16_to_cpu(vht_capa->supp_mcs.rx_mcs_map);
93
94     for (i = 7; i >= 0; i--) {
95         u8 mcs = (rx_mcs_map >> (2 * i)) & 3;
96
97         if (mcs != IEEE80211_VHT_MCS_NOT_SUPPORTED) {
98             rx_nss = i + 1;
99             break;
100         }
101     }
102
103     return rx_nss;
104 }
105 #endif /* CONFIG_ECRNX_FULLMAC */