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
= NULL
;
31 struct ieee80211_tx_info
*info
;
32 struct skb_info
*tx_params
;
33 struct ieee80211_bss_conf
*bss
= NULL
;
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
;
47 tmp_hdr
= (struct ieee80211_hdr
*)&skb
->data
[0];
48 seq_num
= (le16_to_cpu(tmp_hdr
->seq_ctrl
) >> 4);
50 extnd_size
= ((uintptr_t)skb
->data
& 0x3);
52 if ((FRAME_DESC_SZ
+ extnd_size
) > skb_headroom(skb
)) {
53 rsi_dbg(ERR_ZONE
, "%s: Unable to send pkt\n", __func__
);
58 skb_push(skb
, (FRAME_DESC_SZ
+ extnd_size
));
59 frame_desc
= (__le16
*)&skb
->data
[0];
60 memset((u8
*)frame_desc
, 0, FRAME_DESC_SZ
);
62 if (ieee80211_is_data_qos(tmp_hdr
->frame_control
)) {
64 frame_desc
[6] |= cpu_to_le16(BIT(12));
67 if ((!(info
->flags
& IEEE80211_TX_INTFL_DONT_ENCRYPT
)) &&
68 (common
->secinfo
.security_enable
)) {
69 if (rsi_is_cipher_wep(common
))
73 frame_desc
[6] |= cpu_to_le16(BIT(15));
76 frame_desc
[0] = cpu_to_le16((skb
->len
- FRAME_DESC_SZ
) |
77 (RSI_WIFI_DATA_Q
<< 12));
78 frame_desc
[2] = cpu_to_le16((extnd_size
) | (ieee80211_size
) << 8);
80 if (common
->min_rate
!= 0xffff) {
82 frame_desc
[3] = cpu_to_le16(RATE_INFO_ENABLE
);
83 frame_desc
[4] = cpu_to_le16(common
->min_rate
);
85 if (conf_is_ht40(&common
->priv
->hw
->conf
))
86 frame_desc
[5] = cpu_to_le16(FULL40M_ENABLE
);
88 if (common
->vif_info
[0].sgi
) {
89 if (common
->min_rate
& 0x100) /* Only MCS rates */
91 cpu_to_le16(ENABLE_SHORTGI_RATE
);
96 frame_desc
[6] |= cpu_to_le16(seq_num
& 0xfff);
97 frame_desc
[7] = cpu_to_le16(((tx_params
->tid
& 0xf) << 4) |
98 (skb
->priority
& 0xf) |
99 (tx_params
->sta_id
<< 8));
101 status
= adapter
->host_intf_write_pkt(common
->priv
,
105 rsi_dbg(ERR_ZONE
, "%s: Failed to write pkt\n",
109 ++common
->tx_stats
.total_tx_pkt_freed
[skb
->priority
];
110 rsi_indicate_tx_status(common
->priv
, skb
, status
);
115 * rsi_send_mgmt_pkt() - This functions sends the received management packet
116 * from driver to device.
117 * @common: Pointer to the driver private structure.
118 * @skb: Pointer to the socket buffer structure.
120 * Return: status: 0 on success, -1 on failure.
122 int rsi_send_mgmt_pkt(struct rsi_common
*common
,
125 struct rsi_hw
*adapter
= common
->priv
;
126 struct ieee80211_hdr
*wh
= NULL
;
127 struct ieee80211_tx_info
*info
;
128 struct ieee80211_bss_conf
*bss
= NULL
;
129 struct ieee80211_hw
*hw
= adapter
->hw
;
130 struct ieee80211_conf
*conf
= &hw
->conf
;
131 struct skb_info
*tx_params
;
137 info
= IEEE80211_SKB_CB(skb
);
138 tx_params
= (struct skb_info
*)info
->driver_data
;
139 extnd_size
= ((uintptr_t)skb
->data
& 0x3);
141 if (tx_params
->flags
& INTERNAL_MGMT_PKT
) {
142 if ((extnd_size
) > skb_headroom(skb
)) {
143 rsi_dbg(ERR_ZONE
, "%s: Unable to send pkt\n", __func__
);
147 skb_push(skb
, extnd_size
);
148 skb
->data
[extnd_size
+ 4] = extnd_size
;
149 status
= adapter
->host_intf_write_pkt(common
->priv
,
154 "%s: Failed to write the packet\n", __func__
);
160 bss
= &info
->control
.vif
->bss_conf
;
161 wh
= (struct ieee80211_hdr
*)&skb
->data
[0];
163 if (FRAME_DESC_SZ
> skb_headroom(skb
))
166 skb_push(skb
, FRAME_DESC_SZ
);
167 memset(skb
->data
, 0, FRAME_DESC_SZ
);
168 msg
= (__le16
*)skb
->data
;
170 if (skb
->len
> MAX_MGMT_PKT_SIZE
) {
171 rsi_dbg(INFO_ZONE
, "%s: Dropping mgmt pkt > 512\n", __func__
);
175 msg
[0] = cpu_to_le16((skb
->len
- FRAME_DESC_SZ
) |
176 (RSI_WIFI_MGMT_Q
<< 12));
177 msg
[1] = cpu_to_le16(TX_DOT11_MGMT
);
178 msg
[2] = cpu_to_le16(MIN_802_11_HDR_LEN
<< 8);
179 msg
[3] = cpu_to_le16(RATE_INFO_ENABLE
);
180 msg
[6] = cpu_to_le16(le16_to_cpu(wh
->seq_ctrl
) >> 4);
182 if (wh
->addr1
[0] & BIT(0))
183 msg
[3] |= cpu_to_le16(RSI_BROADCAST_PKT
);
185 if (common
->band
== IEEE80211_BAND_2GHZ
)
186 msg
[4] = cpu_to_le16(RSI_11B_MODE
);
188 msg
[4] = cpu_to_le16((RSI_RATE_6
& 0x0f) | RSI_11G_MODE
);
190 if (conf_is_ht40(conf
)) {
191 msg
[4] = cpu_to_le16(0xB | RSI_11G_MODE
);
192 msg
[5] = cpu_to_le16(0x6);
195 /* Indicate to firmware to give cfm */
196 if ((skb
->data
[16] == IEEE80211_STYPE_PROBE_REQ
) && (!bss
->assoc
)) {
197 msg
[1] |= cpu_to_le16(BIT(10));
198 msg
[7] = cpu_to_le16(PROBEREQ_CONFIRM
);
199 common
->mgmt_q_block
= true;
202 msg
[7] |= cpu_to_le16(vap_id
<< 8);
204 status
= adapter
->host_intf_write_pkt(common
->priv
,
208 rsi_dbg(ERR_ZONE
, "%s: Failed to write the packet\n", __func__
);
211 rsi_indicate_tx_status(common
->priv
, skb
, status
);