2 * Copyright (c) 2014 Redpine Signals Inc.
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * rsi_send_data_pkt() - This function sends the recieved data packet from
22 * @common: Pointer to the driver private structure.
23 * @skb: Pointer to the socket buffer structure.
25 * Return: status: 0 on success, -1 on failure.
27 int rsi_send_data_pkt(struct rsi_common
*common
, struct sk_buff
*skb
)
29 struct rsi_hw
*adapter
= common
->priv
;
30 struct ieee80211_hdr
*tmp_hdr
;
31 struct ieee80211_tx_info
*info
;
32 struct skb_info
*tx_params
;
33 struct ieee80211_bss_conf
*bss
;
35 u8 ieee80211_size
= MIN_802_11_HDR_LEN
;
40 info
= IEEE80211_SKB_CB(skb
);
41 bss
= &info
->control
.vif
->bss_conf
;
42 tx_params
= (struct skb_info
*)info
->driver_data
;
49 tmp_hdr
= (struct ieee80211_hdr
*)&skb
->data
[0];
50 seq_num
= (le16_to_cpu(tmp_hdr
->seq_ctrl
) >> 4);
52 extnd_size
= ((uintptr_t)skb
->data
& 0x3);
54 if ((FRAME_DESC_SZ
+ extnd_size
) > skb_headroom(skb
)) {
55 rsi_dbg(ERR_ZONE
, "%s: Unable to send pkt\n", __func__
);
60 skb_push(skb
, (FRAME_DESC_SZ
+ extnd_size
));
61 frame_desc
= (__le16
*)&skb
->data
[0];
62 memset((u8
*)frame_desc
, 0, FRAME_DESC_SZ
);
64 if (ieee80211_is_data_qos(tmp_hdr
->frame_control
)) {
66 frame_desc
[6] |= cpu_to_le16(BIT(12));
69 if ((!(info
->flags
& IEEE80211_TX_INTFL_DONT_ENCRYPT
)) &&
70 (common
->secinfo
.security_enable
)) {
71 if (rsi_is_cipher_wep(common
))
75 frame_desc
[6] |= cpu_to_le16(BIT(15));
78 frame_desc
[0] = cpu_to_le16((skb
->len
- FRAME_DESC_SZ
) |
79 (RSI_WIFI_DATA_Q
<< 12));
80 frame_desc
[2] = cpu_to_le16((extnd_size
) | (ieee80211_size
) << 8);
82 if (common
->min_rate
!= 0xffff) {
84 frame_desc
[3] = cpu_to_le16(RATE_INFO_ENABLE
);
85 frame_desc
[4] = cpu_to_le16(common
->min_rate
);
87 if (conf_is_ht40(&common
->priv
->hw
->conf
))
88 frame_desc
[5] = cpu_to_le16(FULL40M_ENABLE
);
90 if (common
->vif_info
[0].sgi
) {
91 if (common
->min_rate
& 0x100) /* Only MCS rates */
93 cpu_to_le16(ENABLE_SHORTGI_RATE
);
98 frame_desc
[6] |= cpu_to_le16(seq_num
& 0xfff);
99 frame_desc
[7] = cpu_to_le16(((tx_params
->tid
& 0xf) << 4) |
100 (skb
->priority
& 0xf) |
101 (tx_params
->sta_id
<< 8));
103 status
= adapter
->host_intf_write_pkt(common
->priv
,
107 rsi_dbg(ERR_ZONE
, "%s: Failed to write pkt\n",
111 ++common
->tx_stats
.total_tx_pkt_freed
[skb
->priority
];
112 rsi_indicate_tx_status(common
->priv
, skb
, status
);
117 * rsi_send_mgmt_pkt() - This functions sends the received management packet
118 * from driver to device.
119 * @common: Pointer to the driver private structure.
120 * @skb: Pointer to the socket buffer structure.
122 * Return: status: 0 on success, -1 on failure.
124 int rsi_send_mgmt_pkt(struct rsi_common
*common
,
127 struct rsi_hw
*adapter
= common
->priv
;
128 struct ieee80211_hdr
*wh
;
129 struct ieee80211_tx_info
*info
;
130 struct ieee80211_bss_conf
*bss
;
131 struct ieee80211_hw
*hw
= adapter
->hw
;
132 struct ieee80211_conf
*conf
= &hw
->conf
;
133 struct skb_info
*tx_params
;
139 info
= IEEE80211_SKB_CB(skb
);
140 tx_params
= (struct skb_info
*)info
->driver_data
;
141 extnd_size
= ((uintptr_t)skb
->data
& 0x3);
143 if (tx_params
->flags
& INTERNAL_MGMT_PKT
) {
144 if ((extnd_size
) > skb_headroom(skb
)) {
145 rsi_dbg(ERR_ZONE
, "%s: Unable to send pkt\n", __func__
);
149 skb_push(skb
, extnd_size
);
150 skb
->data
[extnd_size
+ 4] = extnd_size
;
151 status
= adapter
->host_intf_write_pkt(common
->priv
,
156 "%s: Failed to write the packet\n", __func__
);
162 bss
= &info
->control
.vif
->bss_conf
;
163 wh
= (struct ieee80211_hdr
*)&skb
->data
[0];
165 if (FRAME_DESC_SZ
> skb_headroom(skb
))
168 skb_push(skb
, FRAME_DESC_SZ
);
169 memset(skb
->data
, 0, FRAME_DESC_SZ
);
170 msg
= (__le16
*)skb
->data
;
172 if (skb
->len
> MAX_MGMT_PKT_SIZE
) {
173 rsi_dbg(INFO_ZONE
, "%s: Dropping mgmt pkt > 512\n", __func__
);
177 msg
[0] = cpu_to_le16((skb
->len
- FRAME_DESC_SZ
) |
178 (RSI_WIFI_MGMT_Q
<< 12));
179 msg
[1] = cpu_to_le16(TX_DOT11_MGMT
);
180 msg
[2] = cpu_to_le16(MIN_802_11_HDR_LEN
<< 8);
181 msg
[3] = cpu_to_le16(RATE_INFO_ENABLE
);
182 msg
[6] = cpu_to_le16(le16_to_cpu(wh
->seq_ctrl
) >> 4);
184 if (wh
->addr1
[0] & BIT(0))
185 msg
[3] |= cpu_to_le16(RSI_BROADCAST_PKT
);
187 if (common
->band
== NL80211_BAND_2GHZ
)
188 msg
[4] = cpu_to_le16(RSI_11B_MODE
);
190 msg
[4] = cpu_to_le16((RSI_RATE_6
& 0x0f) | RSI_11G_MODE
);
192 if (conf_is_ht40(conf
)) {
193 msg
[4] = cpu_to_le16(0xB | RSI_11G_MODE
);
194 msg
[5] = cpu_to_le16(0x6);
197 /* Indicate to firmware to give cfm */
198 if ((skb
->data
[16] == IEEE80211_STYPE_PROBE_REQ
) && (!bss
->assoc
)) {
199 msg
[1] |= cpu_to_le16(BIT(10));
200 msg
[7] = cpu_to_le16(PROBEREQ_CONFIRM
);
201 common
->mgmt_q_block
= true;
204 msg
[7] |= cpu_to_le16(vap_id
<< 8);
206 status
= adapter
->host_intf_write_pkt(common
->priv
,
210 rsi_dbg(ERR_ZONE
, "%s: Failed to write the packet\n", __func__
);
213 rsi_indicate_tx_status(common
->priv
, skb
, status
);