Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rsi: Add RS9113 wireless driver

This patch adds the Redpine Signals' 91x wireless driver.

Signed-off-by: Fariya Fatima <fariyaf@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Fariya Fatima and committed by
John W. Linville
dad0d04f 097638a0

+6644
+1
drivers/net/wireless/Kconfig
··· 281 281 source "drivers/net/wireless/zd1211rw/Kconfig" 282 282 source "drivers/net/wireless/mwifiex/Kconfig" 283 283 source "drivers/net/wireless/cw1200/Kconfig" 284 + source "drivers/net/wireless/rsi/Kconfig" 284 285 285 286 endif # WLAN
+1
drivers/net/wireless/Makefile
··· 59 59 obj-$(CONFIG_BRCMSMAC) += brcm80211/ 60 60 61 61 obj-$(CONFIG_CW1200) += cw1200/ 62 + obj-$(CONFIG_RSI_91X) += rsi/
+30
drivers/net/wireless/rsi/Kconfig
··· 1 + config RSI_91X 2 + tristate "Redpine Signals Inc 91x WLAN driver support" 3 + depends on MAC80211 4 + ---help--- 5 + This option enabes support for RSI 1x1 devices. 6 + Select M (recommended), if you have a RSI 1x1 wireless module. 7 + 8 + config RSI_DEBUGFS 9 + bool "Redpine Signals Inc debug support" 10 + depends on RSI_91X 11 + default y 12 + ---help--- 13 + Say Y, if you would like to enable debug support. This option 14 + creates debugfs entries 15 + 16 + config RSI_SDIO 17 + tristate "Redpine Signals SDIO bus support" 18 + depends on MMC && RSI_91X 19 + default m 20 + ---help--- 21 + This option enables the SDIO bus support in rsi drivers. 22 + Select M (recommended), if you have a RSI 1x1 wireless module. 23 + 24 + config RSI_USB 25 + tristate "Redpine Signals USB bus support" 26 + depends on USB && RSI_91X 27 + default m 28 + ---help--- 29 + This option enables the USB bus support in rsi drivers. 30 + Select M (recommended), if you have a RSI 1x1 wireless module.
+12
drivers/net/wireless/rsi/Makefile
··· 1 + rsi_91x-y += rsi_91x_main.o 2 + rsi_91x-y += rsi_91x_core.o 3 + rsi_91x-y += rsi_91x_mac80211.o 4 + rsi_91x-y += rsi_91x_mgmt.o 5 + rsi_91x-y += rsi_91x_pkt.o 6 + rsi_91x-$(CONFIG_RSI_DEBUGFS) += rsi_91x_debugfs.o 7 + 8 + rsi_usb-y += rsi_91x_usb.o rsi_91x_usb_ops.o 9 + rsi_sdio-y += rsi_91x_sdio.o rsi_91x_sdio_ops.o 10 + obj-$(CONFIG_RSI_91X) += rsi_91x.o 11 + obj-$(CONFIG_RSI_SDIO) += rsi_sdio.o 12 + obj-$(CONFIG_RSI_USB) += rsi_usb.o
+342
drivers/net/wireless/rsi/rsi_91x_core.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include "rsi_mgmt.h" 18 + #include "rsi_common.h" 19 + 20 + /** 21 + * rsi_determine_min_weight_queue() - This function determines the queue with 22 + * the min weight. 23 + * @common: Pointer to the driver private structure. 24 + * 25 + * Return: q_num: Corresponding queue number. 26 + */ 27 + static u8 rsi_determine_min_weight_queue(struct rsi_common *common) 28 + { 29 + struct wmm_qinfo *tx_qinfo = common->tx_qinfo; 30 + u32 q_len = 0; 31 + u8 ii = 0; 32 + 33 + for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) { 34 + q_len = skb_queue_len(&common->tx_queue[ii]); 35 + if ((tx_qinfo[ii].pkt_contended) && q_len) { 36 + common->min_weight = tx_qinfo[ii].weight; 37 + break; 38 + } 39 + } 40 + return ii; 41 + } 42 + 43 + /** 44 + * rsi_recalculate_weights() - This function recalculates the weights 45 + * corresponding to each queue. 46 + * @common: Pointer to the driver private structure. 47 + * 48 + * Return: recontend_queue bool variable 49 + */ 50 + static bool rsi_recalculate_weights(struct rsi_common *common) 51 + { 52 + struct wmm_qinfo *tx_qinfo = common->tx_qinfo; 53 + bool recontend_queue = false; 54 + u8 ii = 0; 55 + u32 q_len = 0; 56 + 57 + for (ii = 0; ii < NUM_EDCA_QUEUES; ii++) { 58 + q_len = skb_queue_len(&common->tx_queue[ii]); 59 + /* Check for the need of contention */ 60 + if (q_len) { 61 + if (tx_qinfo[ii].pkt_contended) { 62 + tx_qinfo[ii].weight = 63 + ((tx_qinfo[ii].weight > common->min_weight) ? 64 + tx_qinfo[ii].weight - common->min_weight : 0); 65 + } else { 66 + tx_qinfo[ii].pkt_contended = 1; 67 + tx_qinfo[ii].weight = tx_qinfo[ii].wme_params; 68 + recontend_queue = true; 69 + } 70 + } else { /* No packets so no contention */ 71 + tx_qinfo[ii].weight = 0; 72 + tx_qinfo[ii].pkt_contended = 0; 73 + } 74 + } 75 + 76 + return recontend_queue; 77 + } 78 + 79 + /** 80 + * rsi_core_determine_hal_queue() - This function determines the queue from 81 + * which packet has to be dequeued. 82 + * @common: Pointer to the driver private structure. 83 + * 84 + * Return: q_num: Corresponding queue number on success. 85 + */ 86 + static u8 rsi_core_determine_hal_queue(struct rsi_common *common) 87 + { 88 + bool recontend_queue = false; 89 + u32 q_len = 0; 90 + u8 q_num = INVALID_QUEUE; 91 + u8 ii, min = 0; 92 + 93 + if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { 94 + if (!common->mgmt_q_block) 95 + q_num = MGMT_SOFT_Q; 96 + return q_num; 97 + } 98 + 99 + if (common->pkt_cnt != 0) { 100 + --common->pkt_cnt; 101 + return common->selected_qnum; 102 + } 103 + 104 + get_queue_num: 105 + q_num = 0; 106 + recontend_queue = false; 107 + 108 + q_num = rsi_determine_min_weight_queue(common); 109 + q_len = skb_queue_len(&common->tx_queue[ii]); 110 + ii = q_num; 111 + 112 + /* Selecting the queue with least back off */ 113 + for (; ii < NUM_EDCA_QUEUES; ii++) { 114 + if (((common->tx_qinfo[ii].pkt_contended) && 115 + (common->tx_qinfo[ii].weight < min)) && q_len) { 116 + min = common->tx_qinfo[ii].weight; 117 + q_num = ii; 118 + } 119 + } 120 + 121 + common->tx_qinfo[q_num].pkt_contended = 0; 122 + /* Adjust the back off values for all queues again */ 123 + recontend_queue = rsi_recalculate_weights(common); 124 + 125 + q_len = skb_queue_len(&common->tx_queue[q_num]); 126 + if (!q_len) { 127 + /* If any queues are freshly contended and the selected queue 128 + * doesn't have any packets 129 + * then get the queue number again with fresh values 130 + */ 131 + if (recontend_queue) 132 + goto get_queue_num; 133 + 134 + q_num = INVALID_QUEUE; 135 + return q_num; 136 + } 137 + 138 + common->selected_qnum = q_num; 139 + q_len = skb_queue_len(&common->tx_queue[q_num]); 140 + 141 + switch (common->selected_qnum) { 142 + case VO_Q: 143 + if (q_len > MAX_CONTINUOUS_VO_PKTS) 144 + common->pkt_cnt = (MAX_CONTINUOUS_VO_PKTS - 1); 145 + else 146 + common->pkt_cnt = --q_len; 147 + break; 148 + 149 + case VI_Q: 150 + if (q_len > MAX_CONTINUOUS_VI_PKTS) 151 + common->pkt_cnt = (MAX_CONTINUOUS_VI_PKTS - 1); 152 + else 153 + common->pkt_cnt = --q_len; 154 + 155 + break; 156 + 157 + default: 158 + common->pkt_cnt = 0; 159 + break; 160 + } 161 + 162 + return q_num; 163 + } 164 + 165 + /** 166 + * rsi_core_queue_pkt() - This functions enqueues the packet to the queue 167 + * specified by the queue number. 168 + * @common: Pointer to the driver private structure. 169 + * @skb: Pointer to the socket buffer structure. 170 + * 171 + * Return: None. 172 + */ 173 + static void rsi_core_queue_pkt(struct rsi_common *common, 174 + struct sk_buff *skb) 175 + { 176 + u8 q_num = skb->priority; 177 + if (q_num >= NUM_SOFT_QUEUES) { 178 + rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n", 179 + __func__, q_num); 180 + dev_kfree_skb(skb); 181 + return; 182 + } 183 + 184 + skb_queue_tail(&common->tx_queue[q_num], skb); 185 + } 186 + 187 + /** 188 + * rsi_core_dequeue_pkt() - This functions dequeues the packet from the queue 189 + * specified by the queue number. 190 + * @common: Pointer to the driver private structure. 191 + * @q_num: Queue number. 192 + * 193 + * Return: Pointer to sk_buff structure. 194 + */ 195 + static struct sk_buff *rsi_core_dequeue_pkt(struct rsi_common *common, 196 + u8 q_num) 197 + { 198 + if (q_num >= NUM_SOFT_QUEUES) { 199 + rsi_dbg(ERR_ZONE, "%s: Invalid Queue Number: q_num = %d\n", 200 + __func__, q_num); 201 + return NULL; 202 + } 203 + 204 + return skb_dequeue(&common->tx_queue[q_num]); 205 + } 206 + 207 + /** 208 + * rsi_core_qos_processor() - This function is used to determine the wmm queue 209 + * based on the backoff procedure. Data packets are 210 + * dequeued from the selected hal queue and sent to 211 + * the below layers. 212 + * @common: Pointer to the driver private structure. 213 + * 214 + * Return: None. 215 + */ 216 + void rsi_core_qos_processor(struct rsi_common *common) 217 + { 218 + struct rsi_hw *adapter = common->priv; 219 + struct sk_buff *skb; 220 + unsigned long tstamp_1, tstamp_2; 221 + u8 q_num; 222 + int status; 223 + 224 + tstamp_1 = jiffies; 225 + while (1) { 226 + q_num = rsi_core_determine_hal_queue(common); 227 + rsi_dbg(DATA_TX_ZONE, 228 + "%s: Queue number = %d\n", __func__, q_num); 229 + 230 + if (q_num == INVALID_QUEUE) { 231 + rsi_dbg(DATA_TX_ZONE, "%s: No More Pkt\n", __func__); 232 + break; 233 + } 234 + 235 + mutex_lock(&common->tx_rxlock); 236 + 237 + status = adapter->check_hw_queue_status(adapter, q_num); 238 + if ((status <= 0)) { 239 + mutex_unlock(&common->tx_rxlock); 240 + break; 241 + } 242 + 243 + if ((q_num < MGMT_SOFT_Q) && 244 + ((skb_queue_len(&common->tx_queue[q_num])) <= 245 + MIN_DATA_QUEUE_WATER_MARK)) { 246 + if (ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) 247 + ieee80211_wake_queue(adapter->hw, 248 + WME_AC(q_num)); 249 + } 250 + 251 + skb = rsi_core_dequeue_pkt(common, q_num); 252 + if (skb == NULL) { 253 + mutex_unlock(&common->tx_rxlock); 254 + break; 255 + } 256 + 257 + if (q_num == MGMT_SOFT_Q) 258 + status = rsi_send_mgmt_pkt(common, skb); 259 + else 260 + status = rsi_send_data_pkt(common, skb); 261 + 262 + if (status) { 263 + mutex_unlock(&common->tx_rxlock); 264 + break; 265 + } 266 + 267 + common->tx_stats.total_tx_pkt_send[q_num]++; 268 + 269 + tstamp_2 = jiffies; 270 + mutex_unlock(&common->tx_rxlock); 271 + 272 + if (tstamp_2 > tstamp_1 + (300 * HZ / 1000)) 273 + schedule(); 274 + } 275 + } 276 + 277 + /** 278 + * rsi_core_xmit() - This function transmits the packets received from mac80211 279 + * @common: Pointer to the driver private structure. 280 + * @skb: Pointer to the socket buffer structure. 281 + * 282 + * Return: None. 283 + */ 284 + void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb) 285 + { 286 + struct rsi_hw *adapter = common->priv; 287 + struct ieee80211_tx_info *info; 288 + struct skb_info *tx_params; 289 + struct ieee80211_hdr *tmp_hdr = NULL; 290 + u8 q_num, tid = 0; 291 + 292 + if ((!skb) || (!skb->len)) { 293 + rsi_dbg(ERR_ZONE, "%s: Null skb/zero Length packet\n", 294 + __func__); 295 + goto xmit_fail; 296 + } 297 + info = IEEE80211_SKB_CB(skb); 298 + tx_params = (struct skb_info *)info->driver_data; 299 + tmp_hdr = (struct ieee80211_hdr *)&skb->data[0]; 300 + 301 + if (common->fsm_state != FSM_MAC_INIT_DONE) { 302 + rsi_dbg(ERR_ZONE, "%s: FSM state not open\n", __func__); 303 + goto xmit_fail; 304 + } 305 + 306 + if ((ieee80211_is_mgmt(tmp_hdr->frame_control)) || 307 + (ieee80211_is_ctl(tmp_hdr->frame_control))) { 308 + q_num = MGMT_SOFT_Q; 309 + skb->priority = q_num; 310 + } else { 311 + if (ieee80211_is_data_qos(tmp_hdr->frame_control)) { 312 + tid = (skb->data[24] & IEEE80211_QOS_TID); 313 + skb->priority = TID_TO_WME_AC(tid); 314 + } else { 315 + tid = IEEE80211_NONQOS_TID; 316 + skb->priority = BE_Q; 317 + } 318 + q_num = skb->priority; 319 + tx_params->tid = tid; 320 + tx_params->sta_id = 0; 321 + } 322 + 323 + if ((q_num != MGMT_SOFT_Q) && 324 + ((skb_queue_len(&common->tx_queue[q_num]) + 1) >= 325 + DATA_QUEUE_WATER_MARK)) { 326 + if (!ieee80211_queue_stopped(adapter->hw, WME_AC(q_num))) 327 + ieee80211_stop_queue(adapter->hw, WME_AC(q_num)); 328 + rsi_set_event(&common->tx_thread.event); 329 + goto xmit_fail; 330 + } 331 + 332 + rsi_core_queue_pkt(common, skb); 333 + rsi_dbg(DATA_TX_ZONE, "%s: ===> Scheduling TX thead <===\n", __func__); 334 + rsi_set_event(&common->tx_thread.event); 335 + 336 + return; 337 + 338 + xmit_fail: 339 + rsi_dbg(ERR_ZONE, "%s: Failed to queue packet\n", __func__); 340 + /* Dropping pkt here */ 341 + ieee80211_free_txskb(common->priv->hw, skb); 342 + }
+339
drivers/net/wireless/rsi/rsi_91x_debugfs.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include "rsi_debugfs.h" 18 + #include "rsi_sdio.h" 19 + 20 + /** 21 + * rsi_sdio_stats_read() - This function returns the sdio status of the driver. 22 + * @seq: Pointer to the sequence file structure. 23 + * @data: Pointer to the data. 24 + * 25 + * Return: 0 on success, -1 on failure. 26 + */ 27 + static int rsi_sdio_stats_read(struct seq_file *seq, void *data) 28 + { 29 + struct rsi_common *common = seq->private; 30 + struct rsi_hw *adapter = common->priv; 31 + struct rsi_91x_sdiodev *dev = 32 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 33 + 34 + seq_printf(seq, "total_sdio_interrupts: %d\n", 35 + dev->rx_info.sdio_int_counter); 36 + seq_printf(seq, "sdio_msdu_pending_intr_count: %d\n", 37 + dev->rx_info.total_sdio_msdu_pending_intr); 38 + seq_printf(seq, "sdio_buff_full_count : %d\n", 39 + dev->rx_info.buf_full_counter); 40 + seq_printf(seq, "sdio_buf_semi_full_count %d\n", 41 + dev->rx_info.buf_semi_full_counter); 42 + seq_printf(seq, "sdio_unknown_intr_count: %d\n", 43 + dev->rx_info.total_sdio_unknown_intr); 44 + /* RX Path Stats */ 45 + seq_printf(seq, "BUFFER FULL STATUS : %d\n", 46 + dev->rx_info.buffer_full); 47 + seq_printf(seq, "SEMI BUFFER FULL STATUS : %d\n", 48 + dev->rx_info.semi_buffer_full); 49 + seq_printf(seq, "MGMT BUFFER FULL STATUS : %d\n", 50 + dev->rx_info.mgmt_buffer_full); 51 + seq_printf(seq, "BUFFER FULL COUNTER : %d\n", 52 + dev->rx_info.buf_full_counter); 53 + seq_printf(seq, "BUFFER SEMI FULL COUNTER : %d\n", 54 + dev->rx_info.buf_semi_full_counter); 55 + seq_printf(seq, "MGMT BUFFER FULL COUNTER : %d\n", 56 + dev->rx_info.mgmt_buf_full_counter); 57 + 58 + return 0; 59 + } 60 + 61 + /** 62 + * rsi_sdio_stats_open() - This funtion calls single open function of seq_file 63 + * to open file and read contents from it. 64 + * @inode: Pointer to the inode structure. 65 + * @file: Pointer to the file structure. 66 + * 67 + * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 68 + */ 69 + static int rsi_sdio_stats_open(struct inode *inode, 70 + struct file *file) 71 + { 72 + return single_open(file, rsi_sdio_stats_read, inode->i_private); 73 + } 74 + 75 + /** 76 + * rsi_version_read() - This function gives driver and firmware version number. 77 + * @seq: Pointer to the sequence file structure. 78 + * @data: Pointer to the data. 79 + * 80 + * Return: 0 on success, -1 on failure. 81 + */ 82 + static int rsi_version_read(struct seq_file *seq, void *data) 83 + { 84 + struct rsi_common *common = seq->private; 85 + 86 + common->driver_ver.major = 0; 87 + common->driver_ver.minor = 1; 88 + common->driver_ver.release_num = 0; 89 + common->driver_ver.patch_num = 0; 90 + seq_printf(seq, "Driver : %x.%d.%d.%d\nLMAC : %d.%d.%d.%d\n", 91 + common->driver_ver.major, 92 + common->driver_ver.minor, 93 + common->driver_ver.release_num, 94 + common->driver_ver.patch_num, 95 + common->fw_ver.major, 96 + common->fw_ver.minor, 97 + common->fw_ver.release_num, 98 + common->fw_ver.patch_num); 99 + return 0; 100 + } 101 + 102 + /** 103 + * rsi_version_open() - This funtion calls single open function of seq_file to 104 + * open file and read contents from it. 105 + * @inode: Pointer to the inode structure. 106 + * @file: Pointer to the file structure. 107 + * 108 + * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 109 + */ 110 + static int rsi_version_open(struct inode *inode, 111 + struct file *file) 112 + { 113 + return single_open(file, rsi_version_read, inode->i_private); 114 + } 115 + 116 + /** 117 + * rsi_stats_read() - This function return the status of the driver. 118 + * @seq: Pointer to the sequence file structure. 119 + * @data: Pointer to the data. 120 + * 121 + * Return: 0 on success, -1 on failure. 122 + */ 123 + static int rsi_stats_read(struct seq_file *seq, void *data) 124 + { 125 + struct rsi_common *common = seq->private; 126 + 127 + unsigned char fsm_state[][32] = { 128 + "FSM_CARD_NOT_READY", 129 + "FSM_BOOT_PARAMS_SENT", 130 + "FSM_EEPROM_READ_MAC_ADDR", 131 + "FSM_RESET_MAC_SENT", 132 + "FSM_RADIO_CAPS_SENT", 133 + "FSM_BB_RF_PROG_SENT", 134 + "FSM_MAC_INIT_DONE" 135 + }; 136 + seq_puts(seq, "==> RSI STA DRIVER STATUS <==\n"); 137 + seq_puts(seq, "DRIVER_FSM_STATE: "); 138 + 139 + if (common->fsm_state <= FSM_MAC_INIT_DONE) 140 + seq_printf(seq, "%s", fsm_state[common->fsm_state]); 141 + 142 + seq_printf(seq, "(%d)\n\n", common->fsm_state); 143 + 144 + /* Mgmt TX Path Stats */ 145 + seq_printf(seq, "total_mgmt_pkt_send : %d\n", 146 + common->tx_stats.total_tx_pkt_send[MGMT_SOFT_Q]); 147 + seq_printf(seq, "total_mgmt_pkt_queued : %d\n", 148 + skb_queue_len(&common->tx_queue[4])); 149 + seq_printf(seq, "total_mgmt_pkt_freed : %d\n", 150 + common->tx_stats.total_tx_pkt_freed[MGMT_SOFT_Q]); 151 + 152 + /* Data TX Path Stats */ 153 + seq_printf(seq, "total_data_vo_pkt_send: %8d\t", 154 + common->tx_stats.total_tx_pkt_send[VO_Q]); 155 + seq_printf(seq, "total_data_vo_pkt_queued: %8d\t", 156 + skb_queue_len(&common->tx_queue[0])); 157 + seq_printf(seq, "total_vo_pkt_freed: %8d\n", 158 + common->tx_stats.total_tx_pkt_freed[VO_Q]); 159 + seq_printf(seq, "total_data_vi_pkt_send: %8d\t", 160 + common->tx_stats.total_tx_pkt_send[VI_Q]); 161 + seq_printf(seq, "total_data_vi_pkt_queued: %8d\t", 162 + skb_queue_len(&common->tx_queue[1])); 163 + seq_printf(seq, "total_vi_pkt_freed: %8d\n", 164 + common->tx_stats.total_tx_pkt_freed[VI_Q]); 165 + seq_printf(seq, "total_data_be_pkt_send: %8d\t", 166 + common->tx_stats.total_tx_pkt_send[BE_Q]); 167 + seq_printf(seq, "total_data_be_pkt_queued: %8d\t", 168 + skb_queue_len(&common->tx_queue[2])); 169 + seq_printf(seq, "total_be_pkt_freed: %8d\n", 170 + common->tx_stats.total_tx_pkt_freed[BE_Q]); 171 + seq_printf(seq, "total_data_bk_pkt_send: %8d\t", 172 + common->tx_stats.total_tx_pkt_send[BK_Q]); 173 + seq_printf(seq, "total_data_bk_pkt_queued: %8d\t", 174 + skb_queue_len(&common->tx_queue[3])); 175 + seq_printf(seq, "total_bk_pkt_freed: %8d\n", 176 + common->tx_stats.total_tx_pkt_freed[BK_Q]); 177 + 178 + seq_puts(seq, "\n"); 179 + return 0; 180 + } 181 + 182 + /** 183 + * rsi_stats_open() - This funtion calls single open function of seq_file to 184 + * open file and read contents from it. 185 + * @inode: Pointer to the inode structure. 186 + * @file: Pointer to the file structure. 187 + * 188 + * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 189 + */ 190 + static int rsi_stats_open(struct inode *inode, 191 + struct file *file) 192 + { 193 + return single_open(file, rsi_stats_read, inode->i_private); 194 + } 195 + 196 + /** 197 + * rsi_debug_zone_read() - This function display the currently enabled debug zones. 198 + * @seq: Pointer to the sequence file structure. 199 + * @data: Pointer to the data. 200 + * 201 + * Return: 0 on success, -1 on failure. 202 + */ 203 + static int rsi_debug_zone_read(struct seq_file *seq, void *data) 204 + { 205 + rsi_dbg(FSM_ZONE, "%x: rsi_enabled zone", rsi_zone_enabled); 206 + seq_printf(seq, "The zones available are %#x\n", 207 + rsi_zone_enabled); 208 + return 0; 209 + } 210 + 211 + /** 212 + * rsi_debug_read() - This funtion calls single open function of seq_file to 213 + * open file and read contents from it. 214 + * @inode: Pointer to the inode structure. 215 + * @file: Pointer to the file structure. 216 + * 217 + * Return: Pointer to the opened file status: 0 on success, ENOMEM on failure. 218 + */ 219 + static int rsi_debug_read(struct inode *inode, 220 + struct file *file) 221 + { 222 + return single_open(file, rsi_debug_zone_read, inode->i_private); 223 + } 224 + 225 + /** 226 + * rsi_debug_zone_write() - This function writes into hal queues as per user 227 + * requirement. 228 + * @filp: Pointer to the file structure. 229 + * @buff: Pointer to the character buffer. 230 + * @len: Length of the data to be written into buffer. 231 + * @data: Pointer to the data. 232 + * 233 + * Return: len: Number of bytes read. 234 + */ 235 + static ssize_t rsi_debug_zone_write(struct file *filp, 236 + const char __user *buff, 237 + size_t len, 238 + loff_t *data) 239 + { 240 + unsigned long dbg_zone; 241 + int ret; 242 + 243 + if (!len) 244 + return 0; 245 + 246 + ret = kstrtoul_from_user(buff, len, 16, &dbg_zone); 247 + 248 + if (ret) 249 + return ret; 250 + 251 + rsi_zone_enabled = dbg_zone; 252 + return len; 253 + } 254 + 255 + #define FOPS(fopen) { \ 256 + .owner = THIS_MODULE, \ 257 + .open = (fopen), \ 258 + .read = seq_read, \ 259 + .llseek = seq_lseek, \ 260 + } 261 + 262 + #define FOPS_RW(fopen, fwrite) { \ 263 + .owner = THIS_MODULE, \ 264 + .open = (fopen), \ 265 + .read = seq_read, \ 266 + .llseek = seq_lseek, \ 267 + .write = (fwrite), \ 268 + } 269 + 270 + static const struct rsi_dbg_files dev_debugfs_files[] = { 271 + {"version", 0644, FOPS(rsi_version_open),}, 272 + {"stats", 0644, FOPS(rsi_stats_open),}, 273 + {"debug_zone", 0666, FOPS_RW(rsi_debug_read, rsi_debug_zone_write),}, 274 + {"sdio_stats", 0644, FOPS(rsi_sdio_stats_open),}, 275 + }; 276 + 277 + /** 278 + * rsi_init_dbgfs() - This function initializes the dbgfs entry. 279 + * @adapter: Pointer to the adapter structure. 280 + * 281 + * Return: 0 on success, -1 on failure. 282 + */ 283 + int rsi_init_dbgfs(struct rsi_hw *adapter) 284 + { 285 + struct rsi_common *common = adapter->priv; 286 + struct rsi_debugfs *dev_dbgfs; 287 + char devdir[6]; 288 + int ii; 289 + const struct rsi_dbg_files *files; 290 + 291 + dev_dbgfs = kzalloc(sizeof(*dev_dbgfs), GFP_KERNEL); 292 + adapter->dfsentry = dev_dbgfs; 293 + 294 + snprintf(devdir, sizeof(devdir), "%s", 295 + wiphy_name(adapter->hw->wiphy)); 296 + dev_dbgfs->subdir = debugfs_create_dir(devdir, NULL); 297 + 298 + if (IS_ERR(dev_dbgfs->subdir)) { 299 + if (dev_dbgfs->subdir == ERR_PTR(-ENODEV)) 300 + rsi_dbg(ERR_ZONE, 301 + "%s:Debugfs has not been mounted\n", __func__); 302 + else 303 + rsi_dbg(ERR_ZONE, "debugfs:%s not created\n", devdir); 304 + 305 + adapter->dfsentry = NULL; 306 + kfree(dev_dbgfs); 307 + return (int)PTR_ERR(dev_dbgfs->subdir); 308 + } else { 309 + for (ii = 0; ii < adapter->num_debugfs_entries; ii++) { 310 + files = &dev_debugfs_files[ii]; 311 + dev_dbgfs->rsi_files[ii] = 312 + debugfs_create_file(files->name, 313 + files->perms, 314 + dev_dbgfs->subdir, 315 + common, 316 + &files->fops); 317 + } 318 + } 319 + return 0; 320 + } 321 + EXPORT_SYMBOL_GPL(rsi_init_dbgfs); 322 + 323 + /** 324 + * rsi_remove_dbgfs() - Removes the previously created dbgfs file entries 325 + * in the reverse order of creation. 326 + * @adapter: Pointer to the adapter structure. 327 + * 328 + * Return: None. 329 + */ 330 + void rsi_remove_dbgfs(struct rsi_hw *adapter) 331 + { 332 + struct rsi_debugfs *dev_dbgfs = adapter->dfsentry; 333 + 334 + if (!dev_dbgfs) 335 + return; 336 + 337 + debugfs_remove_recursive(dev_dbgfs->subdir); 338 + } 339 + EXPORT_SYMBOL_GPL(rsi_remove_dbgfs);
+1008
drivers/net/wireless/rsi/rsi_91x_mac80211.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include <linux/etherdevice.h> 18 + #include "rsi_debugfs.h" 19 + #include "rsi_mgmt.h" 20 + #include "rsi_common.h" 21 + 22 + static const struct ieee80211_channel rsi_2ghz_channels[] = { 23 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2412, 24 + .hw_value = 1 }, /* Channel 1 */ 25 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2417, 26 + .hw_value = 2 }, /* Channel 2 */ 27 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2422, 28 + .hw_value = 3 }, /* Channel 3 */ 29 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2427, 30 + .hw_value = 4 }, /* Channel 4 */ 31 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2432, 32 + .hw_value = 5 }, /* Channel 5 */ 33 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2437, 34 + .hw_value = 6 }, /* Channel 6 */ 35 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2442, 36 + .hw_value = 7 }, /* Channel 7 */ 37 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2447, 38 + .hw_value = 8 }, /* Channel 8 */ 39 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2452, 40 + .hw_value = 9 }, /* Channel 9 */ 41 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2457, 42 + .hw_value = 10 }, /* Channel 10 */ 43 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2462, 44 + .hw_value = 11 }, /* Channel 11 */ 45 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2467, 46 + .hw_value = 12 }, /* Channel 12 */ 47 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2472, 48 + .hw_value = 13 }, /* Channel 13 */ 49 + { .band = IEEE80211_BAND_2GHZ, .center_freq = 2484, 50 + .hw_value = 14 }, /* Channel 14 */ 51 + }; 52 + 53 + static const struct ieee80211_channel rsi_5ghz_channels[] = { 54 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5180, 55 + .hw_value = 36, }, /* Channel 36 */ 56 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5200, 57 + .hw_value = 40, }, /* Channel 40 */ 58 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5220, 59 + .hw_value = 44, }, /* Channel 44 */ 60 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5240, 61 + .hw_value = 48, }, /* Channel 48 */ 62 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5260, 63 + .hw_value = 52, }, /* Channel 52 */ 64 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5280, 65 + .hw_value = 56, }, /* Channel 56 */ 66 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5300, 67 + .hw_value = 60, }, /* Channel 60 */ 68 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5320, 69 + .hw_value = 64, }, /* Channel 64 */ 70 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5500, 71 + .hw_value = 100, }, /* Channel 100 */ 72 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5520, 73 + .hw_value = 104, }, /* Channel 104 */ 74 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5540, 75 + .hw_value = 108, }, /* Channel 108 */ 76 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5560, 77 + .hw_value = 112, }, /* Channel 112 */ 78 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5580, 79 + .hw_value = 116, }, /* Channel 116 */ 80 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5600, 81 + .hw_value = 120, }, /* Channel 120 */ 82 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5620, 83 + .hw_value = 124, }, /* Channel 124 */ 84 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5640, 85 + .hw_value = 128, }, /* Channel 128 */ 86 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5660, 87 + .hw_value = 132, }, /* Channel 132 */ 88 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5680, 89 + .hw_value = 136, }, /* Channel 136 */ 90 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5700, 91 + .hw_value = 140, }, /* Channel 140 */ 92 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5745, 93 + .hw_value = 149, }, /* Channel 149 */ 94 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5765, 95 + .hw_value = 153, }, /* Channel 153 */ 96 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5785, 97 + .hw_value = 157, }, /* Channel 157 */ 98 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5805, 99 + .hw_value = 161, }, /* Channel 161 */ 100 + { .band = IEEE80211_BAND_5GHZ, .center_freq = 5825, 101 + .hw_value = 165, }, /* Channel 165 */ 102 + }; 103 + 104 + struct ieee80211_rate rsi_rates[12] = { 105 + { .bitrate = STD_RATE_01 * 5, .hw_value = RSI_RATE_1 }, 106 + { .bitrate = STD_RATE_02 * 5, .hw_value = RSI_RATE_2 }, 107 + { .bitrate = STD_RATE_5_5 * 5, .hw_value = RSI_RATE_5_5 }, 108 + { .bitrate = STD_RATE_11 * 5, .hw_value = RSI_RATE_11 }, 109 + { .bitrate = STD_RATE_06 * 5, .hw_value = RSI_RATE_6 }, 110 + { .bitrate = STD_RATE_09 * 5, .hw_value = RSI_RATE_9 }, 111 + { .bitrate = STD_RATE_12 * 5, .hw_value = RSI_RATE_12 }, 112 + { .bitrate = STD_RATE_18 * 5, .hw_value = RSI_RATE_18 }, 113 + { .bitrate = STD_RATE_24 * 5, .hw_value = RSI_RATE_24 }, 114 + { .bitrate = STD_RATE_36 * 5, .hw_value = RSI_RATE_36 }, 115 + { .bitrate = STD_RATE_48 * 5, .hw_value = RSI_RATE_48 }, 116 + { .bitrate = STD_RATE_54 * 5, .hw_value = RSI_RATE_54 }, 117 + }; 118 + 119 + const u16 rsi_mcsrates[8] = { 120 + RSI_RATE_MCS0, RSI_RATE_MCS1, RSI_RATE_MCS2, RSI_RATE_MCS3, 121 + RSI_RATE_MCS4, RSI_RATE_MCS5, RSI_RATE_MCS6, RSI_RATE_MCS7 122 + }; 123 + 124 + /** 125 + * rsi_is_cipher_wep() - This function determines if the cipher is WEP or not. 126 + * @common: Pointer to the driver private structure. 127 + * 128 + * Return: If cipher type is WEP, a value of 1 is returned, else 0. 129 + */ 130 + 131 + bool rsi_is_cipher_wep(struct rsi_common *common) 132 + { 133 + if (((common->secinfo.gtk_cipher == WLAN_CIPHER_SUITE_WEP104) || 134 + (common->secinfo.gtk_cipher == WLAN_CIPHER_SUITE_WEP40)) && 135 + (!common->secinfo.ptk_cipher)) 136 + return true; 137 + else 138 + return false; 139 + } 140 + 141 + /** 142 + * rsi_register_rates_channels() - This function registers channels and rates. 143 + * @adapter: Pointer to the adapter structure. 144 + * @band: Operating band to be set. 145 + * 146 + * Return: None. 147 + */ 148 + static void rsi_register_rates_channels(struct rsi_hw *adapter, int band) 149 + { 150 + struct ieee80211_supported_band *sbands = &adapter->sbands[band]; 151 + void *channels = NULL; 152 + 153 + if (band == IEEE80211_BAND_2GHZ) { 154 + channels = kmalloc(sizeof(rsi_2ghz_channels), GFP_KERNEL); 155 + memcpy(channels, 156 + rsi_2ghz_channels, 157 + sizeof(rsi_2ghz_channels)); 158 + sbands->band = IEEE80211_BAND_2GHZ; 159 + sbands->n_channels = ARRAY_SIZE(rsi_2ghz_channels); 160 + sbands->bitrates = rsi_rates; 161 + sbands->n_bitrates = ARRAY_SIZE(rsi_rates); 162 + } else { 163 + channels = kmalloc(sizeof(rsi_5ghz_channels), GFP_KERNEL); 164 + memcpy(channels, 165 + rsi_5ghz_channels, 166 + sizeof(rsi_5ghz_channels)); 167 + sbands->band = IEEE80211_BAND_5GHZ; 168 + sbands->n_channels = ARRAY_SIZE(rsi_5ghz_channels); 169 + sbands->bitrates = &rsi_rates[4]; 170 + sbands->n_bitrates = ARRAY_SIZE(rsi_rates) - 4; 171 + } 172 + 173 + sbands->channels = channels; 174 + 175 + memset(&sbands->ht_cap, 0, sizeof(struct ieee80211_sta_ht_cap)); 176 + sbands->ht_cap.ht_supported = true; 177 + sbands->ht_cap.cap = (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 178 + IEEE80211_HT_CAP_SGI_20 | 179 + IEEE80211_HT_CAP_SGI_40); 180 + sbands->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_8K; 181 + sbands->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE; 182 + sbands->ht_cap.mcs.rx_mask[0] = 0xff; 183 + sbands->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 184 + /* sbands->ht_cap.mcs.rx_highest = 0x82; */ 185 + } 186 + 187 + /** 188 + * rsi_mac80211_attach() - This function is used to de-initialize the 189 + * Mac80211 stack. 190 + * @adapter: Pointer to the adapter structure. 191 + * 192 + * Return: None. 193 + */ 194 + void rsi_mac80211_detach(struct rsi_hw *adapter) 195 + { 196 + struct ieee80211_hw *hw = adapter->hw; 197 + 198 + if (hw) { 199 + ieee80211_stop_queues(hw); 200 + ieee80211_unregister_hw(hw); 201 + ieee80211_free_hw(hw); 202 + } 203 + 204 + rsi_remove_dbgfs(adapter); 205 + } 206 + EXPORT_SYMBOL_GPL(rsi_mac80211_detach); 207 + 208 + /** 209 + * rsi_indicate_tx_status() - This function indicates the transmit status. 210 + * @adapter: Pointer to the adapter structure. 211 + * @skb: Pointer to the socket buffer structure. 212 + * @status: Status 213 + * 214 + * Return: None. 215 + */ 216 + void rsi_indicate_tx_status(struct rsi_hw *adapter, 217 + struct sk_buff *skb, 218 + int status) 219 + { 220 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 221 + 222 + memset(info->driver_data, 0, IEEE80211_TX_INFO_DRIVER_DATA_SIZE); 223 + 224 + if (!status) 225 + info->flags |= IEEE80211_TX_STAT_ACK; 226 + 227 + ieee80211_tx_status_irqsafe(adapter->hw, skb); 228 + } 229 + 230 + /** 231 + * rsi_mac80211_tx() - This is the handler that 802.11 module calls for each 232 + * transmitted frame.SKB contains the buffer starting 233 + * from the IEEE 802.11 header. 234 + * @hw: Pointer to the ieee80211_hw structure. 235 + * @control: Pointer to the ieee80211_tx_control structure 236 + * @skb: Pointer to the socket buffer structure. 237 + * 238 + * Return: None 239 + */ 240 + static void rsi_mac80211_tx(struct ieee80211_hw *hw, 241 + struct ieee80211_tx_control *control, 242 + struct sk_buff *skb) 243 + { 244 + struct rsi_hw *adapter = hw->priv; 245 + struct rsi_common *common = adapter->priv; 246 + 247 + rsi_core_xmit(common, skb); 248 + } 249 + 250 + /** 251 + * rsi_mac80211_start() - This is first handler that 802.11 module calls, since 252 + * the driver init is complete by then, just 253 + * returns success. 254 + * @hw: Pointer to the ieee80211_hw structure. 255 + * 256 + * Return: 0 as success. 257 + */ 258 + static int rsi_mac80211_start(struct ieee80211_hw *hw) 259 + { 260 + struct rsi_hw *adapter = hw->priv; 261 + struct rsi_common *common = adapter->priv; 262 + 263 + mutex_lock(&common->mutex); 264 + common->iface_down = false; 265 + mutex_unlock(&common->mutex); 266 + 267 + return 0; 268 + } 269 + 270 + /** 271 + * rsi_mac80211_stop() - This is the last handler that 802.11 module calls. 272 + * @hw: Pointer to the ieee80211_hw structure. 273 + * 274 + * Return: None. 275 + */ 276 + static void rsi_mac80211_stop(struct ieee80211_hw *hw) 277 + { 278 + struct rsi_hw *adapter = hw->priv; 279 + struct rsi_common *common = adapter->priv; 280 + 281 + mutex_lock(&common->mutex); 282 + common->iface_down = true; 283 + mutex_unlock(&common->mutex); 284 + } 285 + 286 + /** 287 + * rsi_mac80211_add_interface() - This function is called when a netdevice 288 + * attached to the hardware is enabled. 289 + * @hw: Pointer to the ieee80211_hw structure. 290 + * @vif: Pointer to the ieee80211_vif structure. 291 + * 292 + * Return: ret: 0 on success, negative error code on failure. 293 + */ 294 + static int rsi_mac80211_add_interface(struct ieee80211_hw *hw, 295 + struct ieee80211_vif *vif) 296 + { 297 + struct rsi_hw *adapter = hw->priv; 298 + struct rsi_common *common = adapter->priv; 299 + int ret = -EOPNOTSUPP; 300 + 301 + mutex_lock(&common->mutex); 302 + switch (vif->type) { 303 + case NL80211_IFTYPE_STATION: 304 + if (!adapter->sc_nvifs) { 305 + ++adapter->sc_nvifs; 306 + adapter->vifs[0] = vif; 307 + ret = rsi_set_vap_capabilities(common, STA_OPMODE); 308 + } 309 + break; 310 + default: 311 + rsi_dbg(ERR_ZONE, 312 + "%s: Interface type %d not supported\n", __func__, 313 + vif->type); 314 + } 315 + mutex_unlock(&common->mutex); 316 + 317 + return ret; 318 + } 319 + 320 + /** 321 + * rsi_mac80211_remove_interface() - This function notifies driver that an 322 + * interface is going down. 323 + * @hw: Pointer to the ieee80211_hw structure. 324 + * @vif: Pointer to the ieee80211_vif structure. 325 + * 326 + * Return: None. 327 + */ 328 + static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw, 329 + struct ieee80211_vif *vif) 330 + { 331 + struct rsi_hw *adapter = hw->priv; 332 + struct rsi_common *common = adapter->priv; 333 + 334 + mutex_lock(&common->mutex); 335 + if (vif->type == NL80211_IFTYPE_STATION) 336 + adapter->sc_nvifs--; 337 + 338 + if (!memcmp(adapter->vifs[0], vif, sizeof(struct ieee80211_vif))) 339 + adapter->vifs[0] = NULL; 340 + mutex_unlock(&common->mutex); 341 + } 342 + 343 + /** 344 + * rsi_mac80211_config() - This function is a handler for configuration 345 + * requests. The stack calls this function to 346 + * change hardware configuration, e.g., channel. 347 + * @hw: Pointer to the ieee80211_hw structure. 348 + * @changed: Changed flags set. 349 + * 350 + * Return: 0 on success, negative error code on failure. 351 + */ 352 + static int rsi_mac80211_config(struct ieee80211_hw *hw, 353 + u32 changed) 354 + { 355 + struct rsi_hw *adapter = hw->priv; 356 + struct rsi_common *common = adapter->priv; 357 + int status = -EOPNOTSUPP; 358 + 359 + mutex_lock(&common->mutex); 360 + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 361 + struct ieee80211_channel *curchan = hw->conf.chandef.chan; 362 + u16 channel = curchan->hw_value; 363 + 364 + rsi_dbg(INFO_ZONE, 365 + "%s: Set channel: %d MHz type: %d channel_no %d\n", 366 + __func__, curchan->center_freq, 367 + curchan->flags, channel); 368 + common->band = curchan->band; 369 + status = rsi_set_channel(adapter->priv, channel); 370 + } 371 + mutex_unlock(&common->mutex); 372 + 373 + return status; 374 + } 375 + 376 + /** 377 + * rsi_get_connected_channel() - This function is used to get the current 378 + * connected channel number. 379 + * @adapter: Pointer to the adapter structure. 380 + * 381 + * Return: Current connected AP's channel number is returned. 382 + */ 383 + u16 rsi_get_connected_channel(struct rsi_hw *adapter) 384 + { 385 + struct ieee80211_vif *vif = adapter->vifs[0]; 386 + if (vif) { 387 + struct ieee80211_bss_conf *bss = &vif->bss_conf; 388 + struct ieee80211_channel *channel = bss->chandef.chan; 389 + return channel->hw_value; 390 + } 391 + 392 + return 0; 393 + } 394 + 395 + /** 396 + * rsi_mac80211_bss_info_changed() - This function is a handler for config 397 + * requests related to BSS parameters that 398 + * may vary during BSS's lifespan. 399 + * @hw: Pointer to the ieee80211_hw structure. 400 + * @vif: Pointer to the ieee80211_vif structure. 401 + * @bss_conf: Pointer to the ieee80211_bss_conf structure. 402 + * @changed: Changed flags set. 403 + * 404 + * Return: None. 405 + */ 406 + static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw, 407 + struct ieee80211_vif *vif, 408 + struct ieee80211_bss_conf *bss_conf, 409 + u32 changed) 410 + { 411 + struct rsi_hw *adapter = hw->priv; 412 + struct rsi_common *common = adapter->priv; 413 + 414 + mutex_lock(&common->mutex); 415 + if (changed & BSS_CHANGED_ASSOC) { 416 + rsi_dbg(INFO_ZONE, "%s: Changed Association status: %d\n", 417 + __func__, bss_conf->assoc); 418 + rsi_inform_bss_status(common, 419 + bss_conf->assoc, 420 + bss_conf->bssid, 421 + bss_conf->qos, 422 + bss_conf->aid); 423 + } 424 + mutex_unlock(&common->mutex); 425 + } 426 + 427 + /** 428 + * rsi_mac80211_conf_filter() - This function configure the device's RX filter. 429 + * @hw: Pointer to the ieee80211_hw structure. 430 + * @changed: Changed flags set. 431 + * @total_flags: Total initial flags set. 432 + * @multicast: Multicast. 433 + * 434 + * Return: None. 435 + */ 436 + static void rsi_mac80211_conf_filter(struct ieee80211_hw *hw, 437 + u32 changed_flags, 438 + u32 *total_flags, 439 + u64 multicast) 440 + { 441 + /* Not doing much here as of now */ 442 + *total_flags &= RSI_SUPP_FILTERS; 443 + } 444 + 445 + /** 446 + * rsi_mac80211_conf_tx() - This function configures TX queue parameters 447 + * (EDCF (aifs, cw_min, cw_max), bursting) 448 + * for a hardware TX queue. 449 + * @hw: Pointer to the ieee80211_hw structure 450 + * @vif: Pointer to the ieee80211_vif structure. 451 + * @queue: Queue number. 452 + * @params: Pointer to ieee80211_tx_queue_params structure. 453 + * 454 + * Return: 0 on success, negative error code on failure. 455 + */ 456 + static int rsi_mac80211_conf_tx(struct ieee80211_hw *hw, 457 + struct ieee80211_vif *vif, u16 queue, 458 + const struct ieee80211_tx_queue_params *params) 459 + { 460 + struct rsi_hw *adapter = hw->priv; 461 + struct rsi_common *common = adapter->priv; 462 + u8 idx = 0; 463 + 464 + if (queue >= IEEE80211_NUM_ACS) 465 + return 0; 466 + 467 + rsi_dbg(INFO_ZONE, 468 + "%s: Conf queue %d, aifs: %d, cwmin: %d cwmax: %d, txop: %d\n", 469 + __func__, queue, params->aifs, 470 + params->cw_min, params->cw_max, params->txop); 471 + 472 + mutex_lock(&common->mutex); 473 + /* Map into the way the f/w expects */ 474 + switch (queue) { 475 + case IEEE80211_AC_VO: 476 + idx = VO_Q; 477 + break; 478 + case IEEE80211_AC_VI: 479 + idx = VI_Q; 480 + break; 481 + case IEEE80211_AC_BE: 482 + idx = BE_Q; 483 + break; 484 + case IEEE80211_AC_BK: 485 + idx = BK_Q; 486 + break; 487 + default: 488 + idx = BE_Q; 489 + break; 490 + } 491 + 492 + memcpy(&common->edca_params[idx], 493 + params, 494 + sizeof(struct ieee80211_tx_queue_params)); 495 + mutex_unlock(&common->mutex); 496 + 497 + return 0; 498 + } 499 + 500 + /** 501 + * rsi_hal_key_config() - This function loads the keys into the firmware. 502 + * @hw: Pointer to the ieee80211_hw structure. 503 + * @vif: Pointer to the ieee80211_vif structure. 504 + * @key: Pointer to the ieee80211_key_conf structure. 505 + * 506 + * Return: status: 0 on success, -1 on failure. 507 + */ 508 + static int rsi_hal_key_config(struct ieee80211_hw *hw, 509 + struct ieee80211_vif *vif, 510 + struct ieee80211_key_conf *key) 511 + { 512 + struct rsi_hw *adapter = hw->priv; 513 + int status; 514 + u8 key_type; 515 + 516 + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 517 + key_type = RSI_PAIRWISE_KEY; 518 + else 519 + key_type = RSI_GROUP_KEY; 520 + 521 + rsi_dbg(ERR_ZONE, "%s: Cipher 0x%x key_type: %d key_len: %d\n", 522 + __func__, key->cipher, key_type, key->keylen); 523 + 524 + if ((key->cipher == WLAN_CIPHER_SUITE_WEP104) || 525 + (key->cipher == WLAN_CIPHER_SUITE_WEP40)) { 526 + status = rsi_hal_load_key(adapter->priv, 527 + key->key, 528 + key->keylen, 529 + RSI_PAIRWISE_KEY, 530 + key->keyidx, 531 + key->cipher); 532 + if (status) 533 + return status; 534 + } 535 + return rsi_hal_load_key(adapter->priv, 536 + key->key, 537 + key->keylen, 538 + key_type, 539 + key->keyidx, 540 + key->cipher); 541 + } 542 + 543 + /** 544 + * rsi_mac80211_set_key() - This function sets type of key to be loaded. 545 + * @hw: Pointer to the ieee80211_hw structure. 546 + * @cmd: enum set_key_cmd. 547 + * @vif: Pointer to the ieee80211_vif structure. 548 + * @sta: Pointer to the ieee80211_sta structure. 549 + * @key: Pointer to the ieee80211_key_conf structure. 550 + * 551 + * Return: status: 0 on success, negative error code on failure. 552 + */ 553 + static int rsi_mac80211_set_key(struct ieee80211_hw *hw, 554 + enum set_key_cmd cmd, 555 + struct ieee80211_vif *vif, 556 + struct ieee80211_sta *sta, 557 + struct ieee80211_key_conf *key) 558 + { 559 + struct rsi_hw *adapter = hw->priv; 560 + struct rsi_common *common = adapter->priv; 561 + struct security_info *secinfo = &common->secinfo; 562 + int status; 563 + 564 + mutex_lock(&common->mutex); 565 + switch (cmd) { 566 + case SET_KEY: 567 + secinfo->security_enable = true; 568 + status = rsi_hal_key_config(hw, vif, key); 569 + if (status) { 570 + mutex_unlock(&common->mutex); 571 + return status; 572 + } 573 + 574 + if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) 575 + secinfo->ptk_cipher = key->cipher; 576 + else 577 + secinfo->gtk_cipher = key->cipher; 578 + 579 + key->hw_key_idx = key->keyidx; 580 + key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 581 + 582 + rsi_dbg(ERR_ZONE, "%s: RSI set_key\n", __func__); 583 + break; 584 + 585 + case DISABLE_KEY: 586 + secinfo->security_enable = false; 587 + rsi_dbg(ERR_ZONE, "%s: RSI del key\n", __func__); 588 + memset(key, 0, sizeof(struct ieee80211_key_conf)); 589 + status = rsi_hal_key_config(hw, vif, key); 590 + break; 591 + 592 + default: 593 + status = -EOPNOTSUPP; 594 + break; 595 + } 596 + 597 + mutex_unlock(&common->mutex); 598 + return status; 599 + } 600 + 601 + /** 602 + * rsi_mac80211_ampdu_action() - This function selects the AMPDU action for 603 + * the corresponding mlme_action flag and 604 + * informs the f/w regarding this. 605 + * @hw: Pointer to the ieee80211_hw structure. 606 + * @vif: Pointer to the ieee80211_vif structure. 607 + * @action: ieee80211_ampdu_mlme_action enum. 608 + * @sta: Pointer to the ieee80211_sta structure. 609 + * @tid: Traffic identifier. 610 + * @ssn: Pointer to ssn value. 611 + * @buf_size: Buffer size (for kernel version > 2.6.38). 612 + * 613 + * Return: status: 0 on success, negative error code on failure. 614 + */ 615 + static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw, 616 + struct ieee80211_vif *vif, 617 + enum ieee80211_ampdu_mlme_action action, 618 + struct ieee80211_sta *sta, 619 + unsigned short tid, 620 + unsigned short *ssn, 621 + unsigned char buf_size) 622 + { 623 + int status = -EOPNOTSUPP; 624 + struct rsi_hw *adapter = hw->priv; 625 + struct rsi_common *common = adapter->priv; 626 + u16 seq_no = 0; 627 + u8 ii = 0; 628 + 629 + for (ii = 0; ii < RSI_MAX_VIFS; ii++) { 630 + if (vif == adapter->vifs[ii]) 631 + break; 632 + } 633 + 634 + mutex_lock(&common->mutex); 635 + rsi_dbg(INFO_ZONE, "%s: AMPDU action %d called\n", __func__, action); 636 + if (ssn != NULL) 637 + seq_no = *ssn; 638 + 639 + switch (action) { 640 + case IEEE80211_AMPDU_RX_START: 641 + status = rsi_send_aggregation_params_frame(common, 642 + tid, 643 + seq_no, 644 + buf_size, 645 + STA_RX_ADDBA_DONE); 646 + break; 647 + 648 + case IEEE80211_AMPDU_RX_STOP: 649 + status = rsi_send_aggregation_params_frame(common, 650 + tid, 651 + 0, 652 + buf_size, 653 + STA_RX_DELBA); 654 + break; 655 + 656 + case IEEE80211_AMPDU_TX_START: 657 + common->vif_info[ii].seq_start = seq_no; 658 + ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 659 + break; 660 + 661 + case IEEE80211_AMPDU_TX_STOP_CONT: 662 + case IEEE80211_AMPDU_TX_STOP_FLUSH: 663 + case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: 664 + status = rsi_send_aggregation_params_frame(common, 665 + tid, 666 + seq_no, 667 + buf_size, 668 + STA_TX_DELBA); 669 + if (!status) 670 + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 671 + break; 672 + 673 + case IEEE80211_AMPDU_TX_OPERATIONAL: 674 + status = rsi_send_aggregation_params_frame(common, 675 + tid, 676 + common->vif_info[ii] 677 + .seq_start, 678 + buf_size, 679 + STA_TX_ADDBA_DONE); 680 + break; 681 + 682 + default: 683 + rsi_dbg(ERR_ZONE, "%s: Uknown AMPDU action\n", __func__); 684 + break; 685 + } 686 + 687 + mutex_unlock(&common->mutex); 688 + return status; 689 + } 690 + 691 + /** 692 + * rsi_mac80211_set_rts_threshold() - This function sets rts threshold value. 693 + * @hw: Pointer to the ieee80211_hw structure. 694 + * @value: Rts threshold value. 695 + * 696 + * Return: 0 on success. 697 + */ 698 + static int rsi_mac80211_set_rts_threshold(struct ieee80211_hw *hw, 699 + u32 value) 700 + { 701 + struct rsi_hw *adapter = hw->priv; 702 + struct rsi_common *common = adapter->priv; 703 + 704 + mutex_lock(&common->mutex); 705 + common->rts_threshold = value; 706 + mutex_unlock(&common->mutex); 707 + 708 + return 0; 709 + } 710 + 711 + /** 712 + * rsi_mac80211_set_rate_mask() - This function sets bitrate_mask to be used. 713 + * @hw: Pointer to the ieee80211_hw structure 714 + * @vif: Pointer to the ieee80211_vif structure. 715 + * @mask: Pointer to the cfg80211_bitrate_mask structure. 716 + * 717 + * Return: 0 on success. 718 + */ 719 + static int rsi_mac80211_set_rate_mask(struct ieee80211_hw *hw, 720 + struct ieee80211_vif *vif, 721 + const struct cfg80211_bitrate_mask *mask) 722 + { 723 + struct rsi_hw *adapter = hw->priv; 724 + struct rsi_common *common = adapter->priv; 725 + 726 + mutex_lock(&common->mutex); 727 + 728 + common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 0; 729 + 730 + if (mask->control[IEEE80211_BAND_2GHZ].legacy == 0xfff) { 731 + common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 732 + (mask->control[IEEE80211_BAND_2GHZ].ht_mcs[0] << 12); 733 + } else { 734 + common->fixedrate_mask[IEEE80211_BAND_2GHZ] = 735 + mask->control[IEEE80211_BAND_2GHZ].legacy; 736 + } 737 + mutex_unlock(&common->mutex); 738 + 739 + return 0; 740 + } 741 + 742 + /** 743 + * rsi_fill_rx_status() - This function fills rx status in 744 + * ieee80211_rx_status structure. 745 + * @hw: Pointer to the ieee80211_hw structure. 746 + * @skb: Pointer to the socket buffer structure. 747 + * @common: Pointer to the driver private structure. 748 + * @rxs: Pointer to the ieee80211_rx_status structure. 749 + * 750 + * Return: None. 751 + */ 752 + static void rsi_fill_rx_status(struct ieee80211_hw *hw, 753 + struct sk_buff *skb, 754 + struct rsi_common *common, 755 + struct ieee80211_rx_status *rxs) 756 + { 757 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 758 + struct skb_info *rx_params = (struct skb_info *)info->driver_data; 759 + struct ieee80211_hdr *hdr; 760 + char rssi = rx_params->rssi; 761 + u8 hdrlen = 0; 762 + u8 channel = rx_params->channel; 763 + s32 freq; 764 + 765 + hdr = ((struct ieee80211_hdr *)(skb->data)); 766 + hdrlen = ieee80211_hdrlen(hdr->frame_control); 767 + 768 + memset(info, 0, sizeof(struct ieee80211_tx_info)); 769 + 770 + rxs->signal = -(rssi); 771 + 772 + if (channel <= 14) 773 + rxs->band = IEEE80211_BAND_2GHZ; 774 + else 775 + rxs->band = IEEE80211_BAND_5GHZ; 776 + 777 + freq = ieee80211_channel_to_frequency(channel, rxs->band); 778 + 779 + if (freq) 780 + rxs->freq = freq; 781 + 782 + if (ieee80211_has_protected(hdr->frame_control)) { 783 + if (rsi_is_cipher_wep(common)) { 784 + memmove(skb->data + 4, skb->data, hdrlen); 785 + skb_pull(skb, 4); 786 + } else { 787 + memmove(skb->data + 8, skb->data, hdrlen); 788 + skb_pull(skb, 8); 789 + rxs->flag |= RX_FLAG_MMIC_STRIPPED; 790 + } 791 + rxs->flag |= RX_FLAG_DECRYPTED; 792 + rxs->flag |= RX_FLAG_IV_STRIPPED; 793 + } 794 + } 795 + 796 + /** 797 + * rsi_indicate_pkt_to_os() - This function sends recieved packet to mac80211. 798 + * @common: Pointer to the driver private structure. 799 + * @skb: Pointer to the socket buffer structure. 800 + * 801 + * Return: None. 802 + */ 803 + void rsi_indicate_pkt_to_os(struct rsi_common *common, 804 + struct sk_buff *skb) 805 + { 806 + struct rsi_hw *adapter = common->priv; 807 + struct ieee80211_hw *hw = adapter->hw; 808 + struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); 809 + 810 + if ((common->iface_down) || (!adapter->sc_nvifs)) { 811 + dev_kfree_skb(skb); 812 + return; 813 + } 814 + 815 + /* filling in the ieee80211_rx_status flags */ 816 + rsi_fill_rx_status(hw, skb, common, rx_status); 817 + 818 + ieee80211_rx_irqsafe(hw, skb); 819 + } 820 + 821 + static void rsi_set_min_rate(struct ieee80211_hw *hw, 822 + struct ieee80211_sta *sta, 823 + struct rsi_common *common) 824 + { 825 + u8 band = hw->conf.chandef.chan->band; 826 + u8 ii; 827 + u32 rate_bitmap; 828 + bool matched = false; 829 + 830 + common->bitrate_mask[band] = sta->supp_rates[band]; 831 + 832 + rate_bitmap = (common->fixedrate_mask[band] & sta->supp_rates[band]); 833 + 834 + if (rate_bitmap & 0xfff) { 835 + /* Find out the min rate */ 836 + for (ii = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { 837 + if (rate_bitmap & BIT(ii)) { 838 + common->min_rate = rsi_rates[ii].hw_value; 839 + matched = true; 840 + break; 841 + } 842 + } 843 + } 844 + 845 + common->vif_info[0].is_ht = sta->ht_cap.ht_supported; 846 + 847 + if ((common->vif_info[0].is_ht) && (rate_bitmap >> 12)) { 848 + for (ii = 0; ii < ARRAY_SIZE(rsi_mcsrates); ii++) { 849 + if ((rate_bitmap >> 12) & BIT(ii)) { 850 + common->min_rate = rsi_mcsrates[ii]; 851 + matched = true; 852 + break; 853 + } 854 + } 855 + } 856 + 857 + if (!matched) 858 + common->min_rate = 0xffff; 859 + } 860 + 861 + /** 862 + * rsi_mac80211_sta_add() - This function notifies driver about a peer getting 863 + * connected. 864 + * @hw: pointer to the ieee80211_hw structure. 865 + * @vif: Pointer to the ieee80211_vif structure. 866 + * @sta: Pointer to the ieee80211_sta structure. 867 + * 868 + * Return: 0 on success, -1 on failure. 869 + */ 870 + static int rsi_mac80211_sta_add(struct ieee80211_hw *hw, 871 + struct ieee80211_vif *vif, 872 + struct ieee80211_sta *sta) 873 + { 874 + struct rsi_hw *adapter = hw->priv; 875 + struct rsi_common *common = adapter->priv; 876 + 877 + mutex_lock(&common->mutex); 878 + 879 + rsi_set_min_rate(hw, sta, common); 880 + 881 + if ((sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) || 882 + (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40)) { 883 + common->vif_info[0].sgi = true; 884 + } 885 + 886 + if (sta->ht_cap.ht_supported) 887 + ieee80211_start_tx_ba_session(sta, 0, 0); 888 + 889 + mutex_unlock(&common->mutex); 890 + 891 + return 0; 892 + } 893 + 894 + /** 895 + * rsi_mac80211_sta_remove() - This function notifies driver about a peer 896 + * getting disconnected. 897 + * @hw: Pointer to the ieee80211_hw structure. 898 + * @vif: Pointer to the ieee80211_vif structure. 899 + * @sta: Pointer to the ieee80211_sta structure. 900 + * 901 + * Return: 0 on success, -1 on failure. 902 + */ 903 + static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw, 904 + struct ieee80211_vif *vif, 905 + struct ieee80211_sta *sta) 906 + { 907 + struct rsi_hw *adapter = hw->priv; 908 + struct rsi_common *common = adapter->priv; 909 + 910 + mutex_lock(&common->mutex); 911 + /* Resetting all the fields to default values */ 912 + common->bitrate_mask[IEEE80211_BAND_2GHZ] = 0; 913 + common->bitrate_mask[IEEE80211_BAND_5GHZ] = 0; 914 + common->min_rate = 0xffff; 915 + common->vif_info[0].is_ht = false; 916 + common->vif_info[0].sgi = false; 917 + common->vif_info[0].seq_start = 0; 918 + common->secinfo.ptk_cipher = 0; 919 + common->secinfo.gtk_cipher = 0; 920 + mutex_unlock(&common->mutex); 921 + 922 + return 0; 923 + } 924 + 925 + static struct ieee80211_ops mac80211_ops = { 926 + .tx = rsi_mac80211_tx, 927 + .start = rsi_mac80211_start, 928 + .stop = rsi_mac80211_stop, 929 + .add_interface = rsi_mac80211_add_interface, 930 + .remove_interface = rsi_mac80211_remove_interface, 931 + .config = rsi_mac80211_config, 932 + .bss_info_changed = rsi_mac80211_bss_info_changed, 933 + .conf_tx = rsi_mac80211_conf_tx, 934 + .configure_filter = rsi_mac80211_conf_filter, 935 + .set_key = rsi_mac80211_set_key, 936 + .set_rts_threshold = rsi_mac80211_set_rts_threshold, 937 + .set_bitrate_mask = rsi_mac80211_set_rate_mask, 938 + .ampdu_action = rsi_mac80211_ampdu_action, 939 + .sta_add = rsi_mac80211_sta_add, 940 + .sta_remove = rsi_mac80211_sta_remove, 941 + }; 942 + 943 + /** 944 + * rsi_mac80211_attach() - This function is used to initialize Mac80211 stack. 945 + * @common: Pointer to the driver private structure. 946 + * 947 + * Return: 0 on success, -1 on failure. 948 + */ 949 + int rsi_mac80211_attach(struct rsi_common *common) 950 + { 951 + int status = 0; 952 + struct ieee80211_hw *hw = NULL; 953 + struct wiphy *wiphy = NULL; 954 + struct rsi_hw *adapter = common->priv; 955 + u8 addr_mask[ETH_ALEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x3}; 956 + 957 + rsi_dbg(INIT_ZONE, "%s: Performing mac80211 attach\n", __func__); 958 + 959 + hw = ieee80211_alloc_hw(sizeof(struct rsi_hw), &mac80211_ops); 960 + if (!hw) { 961 + rsi_dbg(ERR_ZONE, "%s: ieee80211 hw alloc failed\n", __func__); 962 + return -ENOMEM; 963 + } 964 + 965 + wiphy = hw->wiphy; 966 + 967 + SET_IEEE80211_DEV(hw, adapter->device); 968 + 969 + hw->priv = adapter; 970 + adapter->hw = hw; 971 + 972 + hw->flags = IEEE80211_HW_SIGNAL_DBM | 973 + IEEE80211_HW_HAS_RATE_CONTROL | 974 + IEEE80211_HW_AMPDU_AGGREGATION | 975 + 0; 976 + 977 + hw->queues = MAX_HW_QUEUES; 978 + hw->extra_tx_headroom = RSI_NEEDED_HEADROOM; 979 + 980 + hw->max_rates = 1; 981 + hw->max_rate_tries = MAX_RETRIES; 982 + 983 + hw->max_tx_aggregation_subframes = 6; 984 + rsi_register_rates_channels(adapter, IEEE80211_BAND_2GHZ); 985 + hw->rate_control_algorithm = "AARF"; 986 + 987 + SET_IEEE80211_PERM_ADDR(hw, common->mac_addr); 988 + ether_addr_copy(hw->wiphy->addr_mask, addr_mask); 989 + 990 + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 991 + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 992 + wiphy->retry_short = RETRY_SHORT; 993 + wiphy->retry_long = RETRY_LONG; 994 + wiphy->frag_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 995 + wiphy->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 996 + wiphy->flags = 0; 997 + 998 + wiphy->available_antennas_rx = 1; 999 + wiphy->available_antennas_tx = 1; 1000 + wiphy->bands[IEEE80211_BAND_2GHZ] = 1001 + &adapter->sbands[IEEE80211_BAND_2GHZ]; 1002 + 1003 + status = ieee80211_register_hw(hw); 1004 + if (status) 1005 + return status; 1006 + 1007 + return rsi_init_dbgfs(adapter); 1008 + }
+270
drivers/net/wireless/rsi/rsi_91x_main.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include <linux/module.h> 18 + #include <linux/firmware.h> 19 + #include "rsi_mgmt.h" 20 + #include "rsi_common.h" 21 + 22 + u32 rsi_zone_enabled = /* INFO_ZONE | 23 + INIT_ZONE | 24 + MGMT_TX_ZONE | 25 + MGMT_RX_ZONE | 26 + DATA_TX_ZONE | 27 + DATA_RX_ZONE | 28 + FSM_ZONE | 29 + ISR_ZONE | */ 30 + ERR_ZONE | 31 + 0; 32 + EXPORT_SYMBOL_GPL(rsi_zone_enabled); 33 + 34 + /** 35 + * rsi_prepare_skb() - This function prepares the skb. 36 + * @common: Pointer to the driver private structure. 37 + * @buffer: Pointer to the packet data. 38 + * @pkt_len: Length of the packet. 39 + * @extended_desc: Extended descriptor. 40 + * 41 + * Return: Successfully skb. 42 + */ 43 + static struct sk_buff *rsi_prepare_skb(struct rsi_common *common, 44 + u8 *buffer, 45 + u32 pkt_len, 46 + u8 extended_desc) 47 + { 48 + struct ieee80211_tx_info *info; 49 + struct skb_info *rx_params; 50 + struct sk_buff *skb = NULL; 51 + u8 payload_offset; 52 + 53 + if (WARN(!pkt_len, "%s: Dummy pkt received", __func__)) 54 + return NULL; 55 + 56 + if (pkt_len > (RSI_RCV_BUFFER_LEN * 4)) { 57 + rsi_dbg(ERR_ZONE, "%s: Pkt size > max rx buf size %d\n", 58 + __func__, pkt_len); 59 + pkt_len = RSI_RCV_BUFFER_LEN * 4; 60 + } 61 + 62 + pkt_len -= extended_desc; 63 + skb = dev_alloc_skb(pkt_len + FRAME_DESC_SZ); 64 + if (skb == NULL) 65 + return NULL; 66 + 67 + payload_offset = (extended_desc + FRAME_DESC_SZ); 68 + skb_put(skb, pkt_len); 69 + memcpy((skb->data), (buffer + payload_offset), skb->len); 70 + 71 + info = IEEE80211_SKB_CB(skb); 72 + rx_params = (struct skb_info *)info->driver_data; 73 + rx_params->rssi = rsi_get_rssi(buffer); 74 + rx_params->channel = rsi_get_connected_channel(common->priv); 75 + 76 + return skb; 77 + } 78 + 79 + /** 80 + * rsi_read_pkt() - This function reads frames from the card. 81 + * @common: Pointer to the driver private structure. 82 + * @rcv_pkt_len: Received pkt length. In case of USB it is 0. 83 + * 84 + * Return: 0 on success, -1 on failure. 85 + */ 86 + int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len) 87 + { 88 + u8 *frame_desc = NULL, extended_desc = 0; 89 + u32 index, length = 0, queueno = 0; 90 + u16 actual_length = 0, offset; 91 + struct sk_buff *skb = NULL; 92 + 93 + index = 0; 94 + do { 95 + frame_desc = &common->rx_data_pkt[index]; 96 + actual_length = *(u16 *)&frame_desc[0]; 97 + offset = *(u16 *)&frame_desc[2]; 98 + 99 + queueno = rsi_get_queueno(frame_desc, offset); 100 + length = rsi_get_length(frame_desc, offset); 101 + extended_desc = rsi_get_extended_desc(frame_desc, offset); 102 + 103 + switch (queueno) { 104 + case RSI_WIFI_DATA_Q: 105 + skb = rsi_prepare_skb(common, 106 + (frame_desc + offset), 107 + length, 108 + extended_desc); 109 + if (skb == NULL) 110 + goto fail; 111 + 112 + rsi_indicate_pkt_to_os(common, skb); 113 + break; 114 + 115 + case RSI_WIFI_MGMT_Q: 116 + rsi_mgmt_pkt_recv(common, (frame_desc + offset)); 117 + break; 118 + 119 + default: 120 + rsi_dbg(ERR_ZONE, "%s: pkt from invalid queue: %d\n", 121 + __func__, queueno); 122 + goto fail; 123 + } 124 + 125 + index += actual_length; 126 + rcv_pkt_len -= actual_length; 127 + } while (rcv_pkt_len > 0); 128 + 129 + return 0; 130 + fail: 131 + return -EINVAL; 132 + } 133 + EXPORT_SYMBOL_GPL(rsi_read_pkt); 134 + 135 + /** 136 + * rsi_tx_scheduler_thread() - This function is a kernel thread to send the 137 + * packets to the device. 138 + * @common: Pointer to the driver private structure. 139 + * 140 + * Return: None. 141 + */ 142 + static void rsi_tx_scheduler_thread(struct rsi_common *common) 143 + { 144 + struct rsi_hw *adapter = common->priv; 145 + u32 timeout = EVENT_WAIT_FOREVER; 146 + 147 + do { 148 + if (adapter->determine_event_timeout) 149 + timeout = adapter->determine_event_timeout(adapter); 150 + rsi_wait_event(&common->tx_thread.event, timeout); 151 + rsi_reset_event(&common->tx_thread.event); 152 + 153 + if (common->init_done) 154 + rsi_core_qos_processor(common); 155 + } while (atomic_read(&common->tx_thread.thread_done) == 0); 156 + complete_and_exit(&common->tx_thread.completion, 0); 157 + } 158 + 159 + /** 160 + * rsi_91x_init() - This function initializes os interface operations. 161 + * @void: Void. 162 + * 163 + * Return: Pointer to the adapter structure on success, NULL on failure . 164 + */ 165 + struct rsi_hw *rsi_91x_init(void) 166 + { 167 + struct rsi_hw *adapter = NULL; 168 + struct rsi_common *common = NULL; 169 + u8 ii = 0; 170 + 171 + adapter = kzalloc(sizeof(*adapter), GFP_KERNEL); 172 + if (!adapter) 173 + return NULL; 174 + 175 + adapter->priv = kzalloc(sizeof(*common), GFP_KERNEL); 176 + if (adapter->priv == NULL) { 177 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of memory\n", 178 + __func__); 179 + kfree(adapter); 180 + return NULL; 181 + } else { 182 + common = adapter->priv; 183 + common->priv = adapter; 184 + } 185 + 186 + for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) 187 + skb_queue_head_init(&common->tx_queue[ii]); 188 + 189 + rsi_init_event(&common->tx_thread.event); 190 + mutex_init(&common->mutex); 191 + mutex_init(&common->tx_rxlock); 192 + 193 + if (rsi_create_kthread(common, 194 + &common->tx_thread, 195 + rsi_tx_scheduler_thread, 196 + "Tx-Thread")) { 197 + rsi_dbg(ERR_ZONE, "%s: Unable to init tx thrd\n", __func__); 198 + goto err; 199 + } 200 + 201 + common->init_done = true; 202 + return adapter; 203 + 204 + err: 205 + kfree(common); 206 + kfree(adapter); 207 + return NULL; 208 + } 209 + EXPORT_SYMBOL_GPL(rsi_91x_init); 210 + 211 + /** 212 + * rsi_91x_deinit() - This function de-intializes os intf operations. 213 + * @adapter: Pointer to the adapter structure. 214 + * 215 + * Return: None. 216 + */ 217 + void rsi_91x_deinit(struct rsi_hw *adapter) 218 + { 219 + struct rsi_common *common = adapter->priv; 220 + u8 ii; 221 + 222 + rsi_dbg(INFO_ZONE, "%s: Performing deinit os ops\n", __func__); 223 + 224 + rsi_kill_thread(&common->tx_thread); 225 + 226 + for (ii = 0; ii < NUM_SOFT_QUEUES; ii++) 227 + skb_queue_purge(&common->tx_queue[ii]); 228 + 229 + common->init_done = false; 230 + 231 + kfree(common); 232 + kfree(adapter->rsi_dev); 233 + kfree(adapter); 234 + } 235 + EXPORT_SYMBOL_GPL(rsi_91x_deinit); 236 + 237 + /** 238 + * rsi_91x_hal_module_init() - This function is invoked when the module is 239 + * loaded into the kernel. 240 + * It registers the client driver. 241 + * @void: Void. 242 + * 243 + * Return: 0 on success, -1 on failure. 244 + */ 245 + static int rsi_91x_hal_module_init(void) 246 + { 247 + rsi_dbg(INIT_ZONE, "%s: Module init called\n", __func__); 248 + return 0; 249 + } 250 + 251 + /** 252 + * rsi_91x_hal_module_exit() - This function is called at the time of 253 + * removing/unloading the module. 254 + * It unregisters the client driver. 255 + * @void: Void. 256 + * 257 + * Return: None. 258 + */ 259 + static void rsi_91x_hal_module_exit(void) 260 + { 261 + rsi_dbg(INIT_ZONE, "%s: Module exit called\n", __func__); 262 + } 263 + 264 + module_init(rsi_91x_hal_module_init); 265 + module_exit(rsi_91x_hal_module_exit); 266 + MODULE_AUTHOR("Redpine Signals Inc"); 267 + MODULE_DESCRIPTION("Station driver for RSI 91x devices"); 268 + MODULE_SUPPORTED_DEVICE("RSI-91x"); 269 + MODULE_VERSION("0.1"); 270 + MODULE_LICENSE("Dual BSD/GPL");
+1302
drivers/net/wireless/rsi/rsi_91x_mgmt.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include <linux/etherdevice.h> 18 + #include "rsi_mgmt.h" 19 + #include "rsi_common.h" 20 + 21 + static struct bootup_params boot_params_20 = { 22 + .magic_number = cpu_to_le16(0x5aa5), 23 + .crystal_good_time = 0x0, 24 + .valid = cpu_to_le32(VALID_20), 25 + .reserved_for_valids = 0x0, 26 + .bootup_mode_info = 0x0, 27 + .digital_loop_back_params = 0x0, 28 + .rtls_timestamp_en = 0x0, 29 + .host_spi_intr_cfg = 0x0, 30 + .device_clk_info = {{ 31 + .pll_config_g = { 32 + .tapll_info_g = { 33 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)| 34 + (TA_PLL_M_VAL_20)), 35 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20), 36 + }, 37 + .pll960_info_g = { 38 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)| 39 + (PLL960_N_VAL_20)), 40 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20), 41 + .pll_reg_3 = 0x0, 42 + }, 43 + .afepll_info_g = { 44 + .pll_reg = cpu_to_le16(0x9f0), 45 + } 46 + }, 47 + .switch_clk_g = { 48 + .switch_clk_info = cpu_to_le16(BIT(3)), 49 + .bbp_lmac_clk_reg_val = cpu_to_le16(0x121), 50 + .umac_clock_reg_config = 0x0, 51 + .qspi_uart_clock_reg_config = 0x0 52 + } 53 + }, 54 + { 55 + .pll_config_g = { 56 + .tapll_info_g = { 57 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)| 58 + (TA_PLL_M_VAL_20)), 59 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20), 60 + }, 61 + .pll960_info_g = { 62 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)| 63 + (PLL960_N_VAL_20)), 64 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20), 65 + .pll_reg_3 = 0x0, 66 + }, 67 + .afepll_info_g = { 68 + .pll_reg = cpu_to_le16(0x9f0), 69 + } 70 + }, 71 + .switch_clk_g = { 72 + .switch_clk_info = 0x0, 73 + .bbp_lmac_clk_reg_val = 0x0, 74 + .umac_clock_reg_config = 0x0, 75 + .qspi_uart_clock_reg_config = 0x0 76 + } 77 + }, 78 + { 79 + .pll_config_g = { 80 + .tapll_info_g = { 81 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_20 << 8)| 82 + (TA_PLL_M_VAL_20)), 83 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_20), 84 + }, 85 + .pll960_info_g = { 86 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_20 << 8)| 87 + (PLL960_N_VAL_20)), 88 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_20), 89 + .pll_reg_3 = 0x0, 90 + }, 91 + .afepll_info_g = { 92 + .pll_reg = cpu_to_le16(0x9f0), 93 + } 94 + }, 95 + .switch_clk_g = { 96 + .switch_clk_info = 0x0, 97 + .bbp_lmac_clk_reg_val = 0x0, 98 + .umac_clock_reg_config = 0x0, 99 + .qspi_uart_clock_reg_config = 0x0 100 + } 101 + } }, 102 + .buckboost_wakeup_cnt = 0x0, 103 + .pmu_wakeup_wait = 0x0, 104 + .shutdown_wait_time = 0x0, 105 + .pmu_slp_clkout_sel = 0x0, 106 + .wdt_prog_value = 0x0, 107 + .wdt_soc_rst_delay = 0x0, 108 + .dcdc_operation_mode = 0x0, 109 + .soc_reset_wait_cnt = 0x0 110 + }; 111 + 112 + static struct bootup_params boot_params_40 = { 113 + .magic_number = cpu_to_le16(0x5aa5), 114 + .crystal_good_time = 0x0, 115 + .valid = cpu_to_le32(VALID_40), 116 + .reserved_for_valids = 0x0, 117 + .bootup_mode_info = 0x0, 118 + .digital_loop_back_params = 0x0, 119 + .rtls_timestamp_en = 0x0, 120 + .host_spi_intr_cfg = 0x0, 121 + .device_clk_info = {{ 122 + .pll_config_g = { 123 + .tapll_info_g = { 124 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)| 125 + (TA_PLL_M_VAL_40)), 126 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40), 127 + }, 128 + .pll960_info_g = { 129 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)| 130 + (PLL960_N_VAL_40)), 131 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40), 132 + .pll_reg_3 = 0x0, 133 + }, 134 + .afepll_info_g = { 135 + .pll_reg = cpu_to_le16(0x9f0), 136 + } 137 + }, 138 + .switch_clk_g = { 139 + .switch_clk_info = cpu_to_le16(0x09), 140 + .bbp_lmac_clk_reg_val = cpu_to_le16(0x1121), 141 + .umac_clock_reg_config = cpu_to_le16(0x48), 142 + .qspi_uart_clock_reg_config = 0x0 143 + } 144 + }, 145 + { 146 + .pll_config_g = { 147 + .tapll_info_g = { 148 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)| 149 + (TA_PLL_M_VAL_40)), 150 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40), 151 + }, 152 + .pll960_info_g = { 153 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)| 154 + (PLL960_N_VAL_40)), 155 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40), 156 + .pll_reg_3 = 0x0, 157 + }, 158 + .afepll_info_g = { 159 + .pll_reg = cpu_to_le16(0x9f0), 160 + } 161 + }, 162 + .switch_clk_g = { 163 + .switch_clk_info = 0x0, 164 + .bbp_lmac_clk_reg_val = 0x0, 165 + .umac_clock_reg_config = 0x0, 166 + .qspi_uart_clock_reg_config = 0x0 167 + } 168 + }, 169 + { 170 + .pll_config_g = { 171 + .tapll_info_g = { 172 + .pll_reg_1 = cpu_to_le16((TA_PLL_N_VAL_40 << 8)| 173 + (TA_PLL_M_VAL_40)), 174 + .pll_reg_2 = cpu_to_le16(TA_PLL_P_VAL_40), 175 + }, 176 + .pll960_info_g = { 177 + .pll_reg_1 = cpu_to_le16((PLL960_P_VAL_40 << 8)| 178 + (PLL960_N_VAL_40)), 179 + .pll_reg_2 = cpu_to_le16(PLL960_M_VAL_40), 180 + .pll_reg_3 = 0x0, 181 + }, 182 + .afepll_info_g = { 183 + .pll_reg = cpu_to_le16(0x9f0), 184 + } 185 + }, 186 + .switch_clk_g = { 187 + .switch_clk_info = 0x0, 188 + .bbp_lmac_clk_reg_val = 0x0, 189 + .umac_clock_reg_config = 0x0, 190 + .qspi_uart_clock_reg_config = 0x0 191 + } 192 + } }, 193 + .buckboost_wakeup_cnt = 0x0, 194 + .pmu_wakeup_wait = 0x0, 195 + .shutdown_wait_time = 0x0, 196 + .pmu_slp_clkout_sel = 0x0, 197 + .wdt_prog_value = 0x0, 198 + .wdt_soc_rst_delay = 0x0, 199 + .dcdc_operation_mode = 0x0, 200 + .soc_reset_wait_cnt = 0x0 201 + }; 202 + 203 + static u16 mcs[] = {13, 26, 39, 52, 78, 104, 117, 130}; 204 + 205 + /** 206 + * rsi_set_default_parameters() - This function sets default parameters. 207 + * @common: Pointer to the driver private structure. 208 + * 209 + * Return: none 210 + */ 211 + static void rsi_set_default_parameters(struct rsi_common *common) 212 + { 213 + common->band = IEEE80211_BAND_2GHZ; 214 + common->channel_width = BW_20MHZ; 215 + common->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 216 + common->channel = 1; 217 + common->min_rate = 0xffff; 218 + common->fsm_state = FSM_CARD_NOT_READY; 219 + common->iface_down = true; 220 + } 221 + 222 + /** 223 + * rsi_set_contention_vals() - This function sets the contention values for the 224 + * backoff procedure. 225 + * @common: Pointer to the driver private structure. 226 + * 227 + * Return: None. 228 + */ 229 + static void rsi_set_contention_vals(struct rsi_common *common) 230 + { 231 + u8 ii = 0; 232 + 233 + for (; ii < NUM_EDCA_QUEUES; ii++) { 234 + common->tx_qinfo[ii].wme_params = 235 + (((common->edca_params[ii].cw_min / 2) + 236 + (common->edca_params[ii].aifs)) * 237 + WMM_SHORT_SLOT_TIME + SIFS_DURATION); 238 + common->tx_qinfo[ii].weight = common->tx_qinfo[ii].wme_params; 239 + common->tx_qinfo[ii].pkt_contended = 0; 240 + } 241 + } 242 + 243 + /** 244 + * rsi_send_internal_mgmt_frame() - This function sends management frames to 245 + * firmware.Also schedules packet to queue 246 + * for transmission. 247 + * @common: Pointer to the driver private structure. 248 + * @skb: Pointer to the socket buffer structure. 249 + * 250 + * Return: 0 on success, -1 on failure. 251 + */ 252 + static int rsi_send_internal_mgmt_frame(struct rsi_common *common, 253 + struct sk_buff *skb) 254 + { 255 + struct skb_info *tx_params; 256 + 257 + if (skb == NULL) { 258 + rsi_dbg(ERR_ZONE, "%s: Unable to allocate skb\n", __func__); 259 + return -ENOMEM; 260 + } 261 + tx_params = (struct skb_info *)&IEEE80211_SKB_CB(skb)->driver_data; 262 + tx_params->flags |= INTERNAL_MGMT_PKT; 263 + skb_queue_tail(&common->tx_queue[MGMT_SOFT_Q], skb); 264 + rsi_set_event(&common->tx_thread.event); 265 + return 0; 266 + } 267 + 268 + /** 269 + * rsi_load_radio_caps() - This function is used to send radio capabilities 270 + * values to firmware. 271 + * @common: Pointer to the driver private structure. 272 + * 273 + * Return: 0 on success, corresponding negative error code on failure. 274 + */ 275 + static int rsi_load_radio_caps(struct rsi_common *common) 276 + { 277 + struct rsi_radio_caps *radio_caps; 278 + struct rsi_hw *adapter = common->priv; 279 + struct ieee80211_hw *hw = adapter->hw; 280 + u16 inx = 0; 281 + u8 ii; 282 + u8 radio_id = 0; 283 + u16 gc[20] = {0xf0, 0xf0, 0xf0, 0xf0, 284 + 0xf0, 0xf0, 0xf0, 0xf0, 285 + 0xf0, 0xf0, 0xf0, 0xf0, 286 + 0xf0, 0xf0, 0xf0, 0xf0, 287 + 0xf0, 0xf0, 0xf0, 0xf0}; 288 + struct ieee80211_conf *conf = &hw->conf; 289 + struct sk_buff *skb; 290 + 291 + rsi_dbg(INFO_ZONE, "%s: Sending rate symbol req frame\n", __func__); 292 + 293 + skb = dev_alloc_skb(sizeof(struct rsi_radio_caps)); 294 + 295 + if (!skb) { 296 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 297 + __func__); 298 + return -ENOMEM; 299 + } 300 + 301 + memset(skb->data, 0, sizeof(struct rsi_radio_caps)); 302 + radio_caps = (struct rsi_radio_caps *)skb->data; 303 + 304 + radio_caps->desc_word[1] = cpu_to_le16(RADIO_CAPABILITIES); 305 + radio_caps->desc_word[4] = cpu_to_le16(RSI_RF_TYPE << 8); 306 + 307 + if (common->channel_width == BW_40MHZ) { 308 + radio_caps->desc_word[7] |= cpu_to_le16(RSI_LMAC_CLOCK_80MHZ); 309 + radio_caps->desc_word[7] |= cpu_to_le16(RSI_ENABLE_40MHZ); 310 + if (common->channel_width) { 311 + radio_caps->desc_word[5] = 312 + cpu_to_le16(common->channel_width << 12); 313 + radio_caps->desc_word[5] |= cpu_to_le16(FULL40M_ENABLE); 314 + } 315 + 316 + if (conf_is_ht40_minus(conf)) { 317 + radio_caps->desc_word[5] = 0; 318 + radio_caps->desc_word[5] |= 319 + cpu_to_le16(LOWER_20_ENABLE); 320 + radio_caps->desc_word[5] |= 321 + cpu_to_le16(LOWER_20_ENABLE >> 12); 322 + } 323 + 324 + if (conf_is_ht40_plus(conf)) { 325 + radio_caps->desc_word[5] = 0; 326 + radio_caps->desc_word[5] |= 327 + cpu_to_le16(UPPER_20_ENABLE); 328 + radio_caps->desc_word[5] |= 329 + cpu_to_le16(UPPER_20_ENABLE >> 12); 330 + } 331 + } 332 + 333 + radio_caps->desc_word[7] |= cpu_to_le16(radio_id << 8); 334 + 335 + for (ii = 0; ii < MAX_HW_QUEUES; ii++) { 336 + radio_caps->qos_params[ii].cont_win_min_q = cpu_to_le16(3); 337 + radio_caps->qos_params[ii].cont_win_max_q = cpu_to_le16(0x3f); 338 + radio_caps->qos_params[ii].aifsn_val_q = cpu_to_le16(2); 339 + radio_caps->qos_params[ii].txop_q = 0; 340 + } 341 + 342 + for (ii = 0; ii < MAX_HW_QUEUES - 4; ii++) { 343 + radio_caps->qos_params[ii].cont_win_min_q = 344 + cpu_to_le16(common->edca_params[ii].cw_min); 345 + radio_caps->qos_params[ii].cont_win_max_q = 346 + cpu_to_le16(common->edca_params[ii].cw_max); 347 + radio_caps->qos_params[ii].aifsn_val_q = 348 + cpu_to_le16((common->edca_params[ii].aifs) << 8); 349 + radio_caps->qos_params[ii].txop_q = 350 + cpu_to_le16(common->edca_params[ii].txop); 351 + } 352 + 353 + memcpy(&common->rate_pwr[0], &gc[0], 40); 354 + for (ii = 0; ii < 20; ii++) 355 + radio_caps->gcpd_per_rate[inx++] = 356 + cpu_to_le16(common->rate_pwr[ii] & 0x00FF); 357 + 358 + radio_caps->desc_word[0] = cpu_to_le16((sizeof(struct rsi_radio_caps) - 359 + FRAME_DESC_SZ) | 360 + (RSI_WIFI_MGMT_Q << 12)); 361 + 362 + 363 + skb_put(skb, (sizeof(struct rsi_radio_caps))); 364 + 365 + return rsi_send_internal_mgmt_frame(common, skb); 366 + } 367 + 368 + /** 369 + * rsi_mgmt_pkt_to_core() - This function is the entry point for Mgmt module. 370 + * @common: Pointer to the driver private structure. 371 + * @msg: Pointer to received packet. 372 + * @msg_len: Length of the recieved packet. 373 + * @type: Type of recieved packet. 374 + * 375 + * Return: 0 on success, -1 on failure. 376 + */ 377 + static int rsi_mgmt_pkt_to_core(struct rsi_common *common, 378 + u8 *msg, 379 + s32 msg_len, 380 + u8 type) 381 + { 382 + struct rsi_hw *adapter = common->priv; 383 + struct ieee80211_tx_info *info; 384 + struct skb_info *rx_params; 385 + u8 pad_bytes = msg[4]; 386 + u8 pkt_recv; 387 + struct sk_buff *skb; 388 + char *buffer; 389 + 390 + if (type == RX_DOT11_MGMT) { 391 + if (!adapter->sc_nvifs) 392 + return -ENOLINK; 393 + 394 + msg_len -= pad_bytes; 395 + if ((msg_len <= 0) || (!msg)) { 396 + rsi_dbg(MGMT_RX_ZONE, "Invalid rx msg of len = %d\n", 397 + __func__, msg_len); 398 + return -EINVAL; 399 + } 400 + 401 + skb = dev_alloc_skb(msg_len); 402 + if (!skb) { 403 + rsi_dbg(ERR_ZONE, "%s: Failed to allocate skb\n", 404 + __func__); 405 + return -ENOMEM; 406 + } 407 + 408 + buffer = skb_put(skb, msg_len); 409 + 410 + memcpy(buffer, 411 + (u8 *)(msg + FRAME_DESC_SZ + pad_bytes), 412 + msg_len); 413 + 414 + pkt_recv = buffer[0]; 415 + 416 + info = IEEE80211_SKB_CB(skb); 417 + rx_params = (struct skb_info *)info->driver_data; 418 + rx_params->rssi = rsi_get_rssi(msg); 419 + rx_params->channel = rsi_get_channel(msg); 420 + rsi_indicate_pkt_to_os(common, skb); 421 + } else { 422 + rsi_dbg(MGMT_TX_ZONE, "%s: Internal Packet\n", __func__); 423 + } 424 + 425 + return 0; 426 + } 427 + 428 + /** 429 + * rsi_hal_send_sta_notify_frame() - This function sends the station notify 430 + * frame to firmware. 431 + * @common: Pointer to the driver private structure. 432 + * @opmode: Operating mode of device. 433 + * @notify_event: Notification about station connection. 434 + * @bssid: bssid. 435 + * @qos_enable: Qos is enabled. 436 + * @aid: Aid (unique for all STA). 437 + * 438 + * Return: status: 0 on success, corresponding negative error code on failure. 439 + */ 440 + static int rsi_hal_send_sta_notify_frame(struct rsi_common *common, 441 + u8 opmode, 442 + u8 notify_event, 443 + const unsigned char *bssid, 444 + u8 qos_enable, 445 + u16 aid) 446 + { 447 + struct sk_buff *skb = NULL; 448 + struct rsi_peer_notify *peer_notify; 449 + u16 vap_id = 0; 450 + int status; 451 + 452 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending sta notify frame\n", __func__); 453 + 454 + skb = dev_alloc_skb(sizeof(struct rsi_peer_notify)); 455 + 456 + if (!skb) { 457 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 458 + __func__); 459 + return -ENOMEM; 460 + } 461 + 462 + memset(skb->data, 0, sizeof(struct rsi_peer_notify)); 463 + peer_notify = (struct rsi_peer_notify *)skb->data; 464 + 465 + peer_notify->command = cpu_to_le16(opmode << 1); 466 + 467 + switch (notify_event) { 468 + case STA_CONNECTED: 469 + peer_notify->command |= cpu_to_le16(RSI_ADD_PEER); 470 + break; 471 + case STA_DISCONNECTED: 472 + peer_notify->command |= cpu_to_le16(RSI_DELETE_PEER); 473 + break; 474 + default: 475 + break; 476 + } 477 + 478 + peer_notify->command |= cpu_to_le16((aid & 0xfff) << 4); 479 + ether_addr_copy(peer_notify->mac_addr, bssid); 480 + 481 + peer_notify->sta_flags = cpu_to_le32((qos_enable) ? 1 : 0); 482 + 483 + peer_notify->desc_word[0] = 484 + cpu_to_le16((sizeof(struct rsi_peer_notify) - FRAME_DESC_SZ) | 485 + (RSI_WIFI_MGMT_Q << 12)); 486 + peer_notify->desc_word[1] = cpu_to_le16(PEER_NOTIFY); 487 + peer_notify->desc_word[7] |= cpu_to_le16(vap_id << 8); 488 + 489 + skb_put(skb, sizeof(struct rsi_peer_notify)); 490 + 491 + status = rsi_send_internal_mgmt_frame(common, skb); 492 + 493 + if (!status && qos_enable) { 494 + rsi_set_contention_vals(common); 495 + status = rsi_load_radio_caps(common); 496 + } 497 + return status; 498 + } 499 + 500 + /** 501 + * rsi_send_aggregation_params_frame() - This function sends the ampdu 502 + * indication frame to firmware. 503 + * @common: Pointer to the driver private structure. 504 + * @tid: traffic identifier. 505 + * @ssn: ssn. 506 + * @buf_size: buffer size. 507 + * @event: notification about station connection. 508 + * 509 + * Return: 0 on success, corresponding negative error code on failure. 510 + */ 511 + int rsi_send_aggregation_params_frame(struct rsi_common *common, 512 + u16 tid, 513 + u16 ssn, 514 + u8 buf_size, 515 + u8 event) 516 + { 517 + struct sk_buff *skb = NULL; 518 + struct rsi_mac_frame *mgmt_frame; 519 + u8 peer_id = 0; 520 + 521 + skb = dev_alloc_skb(FRAME_DESC_SZ); 522 + 523 + if (!skb) { 524 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 525 + __func__); 526 + return -ENOMEM; 527 + } 528 + 529 + memset(skb->data, 0, FRAME_DESC_SZ); 530 + mgmt_frame = (struct rsi_mac_frame *)skb->data; 531 + 532 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending AMPDU indication frame\n", __func__); 533 + 534 + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 535 + mgmt_frame->desc_word[1] = cpu_to_le16(AMPDU_IND); 536 + 537 + if (event == STA_TX_ADDBA_DONE) { 538 + mgmt_frame->desc_word[4] = cpu_to_le16(ssn); 539 + mgmt_frame->desc_word[5] = cpu_to_le16(buf_size); 540 + mgmt_frame->desc_word[7] = 541 + cpu_to_le16((tid | (START_AMPDU_AGGR << 4) | (peer_id << 8))); 542 + } else if (event == STA_RX_ADDBA_DONE) { 543 + mgmt_frame->desc_word[4] = cpu_to_le16(ssn); 544 + mgmt_frame->desc_word[7] = cpu_to_le16(tid | 545 + (START_AMPDU_AGGR << 4) | 546 + (RX_BA_INDICATION << 5) | 547 + (peer_id << 8)); 548 + } else if (event == STA_TX_DELBA) { 549 + mgmt_frame->desc_word[7] = cpu_to_le16(tid | 550 + (STOP_AMPDU_AGGR << 4) | 551 + (peer_id << 8)); 552 + } else if (event == STA_RX_DELBA) { 553 + mgmt_frame->desc_word[7] = cpu_to_le16(tid | 554 + (STOP_AMPDU_AGGR << 4) | 555 + (RX_BA_INDICATION << 5) | 556 + (peer_id << 8)); 557 + } 558 + 559 + skb_put(skb, FRAME_DESC_SZ); 560 + 561 + return rsi_send_internal_mgmt_frame(common, skb); 562 + } 563 + 564 + /** 565 + * rsi_program_bb_rf() - This function starts base band and RF programming. 566 + * This is called after initial configurations are done. 567 + * @common: Pointer to the driver private structure. 568 + * 569 + * Return: 0 on success, corresponding negative error code on failure. 570 + */ 571 + static int rsi_program_bb_rf(struct rsi_common *common) 572 + { 573 + struct sk_buff *skb; 574 + struct rsi_mac_frame *mgmt_frame; 575 + 576 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending program BB/RF frame\n", __func__); 577 + 578 + skb = dev_alloc_skb(FRAME_DESC_SZ); 579 + if (!skb) { 580 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 581 + __func__); 582 + return -ENOMEM; 583 + } 584 + 585 + memset(skb->data, 0, FRAME_DESC_SZ); 586 + mgmt_frame = (struct rsi_mac_frame *)skb->data; 587 + 588 + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 589 + mgmt_frame->desc_word[1] = cpu_to_le16(BBP_PROG_IN_TA); 590 + mgmt_frame->desc_word[4] = cpu_to_le16(common->endpoint << 8); 591 + 592 + if (common->rf_reset) { 593 + mgmt_frame->desc_word[7] = cpu_to_le16(RF_RESET_ENABLE); 594 + rsi_dbg(MGMT_TX_ZONE, "%s: ===> RF RESET REQUEST SENT <===\n", 595 + __func__); 596 + common->rf_reset = 0; 597 + } 598 + common->bb_rf_prog_count = 1; 599 + mgmt_frame->desc_word[7] |= cpu_to_le16(PUT_BBP_RESET | 600 + BBP_REG_WRITE | (RSI_RF_TYPE << 4)); 601 + skb_put(skb, FRAME_DESC_SZ); 602 + 603 + return rsi_send_internal_mgmt_frame(common, skb); 604 + } 605 + 606 + /** 607 + * rsi_set_vap_capabilities() - This function send vap capability to firmware. 608 + * @common: Pointer to the driver private structure. 609 + * @opmode: Operating mode of device. 610 + * 611 + * Return: 0 on success, corresponding negative error code on failure. 612 + */ 613 + int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode) 614 + { 615 + struct sk_buff *skb = NULL; 616 + struct rsi_vap_caps *vap_caps; 617 + u16 vap_id = 0; 618 + 619 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending VAP capabilities frame\n", __func__); 620 + 621 + skb = dev_alloc_skb(sizeof(struct rsi_vap_caps)); 622 + if (!skb) { 623 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 624 + __func__); 625 + return -ENOMEM; 626 + } 627 + 628 + memset(skb->data, 0, sizeof(struct rsi_vap_caps)); 629 + vap_caps = (struct rsi_vap_caps *)skb->data; 630 + 631 + vap_caps->desc_word[0] = cpu_to_le16((sizeof(struct rsi_vap_caps) - 632 + FRAME_DESC_SZ) | 633 + (RSI_WIFI_MGMT_Q << 12)); 634 + vap_caps->desc_word[1] = cpu_to_le16(VAP_CAPABILITIES); 635 + vap_caps->desc_word[4] = cpu_to_le16(mode | 636 + (common->channel_width << 8)); 637 + vap_caps->desc_word[7] = cpu_to_le16((vap_id << 8) | 638 + (common->mac_id << 4) | 639 + common->radio_id); 640 + 641 + memcpy(vap_caps->mac_addr, common->mac_addr, IEEE80211_ADDR_LEN); 642 + vap_caps->keep_alive_period = cpu_to_le16(90); 643 + vap_caps->frag_threshold = cpu_to_le16(IEEE80211_MAX_FRAG_THRESHOLD); 644 + 645 + vap_caps->rts_threshold = cpu_to_le16(common->rts_threshold); 646 + vap_caps->default_mgmt_rate = 0; 647 + if (conf_is_ht40(&common->priv->hw->conf)) { 648 + vap_caps->default_ctrl_rate = 649 + cpu_to_le32(RSI_RATE_6 | FULL40M_ENABLE << 16); 650 + } else { 651 + vap_caps->default_ctrl_rate = cpu_to_le32(RSI_RATE_6); 652 + } 653 + vap_caps->default_data_rate = 0; 654 + vap_caps->beacon_interval = cpu_to_le16(200); 655 + vap_caps->dtim_period = cpu_to_le16(4); 656 + 657 + skb_put(skb, sizeof(*vap_caps)); 658 + 659 + return rsi_send_internal_mgmt_frame(common, skb); 660 + } 661 + 662 + /** 663 + * rsi_hal_load_key() - This function is used to load keys within the firmware. 664 + * @common: Pointer to the driver private structure. 665 + * @data: Pointer to the key data. 666 + * @key_len: Key length to be loaded. 667 + * @key_type: Type of key: GROUP/PAIRWISE. 668 + * @key_id: Key index. 669 + * @cipher: Type of cipher used. 670 + * 671 + * Return: 0 on success, -1 on failure. 672 + */ 673 + int rsi_hal_load_key(struct rsi_common *common, 674 + u8 *data, 675 + u16 key_len, 676 + u8 key_type, 677 + u8 key_id, 678 + u32 cipher) 679 + { 680 + struct sk_buff *skb = NULL; 681 + struct rsi_set_key *set_key; 682 + u16 key_descriptor = 0; 683 + 684 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending load key frame\n", __func__); 685 + 686 + skb = dev_alloc_skb(sizeof(struct rsi_set_key)); 687 + if (!skb) { 688 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 689 + __func__); 690 + return -ENOMEM; 691 + } 692 + 693 + memset(skb->data, 0, sizeof(struct rsi_set_key)); 694 + set_key = (struct rsi_set_key *)skb->data; 695 + 696 + if ((cipher == WLAN_CIPHER_SUITE_WEP40) || 697 + (cipher == WLAN_CIPHER_SUITE_WEP104)) { 698 + key_len += 1; 699 + key_descriptor |= BIT(2); 700 + if (key_len >= 13) 701 + key_descriptor |= BIT(3); 702 + } else if (cipher != KEY_TYPE_CLEAR) { 703 + key_descriptor |= BIT(4); 704 + if (key_type == RSI_PAIRWISE_KEY) 705 + key_id = 0; 706 + if (cipher == WLAN_CIPHER_SUITE_TKIP) 707 + key_descriptor |= BIT(5); 708 + } 709 + key_descriptor |= (key_type | BIT(13) | (key_id << 14)); 710 + 711 + set_key->desc_word[0] = cpu_to_le16((sizeof(struct rsi_set_key) - 712 + FRAME_DESC_SZ) | 713 + (RSI_WIFI_MGMT_Q << 12)); 714 + set_key->desc_word[1] = cpu_to_le16(SET_KEY_REQ); 715 + set_key->desc_word[4] = cpu_to_le16(key_descriptor); 716 + 717 + if ((cipher == WLAN_CIPHER_SUITE_WEP40) || 718 + (cipher == WLAN_CIPHER_SUITE_WEP104)) { 719 + memcpy(&set_key->key[key_id][1], 720 + data, 721 + key_len * 2); 722 + } else { 723 + memcpy(&set_key->key[0][0], data, key_len); 724 + } 725 + 726 + memcpy(set_key->tx_mic_key, &data[16], 8); 727 + memcpy(set_key->rx_mic_key, &data[24], 8); 728 + 729 + skb_put(skb, sizeof(struct rsi_set_key)); 730 + 731 + return rsi_send_internal_mgmt_frame(common, skb); 732 + } 733 + 734 + /* 735 + * rsi_load_bootup_params() - This function send bootup params to the firmware. 736 + * @common: Pointer to the driver private structure. 737 + * 738 + * Return: 0 on success, corresponding error code on failure. 739 + */ 740 + static u8 rsi_load_bootup_params(struct rsi_common *common) 741 + { 742 + struct sk_buff *skb; 743 + struct rsi_boot_params *boot_params; 744 + 745 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending boot params frame\n", __func__); 746 + skb = dev_alloc_skb(sizeof(struct rsi_boot_params)); 747 + if (!skb) { 748 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 749 + __func__); 750 + return -ENOMEM; 751 + } 752 + 753 + memset(skb->data, 0, sizeof(struct rsi_boot_params)); 754 + boot_params = (struct rsi_boot_params *)skb->data; 755 + 756 + rsi_dbg(MGMT_TX_ZONE, "%s:\n", __func__); 757 + 758 + if (common->channel_width == BW_40MHZ) { 759 + memcpy(&boot_params->bootup_params, 760 + &boot_params_40, 761 + sizeof(struct bootup_params)); 762 + rsi_dbg(MGMT_TX_ZONE, "%s: Packet 40MHZ <=== %d\n", __func__, 763 + UMAC_CLK_40BW); 764 + boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40BW); 765 + } else { 766 + memcpy(&boot_params->bootup_params, 767 + &boot_params_20, 768 + sizeof(struct bootup_params)); 769 + if (boot_params_20.valid != cpu_to_le32(VALID_20)) { 770 + boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_20BW); 771 + rsi_dbg(MGMT_TX_ZONE, 772 + "%s: Packet 20MHZ <=== %d\n", __func__, 773 + UMAC_CLK_20BW); 774 + } else { 775 + boot_params->desc_word[7] = cpu_to_le16(UMAC_CLK_40MHZ); 776 + rsi_dbg(MGMT_TX_ZONE, 777 + "%s: Packet 20MHZ <=== %d\n", __func__, 778 + UMAC_CLK_40MHZ); 779 + } 780 + } 781 + 782 + /** 783 + * Bit{0:11} indicates length of the Packet 784 + * Bit{12:15} indicates host queue number 785 + */ 786 + boot_params->desc_word[0] = cpu_to_le16(sizeof(struct bootup_params) | 787 + (RSI_WIFI_MGMT_Q << 12)); 788 + boot_params->desc_word[1] = cpu_to_le16(BOOTUP_PARAMS_REQUEST); 789 + 790 + skb_put(skb, sizeof(struct rsi_boot_params)); 791 + 792 + return rsi_send_internal_mgmt_frame(common, skb); 793 + } 794 + 795 + /** 796 + * rsi_send_reset_mac() - This function prepares reset MAC request and sends an 797 + * internal management frame to indicate it to firmware. 798 + * @common: Pointer to the driver private structure. 799 + * 800 + * Return: 0 on success, corresponding error code on failure. 801 + */ 802 + static int rsi_send_reset_mac(struct rsi_common *common) 803 + { 804 + struct sk_buff *skb; 805 + struct rsi_mac_frame *mgmt_frame; 806 + 807 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending reset MAC frame\n", __func__); 808 + 809 + skb = dev_alloc_skb(FRAME_DESC_SZ); 810 + if (!skb) { 811 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 812 + __func__); 813 + return -ENOMEM; 814 + } 815 + 816 + memset(skb->data, 0, FRAME_DESC_SZ); 817 + mgmt_frame = (struct rsi_mac_frame *)skb->data; 818 + 819 + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 820 + mgmt_frame->desc_word[1] = cpu_to_le16(RESET_MAC_REQ); 821 + mgmt_frame->desc_word[4] = cpu_to_le16(RETRY_COUNT << 8); 822 + 823 + skb_put(skb, FRAME_DESC_SZ); 824 + 825 + return rsi_send_internal_mgmt_frame(common, skb); 826 + } 827 + 828 + /** 829 + * rsi_set_channel() - This function programs the channel. 830 + * @common: Pointer to the driver private structure. 831 + * @channel: Channel value to be set. 832 + * 833 + * Return: 0 on success, corresponding error code on failure. 834 + */ 835 + int rsi_set_channel(struct rsi_common *common, u16 channel) 836 + { 837 + struct sk_buff *skb = NULL; 838 + struct rsi_mac_frame *mgmt_frame; 839 + 840 + rsi_dbg(MGMT_TX_ZONE, 841 + "%s: Sending scan req frame\n", __func__); 842 + 843 + skb = dev_alloc_skb(FRAME_DESC_SZ); 844 + if (!skb) { 845 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 846 + __func__); 847 + return -ENOMEM; 848 + } 849 + 850 + memset(skb->data, 0, FRAME_DESC_SZ); 851 + mgmt_frame = (struct rsi_mac_frame *)skb->data; 852 + 853 + if (common->band == IEEE80211_BAND_5GHZ) { 854 + if ((channel >= 36) && (channel <= 64)) 855 + channel = ((channel - 32) / 4); 856 + else if ((channel > 64) && (channel <= 140)) 857 + channel = ((channel - 102) / 4) + 8; 858 + else if (channel >= 149) 859 + channel = ((channel - 151) / 4) + 18; 860 + else 861 + return -EINVAL; 862 + } else { 863 + if (channel > 14) { 864 + rsi_dbg(ERR_ZONE, "%s: Invalid chno %d, band = %d\n", 865 + __func__, channel, common->band); 866 + return -EINVAL; 867 + } 868 + } 869 + 870 + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 871 + mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST); 872 + mgmt_frame->desc_word[4] = cpu_to_le16(channel); 873 + 874 + mgmt_frame->desc_word[7] = cpu_to_le16(PUT_BBP_RESET | 875 + BBP_REG_WRITE | 876 + (RSI_RF_TYPE << 4)); 877 + 878 + mgmt_frame->desc_word[5] = cpu_to_le16(0x01); 879 + 880 + if (common->channel_width == BW_40MHZ) 881 + mgmt_frame->desc_word[5] |= cpu_to_le16(0x1 << 8); 882 + 883 + common->channel = channel; 884 + 885 + skb_put(skb, FRAME_DESC_SZ); 886 + 887 + return rsi_send_internal_mgmt_frame(common, skb); 888 + } 889 + 890 + /** 891 + * rsi_compare() - This function is used to compare two integers 892 + * @a: pointer to the first integer 893 + * @b: pointer to the second integer 894 + * 895 + * Return: 0 if both are equal, -1 if the first is smaller, else 1 896 + */ 897 + static int rsi_compare(const void *a, const void *b) 898 + { 899 + u16 _a = *(const u16 *)(a); 900 + u16 _b = *(const u16 *)(b); 901 + 902 + if (_a > _b) 903 + return -1; 904 + 905 + if (_a < _b) 906 + return 1; 907 + 908 + return 0; 909 + } 910 + 911 + /** 912 + * rsi_map_rates() - This function is used to map selected rates to hw rates. 913 + * @rate: The standard rate to be mapped. 914 + * @offset: Offset that will be returned. 915 + * 916 + * Return: 0 if it is a mcs rate, else 1 917 + */ 918 + static bool rsi_map_rates(u16 rate, int *offset) 919 + { 920 + int kk; 921 + for (kk = 0; kk < ARRAY_SIZE(rsi_mcsrates); kk++) { 922 + if (rate == mcs[kk]) { 923 + *offset = kk; 924 + return false; 925 + } 926 + } 927 + 928 + for (kk = 0; kk < ARRAY_SIZE(rsi_rates); kk++) { 929 + if (rate == rsi_rates[kk].bitrate / 5) { 930 + *offset = kk; 931 + break; 932 + } 933 + } 934 + return true; 935 + } 936 + 937 + /** 938 + * rsi_send_auto_rate_request() - This function is to set rates for connection 939 + * and send autorate request to firmware. 940 + * @common: Pointer to the driver private structure. 941 + * 942 + * Return: 0 on success, corresponding error code on failure. 943 + */ 944 + static int rsi_send_auto_rate_request(struct rsi_common *common) 945 + { 946 + struct sk_buff *skb; 947 + struct rsi_auto_rate *auto_rate; 948 + int ii = 0, jj = 0, kk = 0; 949 + struct ieee80211_hw *hw = common->priv->hw; 950 + u8 band = hw->conf.chandef.chan->band; 951 + u8 num_supported_rates = 0; 952 + u8 rate_offset = 0; 953 + u32 rate_bitmap = common->bitrate_mask[band]; 954 + 955 + u16 *selected_rates, min_rate; 956 + 957 + skb = dev_alloc_skb(sizeof(struct rsi_auto_rate)); 958 + if (!skb) { 959 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 960 + __func__); 961 + return -ENOMEM; 962 + } 963 + 964 + selected_rates = kmalloc(2 * RSI_TBL_SZ, GFP_KERNEL); 965 + if (!selected_rates) { 966 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n", 967 + __func__); 968 + return -ENOMEM; 969 + } 970 + 971 + memset(skb->data, 0, sizeof(struct rsi_auto_rate)); 972 + memset(selected_rates, 0, 2 * RSI_TBL_SZ); 973 + 974 + auto_rate = (struct rsi_auto_rate *)skb->data; 975 + 976 + auto_rate->aarf_rssi = cpu_to_le16(((u16)3 << 6) | (u16)(18 & 0x3f)); 977 + auto_rate->collision_tolerance = cpu_to_le16(3); 978 + auto_rate->failure_limit = cpu_to_le16(3); 979 + auto_rate->initial_boundary = cpu_to_le16(3); 980 + auto_rate->max_threshold_limt = cpu_to_le16(27); 981 + 982 + auto_rate->desc_word[1] = cpu_to_le16(AUTO_RATE_IND); 983 + 984 + if (common->channel_width == BW_40MHZ) 985 + auto_rate->desc_word[7] |= cpu_to_le16(1); 986 + 987 + if (band == IEEE80211_BAND_2GHZ) 988 + min_rate = STD_RATE_01; 989 + else 990 + min_rate = STD_RATE_06; 991 + 992 + for (ii = 0, jj = 0; ii < ARRAY_SIZE(rsi_rates); ii++) { 993 + if (rate_bitmap & BIT(ii)) { 994 + selected_rates[jj++] = (rsi_rates[ii].bitrate / 5); 995 + rate_offset++; 996 + } 997 + } 998 + num_supported_rates = jj; 999 + 1000 + if (common->vif_info[0].is_ht) { 1001 + for (ii = 0; ii < ARRAY_SIZE(mcs); ii++) 1002 + selected_rates[jj++] = mcs[ii]; 1003 + num_supported_rates += ARRAY_SIZE(mcs); 1004 + rate_offset += ARRAY_SIZE(mcs); 1005 + } 1006 + 1007 + if (rate_offset < (RSI_TBL_SZ / 2) - 1) { 1008 + for (ii = jj; ii < (RSI_TBL_SZ / 2); ii++) { 1009 + selected_rates[jj++] = min_rate; 1010 + rate_offset++; 1011 + } 1012 + } 1013 + 1014 + sort(selected_rates, jj, sizeof(u16), &rsi_compare, NULL); 1015 + 1016 + /* mapping the rates to RSI rates */ 1017 + for (ii = 0; ii < jj; ii++) { 1018 + if (rsi_map_rates(selected_rates[ii], &kk)) { 1019 + auto_rate->supported_rates[ii] = 1020 + cpu_to_le16(rsi_rates[kk].hw_value); 1021 + } else { 1022 + auto_rate->supported_rates[ii] = 1023 + cpu_to_le16(rsi_mcsrates[kk]); 1024 + } 1025 + } 1026 + 1027 + /* loading HT rates in the bottom half of the auto rate table */ 1028 + if (common->vif_info[0].is_ht) { 1029 + if (common->vif_info[0].sgi) 1030 + auto_rate->supported_rates[rate_offset++] = 1031 + cpu_to_le16(RSI_RATE_MCS7_SG); 1032 + 1033 + for (ii = rate_offset, kk = ARRAY_SIZE(rsi_mcsrates) - 1; 1034 + ii < rate_offset + 2 * ARRAY_SIZE(rsi_mcsrates); ii++) { 1035 + if (common->vif_info[0].sgi) 1036 + auto_rate->supported_rates[ii++] = 1037 + cpu_to_le16(rsi_mcsrates[kk] | BIT(9)); 1038 + auto_rate->supported_rates[ii] = 1039 + cpu_to_le16(rsi_mcsrates[kk--]); 1040 + } 1041 + 1042 + for (; ii < RSI_TBL_SZ; ii++) { 1043 + auto_rate->supported_rates[ii] = 1044 + cpu_to_le16(rsi_mcsrates[0]); 1045 + } 1046 + } 1047 + 1048 + auto_rate->num_supported_rates = cpu_to_le16(num_supported_rates * 2); 1049 + auto_rate->moderate_rate_inx = cpu_to_le16(num_supported_rates / 2); 1050 + auto_rate->desc_word[7] |= cpu_to_le16(0 << 8); 1051 + num_supported_rates *= 2; 1052 + 1053 + auto_rate->desc_word[0] = cpu_to_le16((sizeof(*auto_rate) - 1054 + FRAME_DESC_SZ) | 1055 + (RSI_WIFI_MGMT_Q << 12)); 1056 + 1057 + skb_put(skb, 1058 + sizeof(struct rsi_auto_rate)); 1059 + kfree(selected_rates); 1060 + 1061 + return rsi_send_internal_mgmt_frame(common, skb); 1062 + } 1063 + 1064 + /** 1065 + * rsi_inform_bss_status() - This function informs about bss status with the 1066 + * help of sta notify params by sending an internal 1067 + * management frame to firmware. 1068 + * @common: Pointer to the driver private structure. 1069 + * @status: Bss status type. 1070 + * @bssid: Bssid. 1071 + * @qos_enable: Qos is enabled. 1072 + * @aid: Aid (unique for all STAs). 1073 + * 1074 + * Return: None. 1075 + */ 1076 + void rsi_inform_bss_status(struct rsi_common *common, 1077 + u8 status, 1078 + const unsigned char *bssid, 1079 + u8 qos_enable, 1080 + u16 aid) 1081 + { 1082 + if (status) { 1083 + rsi_hal_send_sta_notify_frame(common, 1084 + NL80211_IFTYPE_STATION, 1085 + STA_CONNECTED, 1086 + bssid, 1087 + qos_enable, 1088 + aid); 1089 + if (common->min_rate == 0xffff) 1090 + rsi_send_auto_rate_request(common); 1091 + } else { 1092 + rsi_hal_send_sta_notify_frame(common, 1093 + NL80211_IFTYPE_STATION, 1094 + STA_DISCONNECTED, 1095 + bssid, 1096 + qos_enable, 1097 + aid); 1098 + } 1099 + } 1100 + 1101 + /** 1102 + * rsi_eeprom_read() - This function sends a frame to read the mac address 1103 + * from the eeprom. 1104 + * @common: Pointer to the driver private structure. 1105 + * 1106 + * Return: 0 on success, -1 on failure. 1107 + */ 1108 + static int rsi_eeprom_read(struct rsi_common *common) 1109 + { 1110 + struct rsi_mac_frame *mgmt_frame; 1111 + struct sk_buff *skb; 1112 + 1113 + rsi_dbg(MGMT_TX_ZONE, "%s: Sending EEPROM read req frame\n", __func__); 1114 + 1115 + skb = dev_alloc_skb(FRAME_DESC_SZ); 1116 + if (!skb) { 1117 + rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n", 1118 + __func__); 1119 + return -ENOMEM; 1120 + } 1121 + 1122 + memset(skb->data, 0, FRAME_DESC_SZ); 1123 + mgmt_frame = (struct rsi_mac_frame *)skb->data; 1124 + 1125 + /* FrameType */ 1126 + mgmt_frame->desc_word[1] = cpu_to_le16(EEPROM_READ_TYPE); 1127 + mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); 1128 + /* Number of bytes to read */ 1129 + mgmt_frame->desc_word[3] = cpu_to_le16(ETH_ALEN + 1130 + WLAN_MAC_MAGIC_WORD_LEN + 1131 + WLAN_HOST_MODE_LEN + 1132 + WLAN_FW_VERSION_LEN); 1133 + /* Address to read */ 1134 + mgmt_frame->desc_word[4] = cpu_to_le16(WLAN_MAC_EEPROM_ADDR); 1135 + 1136 + skb_put(skb, FRAME_DESC_SZ); 1137 + 1138 + return rsi_send_internal_mgmt_frame(common, skb); 1139 + } 1140 + 1141 + /** 1142 + * rsi_handle_ta_confirm_type() - This function handles the confirm frames. 1143 + * @common: Pointer to the driver private structure. 1144 + * @msg: Pointer to received packet. 1145 + * 1146 + * Return: 0 on success, -1 on failure. 1147 + */ 1148 + static int rsi_handle_ta_confirm_type(struct rsi_common *common, 1149 + u8 *msg) 1150 + { 1151 + u8 sub_type = (msg[15] & 0xff); 1152 + 1153 + switch (sub_type) { 1154 + case BOOTUP_PARAMS_REQUEST: 1155 + rsi_dbg(FSM_ZONE, "%s: Boot up params confirm received\n", 1156 + __func__); 1157 + if (common->fsm_state == FSM_BOOT_PARAMS_SENT) { 1158 + if (rsi_eeprom_read(common)) { 1159 + common->fsm_state = FSM_CARD_NOT_READY; 1160 + goto out; 1161 + } else { 1162 + common->fsm_state = FSM_EEPROM_READ_MAC_ADDR; 1163 + } 1164 + } else { 1165 + rsi_dbg(ERR_ZONE, 1166 + "%s: Received bootup params cfm in %d state\n", 1167 + __func__, common->fsm_state); 1168 + return 0; 1169 + } 1170 + break; 1171 + 1172 + case EEPROM_READ_TYPE: 1173 + if (common->fsm_state == FSM_EEPROM_READ_MAC_ADDR) { 1174 + if (msg[16] == MAGIC_WORD) { 1175 + u8 offset = (FRAME_DESC_SZ + WLAN_HOST_MODE_LEN 1176 + + WLAN_MAC_MAGIC_WORD_LEN); 1177 + memcpy(common->mac_addr, 1178 + &msg[offset], 1179 + ETH_ALEN); 1180 + memcpy(&common->fw_ver, 1181 + &msg[offset + ETH_ALEN], 1182 + sizeof(struct version_info)); 1183 + 1184 + } else { 1185 + common->fsm_state = FSM_CARD_NOT_READY; 1186 + break; 1187 + } 1188 + if (rsi_send_reset_mac(common)) 1189 + goto out; 1190 + else 1191 + common->fsm_state = FSM_RESET_MAC_SENT; 1192 + } else { 1193 + rsi_dbg(ERR_ZONE, 1194 + "%s: Received eeprom mac addr in %d state\n", 1195 + __func__, common->fsm_state); 1196 + return 0; 1197 + } 1198 + break; 1199 + 1200 + case RESET_MAC_REQ: 1201 + if (common->fsm_state == FSM_RESET_MAC_SENT) { 1202 + rsi_dbg(FSM_ZONE, "%s: Reset MAC cfm received\n", 1203 + __func__); 1204 + 1205 + if (rsi_load_radio_caps(common)) 1206 + goto out; 1207 + else 1208 + common->fsm_state = FSM_RADIO_CAPS_SENT; 1209 + } else { 1210 + rsi_dbg(ERR_ZONE, 1211 + "%s: Received reset mac cfm in %d state\n", 1212 + __func__, common->fsm_state); 1213 + return 0; 1214 + } 1215 + break; 1216 + 1217 + case RADIO_CAPABILITIES: 1218 + if (common->fsm_state == FSM_RADIO_CAPS_SENT) { 1219 + common->rf_reset = 1; 1220 + if (rsi_program_bb_rf(common)) { 1221 + goto out; 1222 + } else { 1223 + common->fsm_state = FSM_BB_RF_PROG_SENT; 1224 + rsi_dbg(FSM_ZONE, "%s: Radio cap cfm received\n", 1225 + __func__); 1226 + } 1227 + } else { 1228 + rsi_dbg(ERR_ZONE, 1229 + "%s: Received radio caps cfm in %d state\n", 1230 + __func__, common->fsm_state); 1231 + return 0; 1232 + } 1233 + break; 1234 + 1235 + case BB_PROG_VALUES_REQUEST: 1236 + case RF_PROG_VALUES_REQUEST: 1237 + case BBP_PROG_IN_TA: 1238 + rsi_dbg(FSM_ZONE, "%s: BB/RF cfm received\n", __func__); 1239 + if (common->fsm_state == FSM_BB_RF_PROG_SENT) { 1240 + common->bb_rf_prog_count--; 1241 + if (!common->bb_rf_prog_count) { 1242 + common->fsm_state = FSM_MAC_INIT_DONE; 1243 + return rsi_mac80211_attach(common); 1244 + } 1245 + } else { 1246 + goto out; 1247 + } 1248 + break; 1249 + 1250 + default: 1251 + rsi_dbg(INFO_ZONE, "%s: Invalid TA confirm pkt received\n", 1252 + __func__); 1253 + break; 1254 + } 1255 + return 0; 1256 + out: 1257 + rsi_dbg(ERR_ZONE, "%s: Unable to send pkt/Invalid frame received\n", 1258 + __func__); 1259 + return -EINVAL; 1260 + } 1261 + 1262 + /** 1263 + * rsi_mgmt_pkt_recv() - This function processes the management packets 1264 + * recieved from the hardware. 1265 + * @common: Pointer to the driver private structure. 1266 + * @msg: Pointer to the received packet. 1267 + * 1268 + * Return: 0 on success, -1 on failure. 1269 + */ 1270 + int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg) 1271 + { 1272 + s32 msg_len = (le16_to_cpu(*(__le16 *)&msg[0]) & 0x0fff); 1273 + u16 msg_type = (msg[2]); 1274 + 1275 + rsi_dbg(FSM_ZONE, "%s: Msg Len: %d, Msg Type: %4x\n", 1276 + __func__, msg_len, msg_type); 1277 + 1278 + if (msg_type == TA_CONFIRM_TYPE) { 1279 + return rsi_handle_ta_confirm_type(common, msg); 1280 + } else if (msg_type == CARD_READY_IND) { 1281 + rsi_dbg(FSM_ZONE, "%s: Card ready indication received\n", 1282 + __func__); 1283 + if (common->fsm_state == FSM_CARD_NOT_READY) { 1284 + rsi_set_default_parameters(common); 1285 + 1286 + if (rsi_load_bootup_params(common)) 1287 + return -ENOMEM; 1288 + else 1289 + common->fsm_state = FSM_BOOT_PARAMS_SENT; 1290 + } else { 1291 + return -EINVAL; 1292 + } 1293 + } else if (msg_type == TX_STATUS_IND) { 1294 + if (msg[15] == PROBEREQ_CONFIRM) 1295 + common->mgmt_q_block = false; 1296 + rsi_dbg(FSM_ZONE, "%s: Probe confirm received\n", 1297 + __func__); 1298 + } else { 1299 + return rsi_mgmt_pkt_to_core(common, msg, msg_len, msg_type); 1300 + } 1301 + return 0; 1302 + }
+196
drivers/net/wireless/rsi/rsi_91x_pkt.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #include "rsi_mgmt.h" 18 + 19 + /** 20 + * rsi_send_data_pkt() - This function sends the recieved data packet from 21 + * driver to device. 22 + * @common: Pointer to the driver private structure. 23 + * @skb: Pointer to the socket buffer structure. 24 + * 25 + * Return: status: 0 on success, -1 on failure. 26 + */ 27 + int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb) 28 + { 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; 34 + int status = -EINVAL; 35 + u8 ieee80211_size = MIN_802_11_HDR_LEN; 36 + u8 extnd_size = 0; 37 + __le16 *frame_desc; 38 + u16 seq_num = 0; 39 + 40 + info = IEEE80211_SKB_CB(skb); 41 + bss = &info->control.vif->bss_conf; 42 + tx_params = (struct skb_info *)info->driver_data; 43 + 44 + if (!bss->assoc) 45 + goto err; 46 + 47 + tmp_hdr = (struct ieee80211_hdr *)&skb->data[0]; 48 + seq_num = (le16_to_cpu(tmp_hdr->seq_ctrl) >> 4); 49 + 50 + extnd_size = ((uintptr_t)skb->data & 0x3); 51 + 52 + if ((FRAME_DESC_SZ + extnd_size) > skb_headroom(skb)) { 53 + rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__); 54 + status = -ENOSPC; 55 + goto err; 56 + } 57 + 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); 61 + 62 + if (ieee80211_is_data_qos(tmp_hdr->frame_control)) { 63 + ieee80211_size += 2; 64 + frame_desc[6] |= cpu_to_le16(BIT(12)); 65 + } 66 + 67 + if ((!(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) && 68 + (common->secinfo.security_enable)) { 69 + if (rsi_is_cipher_wep(common)) 70 + ieee80211_size += 4; 71 + else 72 + ieee80211_size += 8; 73 + frame_desc[6] |= cpu_to_le16(BIT(15)); 74 + } 75 + 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); 79 + 80 + if (common->min_rate != 0xffff) { 81 + /* Send fixed rate */ 82 + frame_desc[3] = cpu_to_le16(RATE_INFO_ENABLE); 83 + frame_desc[4] = cpu_to_le16(common->min_rate); 84 + } 85 + 86 + frame_desc[6] |= cpu_to_le16(seq_num & 0xfff); 87 + frame_desc[7] = cpu_to_le16(((tx_params->tid & 0xf) << 4) | 88 + (skb->priority & 0xf) | 89 + (tx_params->sta_id << 8)); 90 + 91 + status = adapter->host_intf_write_pkt(common->priv, 92 + skb->data, 93 + skb->len); 94 + if (status) 95 + rsi_dbg(ERR_ZONE, "%s: Failed to write pkt\n", 96 + __func__); 97 + 98 + err: 99 + ++common->tx_stats.total_tx_pkt_freed[skb->priority]; 100 + rsi_indicate_tx_status(common->priv, skb, status); 101 + return status; 102 + } 103 + 104 + /** 105 + * rsi_send_mgmt_pkt() - This functions sends the received management packet 106 + * from driver to device. 107 + * @common: Pointer to the driver private structure. 108 + * @skb: Pointer to the socket buffer structure. 109 + * 110 + * Return: status: 0 on success, -1 on failure. 111 + */ 112 + int rsi_send_mgmt_pkt(struct rsi_common *common, 113 + struct sk_buff *skb) 114 + { 115 + struct rsi_hw *adapter = common->priv; 116 + struct ieee80211_hdr *wh = NULL; 117 + struct ieee80211_tx_info *info; 118 + struct ieee80211_bss_conf *bss = NULL; 119 + struct skb_info *tx_params; 120 + int status = -E2BIG; 121 + __le16 *msg = NULL; 122 + u8 extnd_size = 0; 123 + u8 vap_id = 0; 124 + 125 + info = IEEE80211_SKB_CB(skb); 126 + tx_params = (struct skb_info *)info->driver_data; 127 + extnd_size = ((uintptr_t)skb->data & 0x3); 128 + 129 + if (tx_params->flags & INTERNAL_MGMT_PKT) { 130 + if ((extnd_size) > skb_headroom(skb)) { 131 + rsi_dbg(ERR_ZONE, "%s: Unable to send pkt\n", __func__); 132 + dev_kfree_skb(skb); 133 + return -ENOSPC; 134 + } 135 + skb_push(skb, extnd_size); 136 + skb->data[extnd_size + 4] = extnd_size; 137 + status = adapter->host_intf_write_pkt(common->priv, 138 + (u8 *)skb->data, 139 + skb->len); 140 + if (status) { 141 + rsi_dbg(ERR_ZONE, 142 + "%s: Failed to write the packet\n", __func__); 143 + } 144 + dev_kfree_skb(skb); 145 + return status; 146 + } 147 + 148 + bss = &info->control.vif->bss_conf; 149 + wh = (struct ieee80211_hdr *)&skb->data[0]; 150 + 151 + if (FRAME_DESC_SZ > skb_headroom(skb)) 152 + goto err; 153 + 154 + skb_push(skb, FRAME_DESC_SZ); 155 + memset(skb->data, 0, FRAME_DESC_SZ); 156 + msg = (__le16 *)skb->data; 157 + 158 + if (skb->len > MAX_MGMT_PKT_SIZE) { 159 + rsi_dbg(INFO_ZONE, "%s: Dropping mgmt pkt > 512\n", __func__); 160 + goto err; 161 + } 162 + 163 + msg[0] = cpu_to_le16((skb->len - FRAME_DESC_SZ) | 164 + (RSI_WIFI_MGMT_Q << 12)); 165 + msg[1] = cpu_to_le16(TX_DOT11_MGMT); 166 + msg[2] = cpu_to_le16(MIN_802_11_HDR_LEN << 8); 167 + msg[3] = cpu_to_le16(RATE_INFO_ENABLE); 168 + msg[6] = cpu_to_le16(le16_to_cpu(wh->seq_ctrl) >> 4); 169 + 170 + if (wh->addr1[0] & BIT(0)) 171 + msg[3] |= cpu_to_le16(RSI_BROADCAST_PKT); 172 + 173 + if (common->band == IEEE80211_BAND_2GHZ) 174 + msg[4] = cpu_to_le16(RSI_11B_MODE); 175 + else 176 + msg[4] = cpu_to_le16((RSI_RATE_6 & 0x0f) | RSI_11G_MODE); 177 + 178 + /* Indicate to firmware to give cfm */ 179 + if ((skb->data[16] == IEEE80211_STYPE_PROBE_REQ) && (!bss->assoc)) { 180 + msg[1] |= cpu_to_le16(BIT(10)); 181 + msg[7] = cpu_to_le16(PROBEREQ_CONFIRM); 182 + common->mgmt_q_block = true; 183 + } 184 + 185 + msg[7] |= cpu_to_le16(vap_id << 8); 186 + 187 + status = adapter->host_intf_write_pkt(common->priv, 188 + (u8 *)msg, 189 + skb->len); 190 + if (status) 191 + rsi_dbg(ERR_ZONE, "%s: Failed to write the packet\n", __func__); 192 + 193 + err: 194 + rsi_indicate_tx_status(common->priv, skb, status); 195 + return status; 196 + }
+850
drivers/net/wireless/rsi/rsi_91x_sdio.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + * 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include "rsi_sdio.h" 20 + #include "rsi_common.h" 21 + 22 + /** 23 + * rsi_sdio_set_cmd52_arg() - This function prepares cmd 52 read/write arg. 24 + * @rw: Read/write 25 + * @func: function number 26 + * @raw: indicates whether to perform read after write 27 + * @address: address to which to read/write 28 + * @writedata: data to write 29 + * 30 + * Return: argument 31 + */ 32 + static u32 rsi_sdio_set_cmd52_arg(bool rw, 33 + u8 func, 34 + u8 raw, 35 + u32 address, 36 + u8 writedata) 37 + { 38 + return ((rw & 1) << 31) | ((func & 0x7) << 28) | 39 + ((raw & 1) << 27) | (1 << 26) | 40 + ((address & 0x1FFFF) << 9) | (1 << 8) | 41 + (writedata & 0xFF); 42 + } 43 + 44 + /** 45 + * rsi_cmd52writebyte() - This function issues cmd52 byte write onto the card. 46 + * @card: Pointer to the mmc_card. 47 + * @address: Address to write. 48 + * @byte: Data to write. 49 + * 50 + * Return: Write status. 51 + */ 52 + static int rsi_cmd52writebyte(struct mmc_card *card, 53 + u32 address, 54 + u8 byte) 55 + { 56 + struct mmc_command io_cmd; 57 + u32 arg; 58 + 59 + memset(&io_cmd, 0, sizeof(io_cmd)); 60 + arg = rsi_sdio_set_cmd52_arg(1, 0, 0, address, byte); 61 + io_cmd.opcode = SD_IO_RW_DIRECT; 62 + io_cmd.arg = arg; 63 + io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; 64 + 65 + return mmc_wait_for_cmd(card->host, &io_cmd, 0); 66 + } 67 + 68 + /** 69 + * rsi_cmd52readbyte() - This function issues cmd52 byte read onto the card. 70 + * @card: Pointer to the mmc_card. 71 + * @address: Address to read from. 72 + * @byte: Variable to store read value. 73 + * 74 + * Return: Read status. 75 + */ 76 + static int rsi_cmd52readbyte(struct mmc_card *card, 77 + u32 address, 78 + u8 *byte) 79 + { 80 + struct mmc_command io_cmd; 81 + u32 arg; 82 + int err; 83 + 84 + memset(&io_cmd, 0, sizeof(io_cmd)); 85 + arg = rsi_sdio_set_cmd52_arg(0, 0, 0, address, 0); 86 + io_cmd.opcode = SD_IO_RW_DIRECT; 87 + io_cmd.arg = arg; 88 + io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC; 89 + 90 + err = mmc_wait_for_cmd(card->host, &io_cmd, 0); 91 + if ((!err) && (byte)) 92 + *byte = io_cmd.resp[0] & 0xFF; 93 + return err; 94 + } 95 + 96 + /** 97 + * rsi_issue_sdiocommand() - This function issues sdio commands. 98 + * @func: Pointer to the sdio_func structure. 99 + * @opcode: Opcode value. 100 + * @arg: Arguments to pass. 101 + * @flags: Flags which are set. 102 + * @resp: Pointer to store response. 103 + * 104 + * Return: err: command status as 0 or -1. 105 + */ 106 + static int rsi_issue_sdiocommand(struct sdio_func *func, 107 + u32 opcode, 108 + u32 arg, 109 + u32 flags, 110 + u32 *resp) 111 + { 112 + struct mmc_command cmd; 113 + struct mmc_host *host; 114 + int err; 115 + 116 + host = func->card->host; 117 + 118 + memset(&cmd, 0, sizeof(struct mmc_command)); 119 + cmd.opcode = opcode; 120 + cmd.arg = arg; 121 + cmd.flags = flags; 122 + err = mmc_wait_for_cmd(host, &cmd, 3); 123 + 124 + if ((!err) && (resp)) 125 + *resp = cmd.resp[0]; 126 + 127 + return err; 128 + } 129 + 130 + /** 131 + * rsi_handle_interrupt() - This function is called upon the occurence 132 + * of an interrupt. 133 + * @function: Pointer to the sdio_func structure. 134 + * 135 + * Return: None. 136 + */ 137 + static void rsi_handle_interrupt(struct sdio_func *function) 138 + { 139 + struct rsi_hw *adapter = sdio_get_drvdata(function); 140 + 141 + sdio_release_host(function); 142 + rsi_interrupt_handler(adapter); 143 + sdio_claim_host(function); 144 + } 145 + 146 + /** 147 + * rsi_reset_card() - This function resets and re-initializes the card. 148 + * @pfunction: Pointer to the sdio_func structure. 149 + * 150 + * Return: None. 151 + */ 152 + static void rsi_reset_card(struct sdio_func *pfunction) 153 + { 154 + int ret = 0; 155 + int err; 156 + struct mmc_card *card = pfunction->card; 157 + struct mmc_host *host = card->host; 158 + s32 bit = (fls(host->ocr_avail) - 1); 159 + u8 cmd52_resp; 160 + u32 clock, resp, i; 161 + u16 rca; 162 + 163 + /* Reset 9110 chip */ 164 + ret = rsi_cmd52writebyte(pfunction->card, 165 + SDIO_CCCR_ABORT, 166 + (1 << 3)); 167 + 168 + /* Card will not send any response as it is getting reset immediately 169 + * Hence expect a timeout status from host controller 170 + */ 171 + if (ret != -ETIMEDOUT) 172 + rsi_dbg(ERR_ZONE, "%s: Reset failed : %d\n", __func__, ret); 173 + 174 + /* Wait for few milli seconds to get rid of residue charges if any */ 175 + msleep(20); 176 + 177 + /* Initialize the SDIO card */ 178 + host->ios.vdd = bit; 179 + host->ios.chip_select = MMC_CS_DONTCARE; 180 + host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; 181 + host->ios.power_mode = MMC_POWER_UP; 182 + host->ios.bus_width = MMC_BUS_WIDTH_1; 183 + host->ios.timing = MMC_TIMING_LEGACY; 184 + host->ops->set_ios(host, &host->ios); 185 + 186 + /* 187 + * This delay should be sufficient to allow the power supply 188 + * to reach the minimum voltage. 189 + */ 190 + msleep(20); 191 + 192 + host->ios.clock = host->f_min; 193 + host->ios.power_mode = MMC_POWER_ON; 194 + host->ops->set_ios(host, &host->ios); 195 + 196 + /* 197 + * This delay must be at least 74 clock sizes, or 1 ms, or the 198 + * time required to reach a stable voltage. 199 + */ 200 + msleep(20); 201 + 202 + /* Issue CMD0. Goto idle state */ 203 + host->ios.chip_select = MMC_CS_HIGH; 204 + host->ops->set_ios(host, &host->ios); 205 + msleep(20); 206 + err = rsi_issue_sdiocommand(pfunction, 207 + MMC_GO_IDLE_STATE, 208 + 0, 209 + (MMC_RSP_NONE | MMC_CMD_BC), 210 + NULL); 211 + host->ios.chip_select = MMC_CS_DONTCARE; 212 + host->ops->set_ios(host, &host->ios); 213 + msleep(20); 214 + host->use_spi_crc = 0; 215 + 216 + if (err) 217 + rsi_dbg(ERR_ZONE, "%s: CMD0 failed : %d\n", __func__, err); 218 + 219 + if (!host->ocr_avail) { 220 + /* Issue CMD5, arg = 0 */ 221 + err = rsi_issue_sdiocommand(pfunction, 222 + SD_IO_SEND_OP_COND, 223 + 0, 224 + (MMC_RSP_R4 | MMC_CMD_BCR), 225 + &resp); 226 + if (err) 227 + rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", 228 + __func__, err); 229 + host->ocr_avail = resp; 230 + } 231 + 232 + /* Issue CMD5, arg = ocr. Wait till card is ready */ 233 + for (i = 0; i < 100; i++) { 234 + err = rsi_issue_sdiocommand(pfunction, 235 + SD_IO_SEND_OP_COND, 236 + host->ocr_avail, 237 + (MMC_RSP_R4 | MMC_CMD_BCR), 238 + &resp); 239 + if (err) { 240 + rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", 241 + __func__, err); 242 + break; 243 + } 244 + 245 + if (resp & MMC_CARD_BUSY) 246 + break; 247 + msleep(20); 248 + } 249 + 250 + if ((i == 100) || (err)) { 251 + rsi_dbg(ERR_ZONE, "%s: card in not ready : %d %d\n", 252 + __func__, i, err); 253 + return; 254 + } 255 + 256 + /* Issue CMD3, get RCA */ 257 + err = rsi_issue_sdiocommand(pfunction, 258 + SD_SEND_RELATIVE_ADDR, 259 + 0, 260 + (MMC_RSP_R6 | MMC_CMD_BCR), 261 + &resp); 262 + if (err) { 263 + rsi_dbg(ERR_ZONE, "%s: CMD3 failed : %d\n", __func__, err); 264 + return; 265 + } 266 + rca = resp >> 16; 267 + host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; 268 + host->ops->set_ios(host, &host->ios); 269 + 270 + /* Issue CMD7, select card */ 271 + err = rsi_issue_sdiocommand(pfunction, 272 + MMC_SELECT_CARD, 273 + (rca << 16), 274 + (MMC_RSP_R1 | MMC_CMD_AC), 275 + NULL); 276 + if (err) { 277 + rsi_dbg(ERR_ZONE, "%s: CMD7 failed : %d\n", __func__, err); 278 + return; 279 + } 280 + 281 + /* Enable high speed */ 282 + if (card->host->caps & MMC_CAP_SD_HIGHSPEED) { 283 + rsi_dbg(ERR_ZONE, "%s: Set high speed mode\n", __func__); 284 + err = rsi_cmd52readbyte(card, SDIO_CCCR_SPEED, &cmd52_resp); 285 + if (err) { 286 + rsi_dbg(ERR_ZONE, "%s: CCCR speed reg read failed: %d\n", 287 + __func__, err); 288 + card->state &= ~MMC_STATE_HIGHSPEED; 289 + } else { 290 + err = rsi_cmd52writebyte(card, 291 + SDIO_CCCR_SPEED, 292 + (cmd52_resp | SDIO_SPEED_EHS)); 293 + if (err) { 294 + rsi_dbg(ERR_ZONE, 295 + "%s: CCR speed regwrite failed %d\n", 296 + __func__, err); 297 + return; 298 + } 299 + mmc_card_set_highspeed(card); 300 + host->ios.timing = MMC_TIMING_SD_HS; 301 + host->ops->set_ios(host, &host->ios); 302 + } 303 + } 304 + 305 + /* Set clock */ 306 + if (mmc_card_highspeed(card)) 307 + clock = 50000000; 308 + else 309 + clock = card->cis.max_dtr; 310 + 311 + if (clock > host->f_max) 312 + clock = host->f_max; 313 + 314 + host->ios.clock = clock; 315 + host->ops->set_ios(host, &host->ios); 316 + 317 + if (card->host->caps & MMC_CAP_4_BIT_DATA) { 318 + /* CMD52: Set bus width & disable card detect resistor */ 319 + err = rsi_cmd52writebyte(card, 320 + SDIO_CCCR_IF, 321 + (SDIO_BUS_CD_DISABLE | 322 + SDIO_BUS_WIDTH_4BIT)); 323 + if (err) { 324 + rsi_dbg(ERR_ZONE, "%s: Set bus mode failed : %d\n", 325 + __func__, err); 326 + return; 327 + } 328 + host->ios.bus_width = MMC_BUS_WIDTH_4; 329 + host->ops->set_ios(host, &host->ios); 330 + } 331 + } 332 + 333 + /** 334 + * rsi_setclock() - This function sets the clock frequency. 335 + * @adapter: Pointer to the adapter structure. 336 + * @freq: Clock frequency. 337 + * 338 + * Return: None. 339 + */ 340 + static void rsi_setclock(struct rsi_hw *adapter, u32 freq) 341 + { 342 + struct rsi_91x_sdiodev *dev = 343 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 344 + struct mmc_host *host = dev->pfunction->card->host; 345 + u32 clock; 346 + 347 + clock = freq * 1000; 348 + if (clock > host->f_max) 349 + clock = host->f_max; 350 + host->ios.clock = clock; 351 + host->ops->set_ios(host, &host->ios); 352 + } 353 + 354 + /** 355 + * rsi_setblocklength() - This function sets the host block length. 356 + * @adapter: Pointer to the adapter structure. 357 + * @length: Block length to be set. 358 + * 359 + * Return: status: 0 on success, -1 on failure. 360 + */ 361 + static int rsi_setblocklength(struct rsi_hw *adapter, u32 length) 362 + { 363 + struct rsi_91x_sdiodev *dev = 364 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 365 + int status; 366 + rsi_dbg(INIT_ZONE, "%s: Setting the block length\n", __func__); 367 + 368 + status = sdio_set_block_size(dev->pfunction, length); 369 + dev->pfunction->max_blksize = 256; 370 + 371 + rsi_dbg(INFO_ZONE, 372 + "%s: Operational blk length is %d\n", __func__, length); 373 + return status; 374 + } 375 + 376 + /** 377 + * rsi_setupcard() - This function queries and sets the card's features. 378 + * @adapter: Pointer to the adapter structure. 379 + * 380 + * Return: status: 0 on success, -1 on failure. 381 + */ 382 + static int rsi_setupcard(struct rsi_hw *adapter) 383 + { 384 + struct rsi_91x_sdiodev *dev = 385 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 386 + int status = 0; 387 + 388 + rsi_setclock(adapter, 50000); 389 + 390 + dev->tx_blk_size = 256; 391 + status = rsi_setblocklength(adapter, dev->tx_blk_size); 392 + if (status) 393 + rsi_dbg(ERR_ZONE, 394 + "%s: Unable to set block length\n", __func__); 395 + return status; 396 + } 397 + 398 + /** 399 + * rsi_sdio_read_register() - This function reads one byte of information 400 + * from a register. 401 + * @adapter: Pointer to the adapter structure. 402 + * @addr: Address of the register. 403 + * @data: Pointer to the data that stores the data read. 404 + * 405 + * Return: 0 on success, -1 on failure. 406 + */ 407 + int rsi_sdio_read_register(struct rsi_hw *adapter, 408 + u32 addr, 409 + u8 *data) 410 + { 411 + struct rsi_91x_sdiodev *dev = 412 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 413 + u8 fun_num = 0; 414 + int status; 415 + 416 + sdio_claim_host(dev->pfunction); 417 + 418 + if (fun_num == 0) 419 + *data = sdio_f0_readb(dev->pfunction, addr, &status); 420 + else 421 + *data = sdio_readb(dev->pfunction, addr, &status); 422 + 423 + sdio_release_host(dev->pfunction); 424 + 425 + return status; 426 + } 427 + 428 + /** 429 + * rsi_sdio_write_register() - This function writes one byte of information 430 + * into a register. 431 + * @adapter: Pointer to the adapter structure. 432 + * @function: Function Number. 433 + * @addr: Address of the register. 434 + * @data: Pointer to the data tha has to be written. 435 + * 436 + * Return: 0 on success, -1 on failure. 437 + */ 438 + int rsi_sdio_write_register(struct rsi_hw *adapter, 439 + u8 function, 440 + u32 addr, 441 + u8 *data) 442 + { 443 + struct rsi_91x_sdiodev *dev = 444 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 445 + int status = 0; 446 + 447 + sdio_claim_host(dev->pfunction); 448 + 449 + if (function == 0) 450 + sdio_f0_writeb(dev->pfunction, *data, addr, &status); 451 + else 452 + sdio_writeb(dev->pfunction, *data, addr, &status); 453 + 454 + sdio_release_host(dev->pfunction); 455 + 456 + return status; 457 + } 458 + 459 + /** 460 + * rsi_sdio_ack_intr() - This function acks the interrupt received. 461 + * @adapter: Pointer to the adapter structure. 462 + * @int_bit: Interrupt bit to write into register. 463 + * 464 + * Return: None. 465 + */ 466 + void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit) 467 + { 468 + int status; 469 + status = rsi_sdio_write_register(adapter, 470 + 1, 471 + (SDIO_FUN1_INTR_CLR_REG | 472 + RSI_SD_REQUEST_MASTER), 473 + &int_bit); 474 + if (status) 475 + rsi_dbg(ERR_ZONE, "%s: unable to send ack\n", __func__); 476 + } 477 + 478 + 479 + 480 + /** 481 + * rsi_sdio_read_register_multiple() - This function read multiple bytes of 482 + * information from the SD card. 483 + * @adapter: Pointer to the adapter structure. 484 + * @addr: Address of the register. 485 + * @count: Number of multiple bytes to be read. 486 + * @data: Pointer to the read data. 487 + * 488 + * Return: 0 on success, -1 on failure. 489 + */ 490 + static int rsi_sdio_read_register_multiple(struct rsi_hw *adapter, 491 + u32 addr, 492 + u32 count, 493 + u8 *data) 494 + { 495 + struct rsi_91x_sdiodev *dev = 496 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 497 + u32 status; 498 + 499 + sdio_claim_host(dev->pfunction); 500 + 501 + status = sdio_readsb(dev->pfunction, data, addr, count); 502 + 503 + sdio_release_host(dev->pfunction); 504 + 505 + if (status != 0) 506 + rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 read failed\n", __func__); 507 + return status; 508 + } 509 + 510 + /** 511 + * rsi_sdio_write_register_multiple() - This function writes multiple bytes of 512 + * information to the SD card. 513 + * @adapter: Pointer to the adapter structure. 514 + * @addr: Address of the register. 515 + * @data: Pointer to the data that has to be written. 516 + * @count: Number of multiple bytes to be written. 517 + * 518 + * Return: 0 on success, -1 on failure. 519 + */ 520 + int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, 521 + u32 addr, 522 + u8 *data, 523 + u32 count) 524 + { 525 + struct rsi_91x_sdiodev *dev = 526 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 527 + int status; 528 + 529 + if (dev->write_fail > 1) { 530 + rsi_dbg(ERR_ZONE, "%s: Stopping card writes\n", __func__); 531 + return 0; 532 + } else if (dev->write_fail == 1) { 533 + /** 534 + * Assuming it is a CRC failure, we want to allow another 535 + * card write 536 + */ 537 + rsi_dbg(ERR_ZONE, "%s: Continue card writes\n", __func__); 538 + dev->write_fail++; 539 + } 540 + 541 + sdio_claim_host(dev->pfunction); 542 + 543 + status = sdio_writesb(dev->pfunction, addr, data, count); 544 + 545 + sdio_release_host(dev->pfunction); 546 + 547 + if (status) { 548 + rsi_dbg(ERR_ZONE, "%s: Synch Cmd53 write failed %d\n", 549 + __func__, status); 550 + dev->write_fail = 2; 551 + } else { 552 + memcpy(dev->prev_desc, data, FRAME_DESC_SZ); 553 + } 554 + return status; 555 + } 556 + 557 + /** 558 + * rsi_sdio_host_intf_write_pkt() - This function writes the packet to device. 559 + * @adapter: Pointer to the adapter structure. 560 + * @pkt: Pointer to the data to be written on to the device. 561 + * @len: length of the data to be written on to the device. 562 + * 563 + * Return: 0 on success, -1 on failure. 564 + */ 565 + static int rsi_sdio_host_intf_write_pkt(struct rsi_hw *adapter, 566 + u8 *pkt, 567 + u32 len) 568 + { 569 + struct rsi_91x_sdiodev *dev = 570 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 571 + u32 block_size = dev->tx_blk_size; 572 + u32 num_blocks, address, length; 573 + u32 queueno; 574 + int status; 575 + 576 + queueno = ((pkt[1] >> 4) & 0xf); 577 + 578 + num_blocks = len / block_size; 579 + 580 + if (len % block_size) 581 + num_blocks++; 582 + 583 + address = (num_blocks * block_size | (queueno << 12)); 584 + length = num_blocks * block_size; 585 + 586 + status = rsi_sdio_write_register_multiple(adapter, 587 + address, 588 + (u8 *)pkt, 589 + length); 590 + if (status) 591 + rsi_dbg(ERR_ZONE, "%s: Unable to write onto the card: %d\n", 592 + __func__, status); 593 + rsi_dbg(DATA_TX_ZONE, "%s: Successfully written onto card\n", __func__); 594 + return status; 595 + } 596 + 597 + /** 598 + * rsi_sdio_host_intf_read_pkt() - This function reads the packet 599 + from the device. 600 + * @adapter: Pointer to the adapter data structure. 601 + * @pkt: Pointer to the packet data to be read from the the device. 602 + * @length: Length of the data to be read from the device. 603 + * 604 + * Return: 0 on success, -1 on failure. 605 + */ 606 + int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, 607 + u8 *pkt, 608 + u32 length) 609 + { 610 + int status = -EINVAL; 611 + 612 + if (!length) { 613 + rsi_dbg(ERR_ZONE, "%s: Pkt size is zero\n", __func__); 614 + return status; 615 + } 616 + 617 + status = rsi_sdio_read_register_multiple(adapter, 618 + length, 619 + length, /*num of bytes*/ 620 + (u8 *)pkt); 621 + 622 + if (status) 623 + rsi_dbg(ERR_ZONE, "%s: Failed to read frame: %d\n", __func__, 624 + status); 625 + return status; 626 + } 627 + 628 + /** 629 + * rsi_init_sdio_interface() - This function does init specific to SDIO. 630 + * 631 + * @adapter: Pointer to the adapter data structure. 632 + * @pkt: Pointer to the packet data to be read from the the device. 633 + * 634 + * Return: 0 on success, -1 on failure. 635 + */ 636 + 637 + static int rsi_init_sdio_interface(struct rsi_hw *adapter, 638 + struct sdio_func *pfunction) 639 + { 640 + struct rsi_91x_sdiodev *rsi_91x_dev; 641 + int status = -ENOMEM; 642 + 643 + rsi_91x_dev = kzalloc(sizeof(*rsi_91x_dev), GFP_KERNEL); 644 + if (!rsi_91x_dev) 645 + return status; 646 + 647 + adapter->rsi_dev = rsi_91x_dev; 648 + 649 + sdio_claim_host(pfunction); 650 + 651 + pfunction->enable_timeout = 100; 652 + status = sdio_enable_func(pfunction); 653 + if (status) { 654 + rsi_dbg(ERR_ZONE, "%s: Failed to enable interface\n", __func__); 655 + sdio_release_host(pfunction); 656 + return status; 657 + } 658 + 659 + rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); 660 + 661 + rsi_91x_dev->pfunction = pfunction; 662 + adapter->device = &pfunction->dev; 663 + 664 + sdio_set_drvdata(pfunction, adapter); 665 + 666 + status = rsi_setupcard(adapter); 667 + if (status) { 668 + rsi_dbg(ERR_ZONE, "%s: Failed to setup card\n", __func__); 669 + goto fail; 670 + } 671 + 672 + rsi_dbg(INIT_ZONE, "%s: Setup card succesfully\n", __func__); 673 + 674 + status = rsi_init_sdio_slave_regs(adapter); 675 + if (status) { 676 + rsi_dbg(ERR_ZONE, "%s: Failed to init slave regs\n", __func__); 677 + goto fail; 678 + } 679 + sdio_release_host(pfunction); 680 + 681 + adapter->host_intf_write_pkt = rsi_sdio_host_intf_write_pkt; 682 + adapter->host_intf_read_pkt = rsi_sdio_host_intf_read_pkt; 683 + adapter->determine_event_timeout = rsi_sdio_determine_event_timeout; 684 + adapter->check_hw_queue_status = rsi_sdio_read_buffer_status_register; 685 + 686 + #ifdef CONFIG_RSI_DEBUGFS 687 + adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES; 688 + #endif 689 + return status; 690 + fail: 691 + sdio_disable_func(pfunction); 692 + sdio_release_host(pfunction); 693 + return status; 694 + } 695 + 696 + /** 697 + * rsi_probe() - This function is called by kernel when the driver provided 698 + * Vendor and device IDs are matched. All the initialization 699 + * work is done here. 700 + * @pfunction: Pointer to the sdio_func structure. 701 + * @id: Pointer to sdio_device_id structure. 702 + * 703 + * Return: 0 on success, 1 on failure. 704 + */ 705 + static int rsi_probe(struct sdio_func *pfunction, 706 + const struct sdio_device_id *id) 707 + { 708 + struct rsi_hw *adapter; 709 + 710 + rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); 711 + 712 + adapter = rsi_91x_init(); 713 + if (!adapter) { 714 + rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n", 715 + __func__); 716 + return 1; 717 + } 718 + 719 + if (rsi_init_sdio_interface(adapter, pfunction)) { 720 + rsi_dbg(ERR_ZONE, "%s: Failed to init sdio interface\n", 721 + __func__); 722 + goto fail; 723 + } 724 + 725 + if (rsi_sdio_device_init(adapter->priv)) { 726 + rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", __func__); 727 + sdio_claim_host(pfunction); 728 + sdio_disable_func(pfunction); 729 + sdio_release_host(pfunction); 730 + goto fail; 731 + } 732 + 733 + sdio_claim_host(pfunction); 734 + if (sdio_claim_irq(pfunction, rsi_handle_interrupt)) { 735 + rsi_dbg(ERR_ZONE, "%s: Failed to request IRQ\n", __func__); 736 + sdio_release_host(pfunction); 737 + goto fail; 738 + } 739 + 740 + sdio_release_host(pfunction); 741 + rsi_dbg(INIT_ZONE, "%s: Registered Interrupt handler\n", __func__); 742 + 743 + return 0; 744 + fail: 745 + rsi_91x_deinit(adapter); 746 + rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); 747 + return 1; 748 + } 749 + 750 + /** 751 + * rsi_disconnect() - This function performs the reverse of the probe function. 752 + * @pfunction: Pointer to the sdio_func structure. 753 + * 754 + * Return: void. 755 + */ 756 + static void rsi_disconnect(struct sdio_func *pfunction) 757 + { 758 + struct rsi_hw *adapter = sdio_get_drvdata(pfunction); 759 + struct rsi_91x_sdiodev *dev = 760 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 761 + 762 + if (!adapter) 763 + return; 764 + 765 + dev->write_fail = 2; 766 + rsi_mac80211_detach(adapter); 767 + 768 + sdio_claim_host(pfunction); 769 + sdio_release_irq(pfunction); 770 + sdio_disable_func(pfunction); 771 + rsi_91x_deinit(adapter); 772 + /* Resetting to take care of the case, where-in driver is re-loaded */ 773 + rsi_reset_card(pfunction); 774 + sdio_release_host(pfunction); 775 + } 776 + 777 + #ifdef CONFIG_PM 778 + static int rsi_suspend(struct device *dev) 779 + { 780 + /* Not yet implemented */ 781 + return -ENOSYS; 782 + } 783 + 784 + static int rsi_resume(struct device *dev) 785 + { 786 + /* Not yet implemented */ 787 + return -ENOSYS; 788 + } 789 + 790 + static const struct dev_pm_ops rsi_pm_ops = { 791 + .suspend = rsi_suspend, 792 + .resume = rsi_resume, 793 + }; 794 + #endif 795 + 796 + static const struct sdio_device_id rsi_dev_table[] = { 797 + { SDIO_DEVICE(0x303, 0x100) }, 798 + { SDIO_DEVICE(0x041B, 0x0301) }, 799 + { SDIO_DEVICE(0x041B, 0x0201) }, 800 + { SDIO_DEVICE(0x041B, 0x9330) }, 801 + { /* Blank */}, 802 + }; 803 + 804 + static struct sdio_driver rsi_driver = { 805 + .name = "RSI-SDIO WLAN", 806 + .probe = rsi_probe, 807 + .remove = rsi_disconnect, 808 + .id_table = rsi_dev_table, 809 + #ifdef CONFIG_PM 810 + .drv = { 811 + .pm = &rsi_pm_ops, 812 + } 813 + #endif 814 + }; 815 + 816 + /** 817 + * rsi_module_init() - This function registers the sdio module. 818 + * @void: Void. 819 + * 820 + * Return: 0 on success. 821 + */ 822 + static int rsi_module_init(void) 823 + { 824 + sdio_register_driver(&rsi_driver); 825 + rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__); 826 + return 0; 827 + } 828 + 829 + /** 830 + * rsi_module_exit() - This function unregisters the sdio module. 831 + * @void: Void. 832 + * 833 + * Return: None. 834 + */ 835 + static void rsi_module_exit(void) 836 + { 837 + sdio_unregister_driver(&rsi_driver); 838 + rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__); 839 + } 840 + 841 + module_init(rsi_module_init); 842 + module_exit(rsi_module_exit); 843 + 844 + MODULE_AUTHOR("Redpine Signals Inc"); 845 + MODULE_DESCRIPTION("Common SDIO layer for RSI drivers"); 846 + MODULE_SUPPORTED_DEVICE("RSI-91x"); 847 + MODULE_DEVICE_TABLE(sdio, rsi_dev_table); 848 + MODULE_FIRMWARE(FIRMWARE_RSI9113); 849 + MODULE_VERSION("0.1"); 850 + MODULE_LICENSE("Dual BSD/GPL");
+566
drivers/net/wireless/rsi/rsi_91x_sdio_ops.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + * 16 + */ 17 + 18 + #include <linux/firmware.h> 19 + #include "rsi_sdio.h" 20 + #include "rsi_common.h" 21 + 22 + /** 23 + * rsi_sdio_master_access_msword() - This function sets the AHB master access 24 + * MS word in the SDIO slave registers. 25 + * @adapter: Pointer to the adapter structure. 26 + * @ms_word: ms word need to be initialized. 27 + * 28 + * Return: status: 0 on success, -1 on failure. 29 + */ 30 + static int rsi_sdio_master_access_msword(struct rsi_hw *adapter, 31 + u16 ms_word) 32 + { 33 + u8 byte; 34 + u8 function = 0; 35 + int status = 0; 36 + 37 + byte = (u8)(ms_word & 0x00FF); 38 + 39 + rsi_dbg(INIT_ZONE, 40 + "%s: MASTER_ACCESS_MSBYTE:0x%x\n", __func__, byte); 41 + 42 + status = rsi_sdio_write_register(adapter, 43 + function, 44 + SDIO_MASTER_ACCESS_MSBYTE, 45 + &byte); 46 + if (status) { 47 + rsi_dbg(ERR_ZONE, 48 + "%s: fail to access MASTER_ACCESS_MSBYTE\n", 49 + __func__); 50 + return -1; 51 + } 52 + 53 + byte = (u8)(ms_word >> 8); 54 + 55 + rsi_dbg(INIT_ZONE, "%s:MASTER_ACCESS_LSBYTE:0x%x\n", __func__, byte); 56 + status = rsi_sdio_write_register(adapter, 57 + function, 58 + SDIO_MASTER_ACCESS_LSBYTE, 59 + &byte); 60 + return status; 61 + } 62 + 63 + /** 64 + * rsi_copy_to_card() - This function includes the actual funtionality of 65 + * copying the TA firmware to the card.Basically this 66 + * function includes opening the TA file,reading the 67 + * TA file and writing their values in blocks of data. 68 + * @common: Pointer to the driver private structure. 69 + * @fw: Pointer to the firmware value to be written. 70 + * @len: length of firmware file. 71 + * @num_blocks: Number of blocks to be written to the card. 72 + * 73 + * Return: 0 on success and -1 on failure. 74 + */ 75 + static int rsi_copy_to_card(struct rsi_common *common, 76 + const u8 *fw, 77 + u32 len, 78 + u32 num_blocks) 79 + { 80 + struct rsi_hw *adapter = common->priv; 81 + struct rsi_91x_sdiodev *dev = 82 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 83 + u32 indx, ii; 84 + u32 block_size = dev->tx_blk_size; 85 + u32 lsb_address; 86 + __le32 data[] = { TA_HOLD_THREAD_VALUE, TA_SOFT_RST_CLR, 87 + TA_PC_ZERO, TA_RELEASE_THREAD_VALUE }; 88 + u32 address[] = { TA_HOLD_THREAD_REG, TA_SOFT_RESET_REG, 89 + TA_TH0_PC_REG, TA_RELEASE_THREAD_REG }; 90 + u32 base_address; 91 + u16 msb_address; 92 + 93 + base_address = TA_LOAD_ADDRESS; 94 + msb_address = base_address >> 16; 95 + 96 + for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) { 97 + lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); 98 + if (rsi_sdio_write_register_multiple(adapter, 99 + lsb_address, 100 + (u8 *)(fw + indx), 101 + block_size)) { 102 + rsi_dbg(ERR_ZONE, 103 + "%s: Unable to load %s blk\n", __func__, 104 + FIRMWARE_RSI9113); 105 + return -1; 106 + } 107 + rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii); 108 + base_address += block_size; 109 + if ((base_address >> 16) != msb_address) { 110 + msb_address += 1; 111 + if (rsi_sdio_master_access_msword(adapter, 112 + msb_address)) { 113 + rsi_dbg(ERR_ZONE, 114 + "%s: Unable to set ms word reg\n", 115 + __func__); 116 + return -1; 117 + } 118 + } 119 + } 120 + 121 + if (len % block_size) { 122 + lsb_address = ((u16) base_address | RSI_SD_REQUEST_MASTER); 123 + if (rsi_sdio_write_register_multiple(adapter, 124 + lsb_address, 125 + (u8 *)(fw + indx), 126 + len % block_size)) { 127 + rsi_dbg(ERR_ZONE, 128 + "%s: Unable to load f/w\n", __func__); 129 + return -1; 130 + } 131 + } 132 + rsi_dbg(INIT_ZONE, 133 + "%s: Succesfully loaded TA instructions\n", __func__); 134 + 135 + if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) { 136 + rsi_dbg(ERR_ZONE, 137 + "%s: Unable to set ms word to common reg\n", 138 + __func__); 139 + return -1; 140 + } 141 + 142 + for (ii = 0; ii < ARRAY_SIZE(data); ii++) { 143 + /* Bringing TA out of reset */ 144 + if (rsi_sdio_write_register_multiple(adapter, 145 + (address[ii] | 146 + RSI_SD_REQUEST_MASTER), 147 + (u8 *)&data[ii], 148 + 4)) { 149 + rsi_dbg(ERR_ZONE, 150 + "%s: Unable to hold TA threads\n", __func__); 151 + return -1; 152 + } 153 + } 154 + 155 + rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__); 156 + return 0; 157 + } 158 + 159 + /** 160 + * rsi_load_ta_instructions() - This function includes the actual funtionality 161 + * of loading the TA firmware.This function also 162 + * includes opening the TA file,reading the TA 163 + * file and writing their value in blocks of data. 164 + * @common: Pointer to the driver private structure. 165 + * 166 + * Return: status: 0 on success, -1 on failure. 167 + */ 168 + static int rsi_load_ta_instructions(struct rsi_common *common) 169 + { 170 + struct rsi_hw *adapter = common->priv; 171 + struct rsi_91x_sdiodev *dev = 172 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 173 + u32 len; 174 + u32 num_blocks; 175 + const u8 *fw; 176 + const struct firmware *fw_entry = NULL; 177 + u32 block_size = dev->tx_blk_size; 178 + int status = 0; 179 + u32 base_address; 180 + u16 msb_address; 181 + 182 + if (rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR)) { 183 + rsi_dbg(ERR_ZONE, 184 + "%s: Unable to set ms word to common reg\n", 185 + __func__); 186 + return -1; 187 + } 188 + base_address = TA_LOAD_ADDRESS; 189 + msb_address = (base_address >> 16); 190 + 191 + if (rsi_sdio_master_access_msword(adapter, msb_address)) { 192 + rsi_dbg(ERR_ZONE, 193 + "%s: Unable to set ms word reg\n", __func__); 194 + return -1; 195 + } 196 + 197 + status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device); 198 + if (status < 0) { 199 + rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n", 200 + __func__, FIRMWARE_RSI9113); 201 + return status; 202 + } 203 + 204 + fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); 205 + len = fw_entry->size; 206 + 207 + if (len % 4) 208 + len += (4 - (len % 4)); 209 + 210 + num_blocks = (len / block_size); 211 + 212 + rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); 213 + rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); 214 + 215 + status = rsi_copy_to_card(common, fw, len, num_blocks); 216 + release_firmware(fw_entry); 217 + return status; 218 + } 219 + 220 + /** 221 + * rsi_process_pkt() - This Function reads rx_blocks register and figures out 222 + * the size of the rx pkt. 223 + * @common: Pointer to the driver private structure. 224 + * 225 + * Return: 0 on success, -1 on failure. 226 + */ 227 + static int rsi_process_pkt(struct rsi_common *common) 228 + { 229 + struct rsi_hw *adapter = common->priv; 230 + u8 num_blks = 0; 231 + u32 rcv_pkt_len = 0; 232 + int status = 0; 233 + 234 + status = rsi_sdio_read_register(adapter, 235 + SDIO_RX_NUM_BLOCKS_REG, 236 + &num_blks); 237 + 238 + if (status) { 239 + rsi_dbg(ERR_ZONE, 240 + "%s: Failed to read pkt length from the card:\n", 241 + __func__); 242 + return status; 243 + } 244 + rcv_pkt_len = (num_blks * 256); 245 + 246 + common->rx_data_pkt = kmalloc(rcv_pkt_len, GFP_KERNEL); 247 + if (!common->rx_data_pkt) { 248 + rsi_dbg(ERR_ZONE, "%s: Failed in memory allocation\n", 249 + __func__); 250 + return -1; 251 + } 252 + 253 + status = rsi_sdio_host_intf_read_pkt(adapter, 254 + common->rx_data_pkt, 255 + rcv_pkt_len); 256 + if (status) { 257 + rsi_dbg(ERR_ZONE, "%s: Failed to read packet from card\n", 258 + __func__); 259 + goto fail; 260 + } 261 + 262 + status = rsi_read_pkt(common, rcv_pkt_len); 263 + kfree(common->rx_data_pkt); 264 + return status; 265 + 266 + fail: 267 + kfree(common->rx_data_pkt); 268 + return -1; 269 + } 270 + 271 + /** 272 + * rsi_init_sdio_slave_regs() - This function does the actual initialization 273 + * of SDBUS slave registers. 274 + * @adapter: Pointer to the adapter structure. 275 + * 276 + * Return: status: 0 on success, -1 on failure. 277 + */ 278 + int rsi_init_sdio_slave_regs(struct rsi_hw *adapter) 279 + { 280 + struct rsi_91x_sdiodev *dev = 281 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 282 + u8 function = 0; 283 + u8 byte; 284 + int status = 0; 285 + 286 + if (dev->next_read_delay) { 287 + byte = dev->next_read_delay; 288 + status = rsi_sdio_write_register(adapter, 289 + function, 290 + SDIO_NXT_RD_DELAY2, 291 + &byte); 292 + if (status) { 293 + rsi_dbg(ERR_ZONE, 294 + "%s: Failed to write SDIO_NXT_RD_DELAY2\n", 295 + __func__); 296 + return -1; 297 + } 298 + } 299 + 300 + if (dev->sdio_high_speed_enable) { 301 + rsi_dbg(INIT_ZONE, "%s: Enabling SDIO High speed\n", __func__); 302 + byte = 0x3; 303 + 304 + status = rsi_sdio_write_register(adapter, 305 + function, 306 + SDIO_REG_HIGH_SPEED, 307 + &byte); 308 + if (status) { 309 + rsi_dbg(ERR_ZONE, 310 + "%s: Failed to enable SDIO high speed\n", 311 + __func__); 312 + return -1; 313 + } 314 + } 315 + 316 + /* This tells SDIO FIFO when to start read to host */ 317 + rsi_dbg(INIT_ZONE, "%s: Initialzing SDIO read start level\n", __func__); 318 + byte = 0x24; 319 + 320 + status = rsi_sdio_write_register(adapter, 321 + function, 322 + SDIO_READ_START_LVL, 323 + &byte); 324 + if (status) { 325 + rsi_dbg(ERR_ZONE, 326 + "%s: Failed to write SDIO_READ_START_LVL\n", __func__); 327 + return -1; 328 + } 329 + 330 + rsi_dbg(INIT_ZONE, "%s: Initialzing FIFO ctrl registers\n", __func__); 331 + byte = (128 - 32); 332 + 333 + status = rsi_sdio_write_register(adapter, 334 + function, 335 + SDIO_READ_FIFO_CTL, 336 + &byte); 337 + if (status) { 338 + rsi_dbg(ERR_ZONE, 339 + "%s: Failed to write SDIO_READ_FIFO_CTL\n", __func__); 340 + return -1; 341 + } 342 + 343 + byte = 32; 344 + status = rsi_sdio_write_register(adapter, 345 + function, 346 + SDIO_WRITE_FIFO_CTL, 347 + &byte); 348 + if (status) { 349 + rsi_dbg(ERR_ZONE, 350 + "%s: Failed to write SDIO_WRITE_FIFO_CTL\n", __func__); 351 + return -1; 352 + } 353 + 354 + return 0; 355 + } 356 + 357 + /** 358 + * rsi_interrupt_handler() - This function read and process SDIO interrupts. 359 + * @adapter: Pointer to the adapter structure. 360 + * 361 + * Return: None. 362 + */ 363 + void rsi_interrupt_handler(struct rsi_hw *adapter) 364 + { 365 + struct rsi_common *common = adapter->priv; 366 + struct rsi_91x_sdiodev *dev = 367 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 368 + int status; 369 + enum sdio_interrupt_type isr_type; 370 + u8 isr_status = 0; 371 + u8 fw_status = 0; 372 + 373 + dev->rx_info.sdio_int_counter++; 374 + 375 + do { 376 + mutex_lock(&common->tx_rxlock); 377 + status = rsi_sdio_read_register(common->priv, 378 + RSI_FN1_INT_REGISTER, 379 + &isr_status); 380 + if (status) { 381 + rsi_dbg(ERR_ZONE, 382 + "%s: Failed to Read Intr Status Register\n", 383 + __func__); 384 + mutex_unlock(&common->tx_rxlock); 385 + return; 386 + } 387 + 388 + if (isr_status == 0) { 389 + rsi_set_event(&common->tx_thread.event); 390 + dev->rx_info.sdio_intr_status_zero++; 391 + mutex_unlock(&common->tx_rxlock); 392 + return; 393 + } 394 + 395 + rsi_dbg(ISR_ZONE, "%s: Intr_status = %x %d %d\n", 396 + __func__, isr_status, (1 << MSDU_PKT_PENDING), 397 + (1 << FW_ASSERT_IND)); 398 + 399 + do { 400 + RSI_GET_SDIO_INTERRUPT_TYPE(isr_status, isr_type); 401 + 402 + switch (isr_type) { 403 + case BUFFER_AVAILABLE: 404 + dev->rx_info.watch_bufferfull_count = 0; 405 + dev->rx_info.buffer_full = false; 406 + dev->rx_info.mgmt_buffer_full = false; 407 + rsi_sdio_ack_intr(common->priv, 408 + (1 << PKT_BUFF_AVAILABLE)); 409 + rsi_set_event((&common->tx_thread.event)); 410 + rsi_dbg(ISR_ZONE, 411 + "%s: ==> BUFFER_AVILABLE <==\n", 412 + __func__); 413 + dev->rx_info.buf_avilable_counter++; 414 + break; 415 + 416 + case FIRMWARE_ASSERT_IND: 417 + rsi_dbg(ERR_ZONE, 418 + "%s: ==> FIRMWARE Assert <==\n", 419 + __func__); 420 + status = rsi_sdio_read_register(common->priv, 421 + SDIO_FW_STATUS_REG, 422 + &fw_status); 423 + if (status) { 424 + rsi_dbg(ERR_ZONE, 425 + "%s: Failed to read f/w reg\n", 426 + __func__); 427 + } else { 428 + rsi_dbg(ERR_ZONE, 429 + "%s: Firmware Status is 0x%x\n", 430 + __func__ , fw_status); 431 + rsi_sdio_ack_intr(common->priv, 432 + (1 << FW_ASSERT_IND)); 433 + } 434 + 435 + common->fsm_state = FSM_CARD_NOT_READY; 436 + break; 437 + 438 + case MSDU_PACKET_PENDING: 439 + rsi_dbg(ISR_ZONE, "Pkt pending interrupt\n"); 440 + dev->rx_info.total_sdio_msdu_pending_intr++; 441 + 442 + status = rsi_process_pkt(common); 443 + if (status) { 444 + rsi_dbg(ERR_ZONE, 445 + "%s: Failed to read pkt\n", 446 + __func__); 447 + mutex_unlock(&common->tx_rxlock); 448 + return; 449 + } 450 + break; 451 + default: 452 + rsi_sdio_ack_intr(common->priv, isr_status); 453 + dev->rx_info.total_sdio_unknown_intr++; 454 + isr_status = 0; 455 + rsi_dbg(ISR_ZONE, 456 + "Unknown Interrupt %x\n", 457 + isr_status); 458 + break; 459 + } 460 + isr_status ^= BIT(isr_type - 1); 461 + } while (isr_status); 462 + mutex_unlock(&common->tx_rxlock); 463 + } while (1); 464 + } 465 + 466 + /** 467 + * rsi_device_init() - This Function Initializes The HAL. 468 + * @common: Pointer to the driver private structure. 469 + * 470 + * Return: 0 on success, -1 on failure. 471 + */ 472 + int rsi_sdio_device_init(struct rsi_common *common) 473 + { 474 + if (rsi_load_ta_instructions(common)) 475 + return -1; 476 + 477 + if (rsi_sdio_master_access_msword(common->priv, MISC_CFG_BASE_ADDR)) { 478 + rsi_dbg(ERR_ZONE, "%s: Unable to set ms word reg\n", 479 + __func__); 480 + return -1; 481 + } 482 + rsi_dbg(INIT_ZONE, 483 + "%s: Setting ms word to 0x41050000\n", __func__); 484 + 485 + return 0; 486 + } 487 + 488 + /** 489 + * rsi_sdio_read_buffer_status_register() - This function is used to the read 490 + * buffer status register and set 491 + * relevant fields in 492 + * rsi_91x_sdiodev struct. 493 + * @adapter: Pointer to the driver hw structure. 494 + * @q_num: The Q number whose status is to be found. 495 + * 496 + * Return: status: -1 on failure or else queue full/stop is indicated. 497 + */ 498 + int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num) 499 + { 500 + struct rsi_common *common = adapter->priv; 501 + struct rsi_91x_sdiodev *dev = 502 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 503 + u8 buf_status = 0; 504 + int status = 0; 505 + 506 + status = rsi_sdio_read_register(common->priv, 507 + RSI_DEVICE_BUFFER_STATUS_REGISTER, 508 + &buf_status); 509 + 510 + if (status) { 511 + rsi_dbg(ERR_ZONE, 512 + "%s: Failed to read status register\n", __func__); 513 + return -1; 514 + } 515 + 516 + if (buf_status & (BIT(PKT_MGMT_BUFF_FULL))) { 517 + if (!dev->rx_info.mgmt_buffer_full) 518 + dev->rx_info.mgmt_buf_full_counter++; 519 + dev->rx_info.mgmt_buffer_full = true; 520 + } else { 521 + dev->rx_info.mgmt_buffer_full = false; 522 + } 523 + 524 + if (buf_status & (BIT(PKT_BUFF_FULL))) { 525 + if (!dev->rx_info.buffer_full) 526 + dev->rx_info.buf_full_counter++; 527 + dev->rx_info.buffer_full = true; 528 + } else { 529 + dev->rx_info.buffer_full = false; 530 + } 531 + 532 + if (buf_status & (BIT(PKT_BUFF_SEMI_FULL))) { 533 + if (!dev->rx_info.semi_buffer_full) 534 + dev->rx_info.buf_semi_full_counter++; 535 + dev->rx_info.semi_buffer_full = true; 536 + } else { 537 + dev->rx_info.semi_buffer_full = false; 538 + } 539 + 540 + if ((q_num == MGMT_SOFT_Q) && (dev->rx_info.mgmt_buffer_full)) 541 + return QUEUE_FULL; 542 + 543 + if (dev->rx_info.buffer_full) 544 + return QUEUE_FULL; 545 + 546 + return QUEUE_NOT_FULL; 547 + } 548 + 549 + /** 550 + * rsi_sdio_determine_event_timeout() - This Function determines the event 551 + * timeout duration. 552 + * @adapter: Pointer to the adapter structure. 553 + * 554 + * Return: timeout duration is returned. 555 + */ 556 + int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter) 557 + { 558 + struct rsi_91x_sdiodev *dev = 559 + (struct rsi_91x_sdiodev *)adapter->rsi_dev; 560 + 561 + /* Once buffer full is seen, event timeout to occur every 2 msecs */ 562 + if (dev->rx_info.buffer_full) 563 + return 2; 564 + 565 + return EVENT_WAIT_FOREVER; 566 + }
+575
drivers/net/wireless/rsi/rsi_91x_usb.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + * 16 + */ 17 + 18 + #include <linux/module.h> 19 + #include "rsi_usb.h" 20 + 21 + /** 22 + * rsi_usb_card_write() - This function writes to the USB Card. 23 + * @adapter: Pointer to the adapter structure. 24 + * @buf: Pointer to the buffer from where the data has to be taken. 25 + * @len: Length to be written. 26 + * @endpoint: Type of endpoint. 27 + * 28 + * Return: status: 0 on success, -1 on failure. 29 + */ 30 + static int rsi_usb_card_write(struct rsi_hw *adapter, 31 + void *buf, 32 + u16 len, 33 + u8 endpoint) 34 + { 35 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 36 + int status; 37 + s32 transfer; 38 + 39 + status = usb_bulk_msg(dev->usbdev, 40 + usb_sndbulkpipe(dev->usbdev, 41 + dev->bulkout_endpoint_addr[endpoint - 1]), 42 + buf, 43 + len, 44 + &transfer, 45 + HZ * 5); 46 + 47 + if (status < 0) { 48 + rsi_dbg(ERR_ZONE, 49 + "Card write failed with error code :%10d\n", status); 50 + dev->write_fail = 1; 51 + } 52 + return status; 53 + } 54 + 55 + /** 56 + * rsi_write_multiple() - This function writes multiple bytes of information 57 + * to the USB card. 58 + * @adapter: Pointer to the adapter structure. 59 + * @addr: Address of the register. 60 + * @data: Pointer to the data that has to be written. 61 + * @count: Number of multiple bytes to be written. 62 + * 63 + * Return: 0 on success, -1 on failure. 64 + */ 65 + static int rsi_write_multiple(struct rsi_hw *adapter, 66 + u8 endpoint, 67 + u8 *data, 68 + u32 count) 69 + { 70 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 71 + u8 *seg = dev->tx_buffer; 72 + 73 + if (dev->write_fail) 74 + return 0; 75 + 76 + if (endpoint == MGMT_EP) { 77 + memset(seg, 0, RSI_USB_TX_HEAD_ROOM); 78 + memcpy(seg + RSI_USB_TX_HEAD_ROOM, data, count); 79 + } else { 80 + seg = ((u8 *)data - RSI_USB_TX_HEAD_ROOM); 81 + } 82 + 83 + return rsi_usb_card_write(adapter, 84 + seg, 85 + count + RSI_USB_TX_HEAD_ROOM, 86 + endpoint); 87 + } 88 + 89 + /** 90 + * rsi_find_bulk_in_and_out_endpoints() - This function initializes the bulk 91 + * endpoints to the device. 92 + * @interface: Pointer to the USB interface structure. 93 + * @adapter: Pointer to the adapter structure. 94 + * 95 + * Return: ret_val: 0 on success, -ENOMEM on failure. 96 + */ 97 + static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, 98 + struct rsi_hw *adapter) 99 + { 100 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 101 + struct usb_host_interface *iface_desc; 102 + struct usb_endpoint_descriptor *endpoint; 103 + __le16 buffer_size; 104 + int ii, bep_found = 0; 105 + 106 + iface_desc = &(interface->altsetting[0]); 107 + 108 + for (ii = 0; ii < iface_desc->desc.bNumEndpoints; ++ii) { 109 + endpoint = &(iface_desc->endpoint[ii].desc); 110 + 111 + if ((!(dev->bulkin_endpoint_addr)) && 112 + (endpoint->bEndpointAddress & USB_DIR_IN) && 113 + ((endpoint->bmAttributes & 114 + USB_ENDPOINT_XFERTYPE_MASK) == 115 + USB_ENDPOINT_XFER_BULK)) { 116 + buffer_size = endpoint->wMaxPacketSize; 117 + dev->bulkin_size = buffer_size; 118 + dev->bulkin_endpoint_addr = 119 + endpoint->bEndpointAddress; 120 + } 121 + 122 + if (!dev->bulkout_endpoint_addr[bep_found] && 123 + !(endpoint->bEndpointAddress & USB_DIR_IN) && 124 + ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == 125 + USB_ENDPOINT_XFER_BULK)) { 126 + dev->bulkout_endpoint_addr[bep_found] = 127 + endpoint->bEndpointAddress; 128 + buffer_size = endpoint->wMaxPacketSize; 129 + dev->bulkout_size[bep_found] = buffer_size; 130 + bep_found++; 131 + } 132 + 133 + if (bep_found >= MAX_BULK_EP) 134 + break; 135 + } 136 + 137 + if (!(dev->bulkin_endpoint_addr) && 138 + (dev->bulkout_endpoint_addr[0])) 139 + return -EINVAL; 140 + 141 + return 0; 142 + } 143 + 144 + /* rsi_usb_reg_read() - This function reads data from given register address. 145 + * @usbdev: Pointer to the usb_device structure. 146 + * @reg: Address of the register to be read. 147 + * @value: Value to be read. 148 + * @len: length of data to be read. 149 + * 150 + * Return: status: 0 on success, -1 on failure. 151 + */ 152 + static int rsi_usb_reg_read(struct usb_device *usbdev, 153 + u32 reg, 154 + u16 *value, 155 + u16 len) 156 + { 157 + u8 temp_buf[4]; 158 + int status = 0; 159 + 160 + status = usb_control_msg(usbdev, 161 + usb_rcvctrlpipe(usbdev, 0), 162 + USB_VENDOR_REGISTER_READ, 163 + USB_TYPE_VENDOR, 164 + ((reg & 0xffff0000) >> 16), (reg & 0xffff), 165 + (void *)temp_buf, 166 + len, 167 + HZ * 5); 168 + 169 + *value = (temp_buf[0] | (temp_buf[1] << 8)); 170 + if (status < 0) { 171 + rsi_dbg(ERR_ZONE, 172 + "%s: Reg read failed with error code :%d\n", 173 + __func__, status); 174 + } 175 + return status; 176 + } 177 + 178 + /** 179 + * rsi_usb_reg_write() - This function writes the given data into the given 180 + * register address. 181 + * @usbdev: Pointer to the usb_device structure. 182 + * @reg: Address of the register. 183 + * @value: Value to write. 184 + * @len: Length of data to be written. 185 + * 186 + * Return: status: 0 on success, -1 on failure. 187 + */ 188 + static int rsi_usb_reg_write(struct usb_device *usbdev, 189 + u32 reg, 190 + u16 value, 191 + u16 len) 192 + { 193 + u8 usb_reg_buf[4]; 194 + int status = 0; 195 + 196 + usb_reg_buf[0] = (value & 0x00ff); 197 + usb_reg_buf[1] = (value & 0xff00) >> 8; 198 + usb_reg_buf[2] = 0x0; 199 + usb_reg_buf[3] = 0x0; 200 + 201 + status = usb_control_msg(usbdev, 202 + usb_sndctrlpipe(usbdev, 0), 203 + USB_VENDOR_REGISTER_WRITE, 204 + USB_TYPE_VENDOR, 205 + ((reg & 0xffff0000) >> 16), 206 + (reg & 0xffff), 207 + (void *)usb_reg_buf, 208 + len, 209 + HZ * 5); 210 + if (status < 0) { 211 + rsi_dbg(ERR_ZONE, 212 + "%s: Reg write failed with error code :%d\n", 213 + __func__, status); 214 + } 215 + return status; 216 + } 217 + 218 + /** 219 + * rsi_rx_done_handler() - This function is called when a packet is received 220 + * from USB stack. This is callback to recieve done. 221 + * @urb: Received URB. 222 + * 223 + * Return: None. 224 + */ 225 + static void rsi_rx_done_handler(struct urb *urb) 226 + { 227 + struct rsi_hw *adapter = urb->context; 228 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 229 + 230 + if (urb->status) 231 + return; 232 + 233 + rsi_set_event(&dev->rx_thread.event); 234 + } 235 + 236 + /** 237 + * rsi_rx_urb_submit() - This function submits the given URB to the USB stack. 238 + * @adapter: Pointer to the adapter structure. 239 + * 240 + * Return: 0 on success, -1 on failure. 241 + */ 242 + static int rsi_rx_urb_submit(struct rsi_hw *adapter) 243 + { 244 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 245 + struct urb *urb = dev->rx_usb_urb[0]; 246 + int status; 247 + 248 + usb_fill_bulk_urb(urb, 249 + dev->usbdev, 250 + usb_rcvbulkpipe(dev->usbdev, 251 + dev->bulkin_endpoint_addr), 252 + urb->transfer_buffer, 253 + 3000, 254 + rsi_rx_done_handler, 255 + adapter); 256 + 257 + status = usb_submit_urb(urb, GFP_KERNEL); 258 + if (status) 259 + rsi_dbg(ERR_ZONE, "%s: Failed in urb submission\n", __func__); 260 + 261 + return status; 262 + } 263 + 264 + /** 265 + * rsi_usb_write_register_multiple() - This function writes multiple bytes of 266 + * information to multiple registers. 267 + * @adapter: Pointer to the adapter structure. 268 + * @addr: Address of the register. 269 + * @data: Pointer to the data that has to be written. 270 + * @count: Number of multiple bytes to be written on to the registers. 271 + * 272 + * Return: status: 0 on success, -1 on failure. 273 + */ 274 + int rsi_usb_write_register_multiple(struct rsi_hw *adapter, 275 + u32 addr, 276 + u8 *data, 277 + u32 count) 278 + { 279 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 280 + u8 *buf; 281 + u8 transfer; 282 + int status = 0; 283 + 284 + buf = kzalloc(4096, GFP_KERNEL); 285 + if (!buf) 286 + return -ENOMEM; 287 + 288 + while (count) { 289 + transfer = min_t(int, count, 4096); 290 + memcpy(buf, data, transfer); 291 + status = usb_control_msg(dev->usbdev, 292 + usb_sndctrlpipe(dev->usbdev, 0), 293 + USB_VENDOR_REGISTER_WRITE, 294 + USB_TYPE_VENDOR, 295 + ((addr & 0xffff0000) >> 16), 296 + (addr & 0xffff), 297 + (void *)buf, 298 + transfer, 299 + HZ * 5); 300 + if (status < 0) { 301 + rsi_dbg(ERR_ZONE, 302 + "Reg write failed with error code :%d\n", 303 + status); 304 + } else { 305 + count -= transfer; 306 + data += transfer; 307 + addr += transfer; 308 + } 309 + } 310 + 311 + kfree(buf); 312 + return 0; 313 + } 314 + 315 + /** 316 + *rsi_usb_host_intf_write_pkt() - This function writes the packet to the 317 + * USB card. 318 + * @adapter: Pointer to the adapter structure. 319 + * @pkt: Pointer to the data to be written on to the card. 320 + * @len: Length of the data to be written on to the card. 321 + * 322 + * Return: 0 on success, -1 on failure. 323 + */ 324 + static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, 325 + u8 *pkt, 326 + u32 len) 327 + { 328 + u32 queueno = ((pkt[1] >> 4) & 0xf); 329 + u8 endpoint; 330 + 331 + endpoint = ((queueno == RSI_WIFI_MGMT_Q) ? MGMT_EP : DATA_EP); 332 + 333 + return rsi_write_multiple(adapter, 334 + endpoint, 335 + (u8 *)pkt, 336 + len); 337 + } 338 + 339 + /** 340 + * rsi_deinit_usb_interface() - This function deinitializes the usb interface. 341 + * @adapter: Pointer to the adapter structure. 342 + * 343 + * Return: None. 344 + */ 345 + static void rsi_deinit_usb_interface(struct rsi_hw *adapter) 346 + { 347 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 348 + 349 + rsi_kill_thread(&dev->rx_thread); 350 + kfree(adapter->priv->rx_data_pkt); 351 + kfree(dev->tx_buffer); 352 + } 353 + 354 + /** 355 + * rsi_init_usb_interface() - This function initializes the usb interface. 356 + * @adapter: Pointer to the adapter structure. 357 + * @pfunction: Pointer to USB interface structure. 358 + * 359 + * Return: 0 on success, -1 on failure. 360 + */ 361 + static int rsi_init_usb_interface(struct rsi_hw *adapter, 362 + struct usb_interface *pfunction) 363 + { 364 + struct rsi_91x_usbdev *rsi_dev; 365 + struct rsi_common *common = adapter->priv; 366 + int status; 367 + 368 + rsi_dev = kzalloc(sizeof(*rsi_dev), GFP_KERNEL); 369 + if (!rsi_dev) 370 + return -ENOMEM; 371 + 372 + adapter->rsi_dev = rsi_dev; 373 + rsi_dev->usbdev = interface_to_usbdev(pfunction); 374 + 375 + if (rsi_find_bulk_in_and_out_endpoints(pfunction, adapter)) 376 + return -EINVAL; 377 + 378 + adapter->device = &pfunction->dev; 379 + usb_set_intfdata(pfunction, adapter); 380 + 381 + common->rx_data_pkt = kmalloc(2048, GFP_KERNEL); 382 + if (!common->rx_data_pkt) { 383 + rsi_dbg(ERR_ZONE, "%s: Failed to allocate memory\n", 384 + __func__); 385 + return -ENOMEM; 386 + } 387 + 388 + rsi_dev->tx_buffer = kmalloc(2048, GFP_ATOMIC); 389 + rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL); 390 + rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; 391 + rsi_dev->tx_blk_size = 252; 392 + 393 + /* Initializing function callbacks */ 394 + adapter->rx_urb_submit = rsi_rx_urb_submit; 395 + adapter->host_intf_write_pkt = rsi_usb_host_intf_write_pkt; 396 + adapter->check_hw_queue_status = rsi_usb_check_queue_status; 397 + adapter->determine_event_timeout = rsi_usb_event_timeout; 398 + 399 + rsi_init_event(&rsi_dev->rx_thread.event); 400 + status = rsi_create_kthread(common, &rsi_dev->rx_thread, 401 + rsi_usb_rx_thread, "RX-Thread"); 402 + if (status) { 403 + rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); 404 + goto fail; 405 + } 406 + 407 + #ifdef CONFIG_RSI_DEBUGFS 408 + /* In USB, one less than the MAX_DEBUGFS_ENTRIES entries is required */ 409 + adapter->num_debugfs_entries = (MAX_DEBUGFS_ENTRIES - 1); 410 + #endif 411 + 412 + rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); 413 + return 0; 414 + 415 + fail: 416 + kfree(rsi_dev->tx_buffer); 417 + kfree(common->rx_data_pkt); 418 + return status; 419 + } 420 + 421 + /** 422 + * rsi_probe() - This function is called by kernel when the driver provided 423 + * Vendor and device IDs are matched. All the initialization 424 + * work is done here. 425 + * @pfunction: Pointer to the USB interface structure. 426 + * @id: Pointer to the usb_device_id structure. 427 + * 428 + * Return: 0 on success, -1 on failure. 429 + */ 430 + static int rsi_probe(struct usb_interface *pfunction, 431 + const struct usb_device_id *id) 432 + { 433 + struct rsi_hw *adapter; 434 + struct rsi_91x_usbdev *dev; 435 + u16 fw_status; 436 + 437 + rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); 438 + 439 + adapter = rsi_91x_init(); 440 + if (!adapter) { 441 + rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n", 442 + __func__); 443 + return 1; 444 + } 445 + 446 + if (rsi_init_usb_interface(adapter, pfunction)) { 447 + rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n", 448 + __func__); 449 + goto err; 450 + } 451 + 452 + rsi_dbg(ERR_ZONE, "%s: Initialized os intf ops\n", __func__); 453 + 454 + dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 455 + 456 + if (rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2) < 0) 457 + goto err1; 458 + else 459 + fw_status &= 1; 460 + 461 + if (!fw_status) { 462 + if (rsi_usb_device_init(adapter->priv)) { 463 + rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", 464 + __func__); 465 + goto err1; 466 + } 467 + 468 + if (rsi_usb_reg_write(dev->usbdev, 469 + USB_INTERNAL_REG_1, 470 + RSI_USB_READY_MAGIC_NUM, 1) < 0) 471 + goto err1; 472 + rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__); 473 + } 474 + 475 + if (rsi_rx_urb_submit(adapter)) 476 + goto err1; 477 + 478 + return 0; 479 + err1: 480 + rsi_deinit_usb_interface(adapter); 481 + err: 482 + rsi_91x_deinit(adapter); 483 + rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); 484 + return 1; 485 + } 486 + 487 + /** 488 + * rsi_disconnect() - This function performs the reverse of the probe function, 489 + * it deintialize the driver structure. 490 + * @pfunction: Pointer to the USB interface structure. 491 + * 492 + * Return: None. 493 + */ 494 + static void rsi_disconnect(struct usb_interface *pfunction) 495 + { 496 + struct rsi_hw *adapter = usb_get_intfdata(pfunction); 497 + 498 + if (!adapter) 499 + return; 500 + 501 + rsi_mac80211_detach(adapter); 502 + rsi_deinit_usb_interface(adapter); 503 + rsi_91x_deinit(adapter); 504 + 505 + rsi_dbg(INFO_ZONE, "%s: Deinitialization completed\n", __func__); 506 + } 507 + 508 + #ifdef CONFIG_PM 509 + static int rsi_suspend(struct usb_interface *intf, pm_message_t message) 510 + { 511 + /* Not yet implemented */ 512 + return -ENOSYS; 513 + } 514 + 515 + static int rsi_resume(struct usb_interface *intf) 516 + { 517 + /* Not yet implemented */ 518 + return -ENOSYS; 519 + } 520 + #endif 521 + 522 + static const struct usb_device_id rsi_dev_table[] = { 523 + { USB_DEVICE(0x0303, 0x0100) }, 524 + { USB_DEVICE(0x041B, 0x0301) }, 525 + { USB_DEVICE(0x041B, 0x0201) }, 526 + { USB_DEVICE(0x041B, 0x9330) }, 527 + { /* Blank */}, 528 + }; 529 + 530 + static struct usb_driver rsi_driver = { 531 + .name = "RSI-USB WLAN", 532 + .probe = rsi_probe, 533 + .disconnect = rsi_disconnect, 534 + .id_table = rsi_dev_table, 535 + #ifdef CONFIG_PM 536 + .suspend = rsi_suspend, 537 + .resume = rsi_resume, 538 + #endif 539 + }; 540 + 541 + /** 542 + * rsi_module_init() - This function registers the client driver. 543 + * @void: Void. 544 + * 545 + * Return: 0 on success. 546 + */ 547 + static int rsi_module_init(void) 548 + { 549 + usb_register(&rsi_driver); 550 + rsi_dbg(INIT_ZONE, "%s: Registering driver\n", __func__); 551 + return 0; 552 + } 553 + 554 + /** 555 + * rsi_module_exit() - This function unregisters the client driver. 556 + * @void: Void. 557 + * 558 + * Return: None. 559 + */ 560 + static void rsi_module_exit(void) 561 + { 562 + usb_deregister(&rsi_driver); 563 + rsi_dbg(INFO_ZONE, "%s: Unregistering driver\n", __func__); 564 + } 565 + 566 + module_init(rsi_module_init); 567 + module_exit(rsi_module_exit); 568 + 569 + MODULE_AUTHOR("Redpine Signals Inc"); 570 + MODULE_DESCRIPTION("Common USB layer for RSI drivers"); 571 + MODULE_SUPPORTED_DEVICE("RSI-91x"); 572 + MODULE_DEVICE_TABLE(usb, rsi_dev_table); 573 + MODULE_FIRMWARE(FIRMWARE_RSI9113); 574 + MODULE_VERSION("0.1"); 575 + MODULE_LICENSE("Dual BSD/GPL");
+177
drivers/net/wireless/rsi/rsi_91x_usb_ops.c
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + * 16 + */ 17 + 18 + #include <linux/firmware.h> 19 + #include "rsi_usb.h" 20 + 21 + /** 22 + * rsi_copy_to_card() - This function includes the actual funtionality of 23 + * copying the TA firmware to the card.Basically this 24 + * function includes opening the TA file,reading the TA 25 + * file and writing their values in blocks of data. 26 + * @common: Pointer to the driver private structure. 27 + * @fw: Pointer to the firmware value to be written. 28 + * @len: length of firmware file. 29 + * @num_blocks: Number of blocks to be written to the card. 30 + * 31 + * Return: 0 on success and -1 on failure. 32 + */ 33 + static int rsi_copy_to_card(struct rsi_common *common, 34 + const u8 *fw, 35 + u32 len, 36 + u32 num_blocks) 37 + { 38 + struct rsi_hw *adapter = common->priv; 39 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 40 + u32 indx, ii; 41 + u32 block_size = dev->tx_blk_size; 42 + u32 lsb_address; 43 + u32 base_address; 44 + 45 + base_address = TA_LOAD_ADDRESS; 46 + 47 + for (indx = 0, ii = 0; ii < num_blocks; ii++, indx += block_size) { 48 + lsb_address = base_address; 49 + if (rsi_usb_write_register_multiple(adapter, 50 + lsb_address, 51 + (u8 *)(fw + indx), 52 + block_size)) { 53 + rsi_dbg(ERR_ZONE, 54 + "%s: Unable to load %s blk\n", __func__, 55 + FIRMWARE_RSI9113); 56 + return -EIO; 57 + } 58 + rsi_dbg(INIT_ZONE, "%s: loading block: %d\n", __func__, ii); 59 + base_address += block_size; 60 + } 61 + 62 + if (len % block_size) { 63 + lsb_address = base_address; 64 + if (rsi_usb_write_register_multiple(adapter, 65 + lsb_address, 66 + (u8 *)(fw + indx), 67 + len % block_size)) { 68 + rsi_dbg(ERR_ZONE, 69 + "%s: Unable to load %s blk\n", __func__, 70 + FIRMWARE_RSI9113); 71 + return -EIO; 72 + } 73 + } 74 + rsi_dbg(INIT_ZONE, 75 + "%s: Succesfully loaded %s instructions\n", __func__, 76 + FIRMWARE_RSI9113); 77 + 78 + rsi_dbg(INIT_ZONE, "%s: loaded firmware\n", __func__); 79 + return 0; 80 + } 81 + 82 + /** 83 + * rsi_usb_rx_thread() - This is a kernel thread to receive the packets from 84 + * the USB device. 85 + * @common: Pointer to the driver private structure. 86 + * 87 + * Return: None. 88 + */ 89 + void rsi_usb_rx_thread(struct rsi_common *common) 90 + { 91 + struct rsi_hw *adapter = common->priv; 92 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 93 + int status; 94 + 95 + do { 96 + rsi_wait_event(&dev->rx_thread.event, EVENT_WAIT_FOREVER); 97 + 98 + if (atomic_read(&dev->rx_thread.thread_done)) 99 + goto out; 100 + 101 + mutex_lock(&common->tx_rxlock); 102 + status = rsi_read_pkt(common, 0); 103 + if (status) { 104 + rsi_dbg(ERR_ZONE, "%s: Failed To read data", __func__); 105 + mutex_unlock(&common->tx_rxlock); 106 + return; 107 + } 108 + mutex_unlock(&common->tx_rxlock); 109 + rsi_reset_event(&dev->rx_thread.event); 110 + if (adapter->rx_urb_submit(adapter)) { 111 + rsi_dbg(ERR_ZONE, 112 + "%s: Failed in urb submission", __func__); 113 + return; 114 + } 115 + } while (1); 116 + 117 + out: 118 + rsi_dbg(INFO_ZONE, "%s: Terminated thread\n", __func__); 119 + complete_and_exit(&dev->rx_thread.completion, 0); 120 + } 121 + 122 + 123 + /** 124 + * rsi_load_ta_instructions() - This function includes the actual funtionality 125 + * of loading the TA firmware.This function also 126 + * includes opening the TA file,reading the TA 127 + * file and writing their value in blocks of data. 128 + * @common: Pointer to the driver private structure. 129 + * 130 + * Return: status: 0 on success, -1 on failure. 131 + */ 132 + static int rsi_load_ta_instructions(struct rsi_common *common) 133 + { 134 + struct rsi_hw *adapter = common->priv; 135 + struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; 136 + const struct firmware *fw_entry = NULL; 137 + u32 block_size = dev->tx_blk_size; 138 + const u8 *fw; 139 + u32 num_blocks, len; 140 + int status = 0; 141 + 142 + status = request_firmware(&fw_entry, FIRMWARE_RSI9113, adapter->device); 143 + if (status < 0) { 144 + rsi_dbg(ERR_ZONE, "%s Firmware file %s not found\n", 145 + __func__, FIRMWARE_RSI9113); 146 + return status; 147 + } 148 + 149 + fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL); 150 + len = fw_entry->size; 151 + 152 + if (len % 4) 153 + len += (4 - (len % 4)); 154 + 155 + num_blocks = (len / block_size); 156 + 157 + rsi_dbg(INIT_ZONE, "%s: Instruction size:%d\n", __func__, len); 158 + rsi_dbg(INIT_ZONE, "%s: num blocks: %d\n", __func__, num_blocks); 159 + 160 + status = rsi_copy_to_card(common, fw, len, num_blocks); 161 + release_firmware(fw_entry); 162 + return status; 163 + } 164 + 165 + /** 166 + * rsi_device_init() - This Function Initializes The HAL. 167 + * @common: Pointer to the driver private structure. 168 + * 169 + * Return: 0 on success, -1 on failure. 170 + */ 171 + int rsi_usb_device_init(struct rsi_common *common) 172 + { 173 + if (rsi_load_ta_instructions(common)) 174 + return -EIO; 175 + 176 + return 0; 177 + }
+126
drivers/net/wireless/rsi/rsi_boot_params.h
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #ifndef __RSI_BOOTPARAMS_HEADER_H__ 18 + #define __RSI_BOOTPARAMS_HEADER_H__ 19 + 20 + #define CRYSTAL_GOOD_TIME BIT(0) 21 + #define BOOTUP_MODE_INFO BIT(1) 22 + #define WIFI_TAPLL_CONFIGS BIT(5) 23 + #define WIFI_PLL960_CONFIGS BIT(6) 24 + #define WIFI_AFEPLL_CONFIGS BIT(7) 25 + #define WIFI_SWITCH_CLK_CONFIGS BIT(8) 26 + 27 + #define TA_PLL_M_VAL_20 8 28 + #define TA_PLL_N_VAL_20 1 29 + #define TA_PLL_P_VAL_20 4 30 + 31 + #define PLL960_M_VAL_20 0x14 32 + #define PLL960_N_VAL_20 0 33 + #define PLL960_P_VAL_20 5 34 + 35 + #define UMAC_CLK_40MHZ 40 36 + 37 + #define TA_PLL_M_VAL_40 46 38 + #define TA_PLL_N_VAL_40 3 39 + #define TA_PLL_P_VAL_40 3 40 + 41 + #define PLL960_M_VAL_40 0x14 42 + #define PLL960_N_VAL_40 0 43 + #define PLL960_P_VAL_40 5 44 + 45 + #define UMAC_CLK_20BW \ 46 + (((TA_PLL_M_VAL_20 + 1) * 40) / \ 47 + ((TA_PLL_N_VAL_20 + 1) * (TA_PLL_P_VAL_20 + 1))) 48 + #define VALID_20 \ 49 + (WIFI_PLL960_CONFIGS | WIFI_AFEPLL_CONFIGS | WIFI_SWITCH_CLK_CONFIGS) 50 + #define UMAC_CLK_40BW \ 51 + (((TA_PLL_M_VAL_40 + 1) * 40) / \ 52 + ((TA_PLL_N_VAL_40 + 1) * (TA_PLL_P_VAL_40 + 1))) 53 + #define VALID_40 \ 54 + (WIFI_PLL960_CONFIGS | WIFI_AFEPLL_CONFIGS | WIFI_SWITCH_CLK_CONFIGS | \ 55 + WIFI_TAPLL_CONFIGS | CRYSTAL_GOOD_TIME | BOOTUP_MODE_INFO) 56 + 57 + /* structure to store configs related to TAPLL programming */ 58 + struct tapll_info { 59 + __le16 pll_reg_1; 60 + __le16 pll_reg_2; 61 + } __packed; 62 + 63 + /* structure to store configs related to PLL960 programming */ 64 + struct pll960_info { 65 + __le16 pll_reg_1; 66 + __le16 pll_reg_2; 67 + __le16 pll_reg_3; 68 + } __packed; 69 + 70 + /* structure to store configs related to AFEPLL programming */ 71 + struct afepll_info { 72 + __le16 pll_reg; 73 + } __packed; 74 + 75 + /* structure to store configs related to pll configs */ 76 + struct pll_config { 77 + struct tapll_info tapll_info_g; 78 + struct pll960_info pll960_info_g; 79 + struct afepll_info afepll_info_g; 80 + } __packed; 81 + 82 + /* structure to store configs related to UMAC clk programming */ 83 + struct switch_clk { 84 + __le16 switch_clk_info; 85 + /* If switch_bbp_lmac_clk_reg is set then this value will be programmed 86 + * into reg 87 + */ 88 + __le16 bbp_lmac_clk_reg_val; 89 + /* if switch_umac_clk is set then this value will be programmed */ 90 + __le16 umac_clock_reg_config; 91 + /* if switch_qspi_clk is set then this value will be programmed */ 92 + __le16 qspi_uart_clock_reg_config; 93 + } __packed; 94 + 95 + struct device_clk_info { 96 + struct pll_config pll_config_g; 97 + struct switch_clk switch_clk_g; 98 + } __packed; 99 + 100 + struct bootup_params { 101 + __le16 magic_number; 102 + __le16 crystal_good_time; 103 + __le32 valid; 104 + __le32 reserved_for_valids; 105 + __le16 bootup_mode_info; 106 + /* configuration used for digital loop back */ 107 + __le16 digital_loop_back_params; 108 + __le16 rtls_timestamp_en; 109 + __le16 host_spi_intr_cfg; 110 + struct device_clk_info device_clk_info[3]; 111 + /* ulp buckboost wait time */ 112 + __le32 buckboost_wakeup_cnt; 113 + /* pmu wakeup wait time & WDT EN info */ 114 + __le16 pmu_wakeup_wait; 115 + u8 shutdown_wait_time; 116 + /* Sleep clock source selection */ 117 + u8 pmu_slp_clkout_sel; 118 + /* WDT programming values */ 119 + __le32 wdt_prog_value; 120 + /* WDT soc reset delay */ 121 + __le32 wdt_soc_rst_delay; 122 + /* dcdc modes configs */ 123 + __le32 dcdc_operation_mode; 124 + __le32 soc_reset_wait_cnt; 125 + } __packed; 126 + #endif
+87
drivers/net/wireless/rsi/rsi_common.h
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #ifndef __RSI_COMMON_H__ 18 + #define __RSI_COMMON_H__ 19 + 20 + #include <linux/kthread.h> 21 + 22 + #define EVENT_WAIT_FOREVER 0 23 + #define TA_LOAD_ADDRESS 0x00 24 + #define FIRMWARE_RSI9113 "rsi_91x.fw" 25 + #define QUEUE_NOT_FULL 1 26 + #define QUEUE_FULL 0 27 + 28 + static inline int rsi_init_event(struct rsi_event *pevent) 29 + { 30 + atomic_set(&pevent->event_condition, 1); 31 + init_waitqueue_head(&pevent->event_queue); 32 + return 0; 33 + } 34 + 35 + static inline int rsi_wait_event(struct rsi_event *event, u32 timeout) 36 + { 37 + int status = 0; 38 + 39 + if (!timeout) 40 + status = wait_event_interruptible(event->event_queue, 41 + (atomic_read(&event->event_condition) == 0)); 42 + else 43 + status = wait_event_interruptible_timeout(event->event_queue, 44 + (atomic_read(&event->event_condition) == 0), 45 + timeout); 46 + return status; 47 + } 48 + 49 + static inline void rsi_set_event(struct rsi_event *event) 50 + { 51 + atomic_set(&event->event_condition, 0); 52 + wake_up_interruptible(&event->event_queue); 53 + } 54 + 55 + static inline void rsi_reset_event(struct rsi_event *event) 56 + { 57 + atomic_set(&event->event_condition, 1); 58 + } 59 + 60 + static inline int rsi_create_kthread(struct rsi_common *common, 61 + struct rsi_thread *thread, 62 + void *func_ptr, 63 + u8 *name) 64 + { 65 + init_completion(&thread->completion); 66 + thread->task = kthread_run(func_ptr, common, name); 67 + if (IS_ERR(thread->task)) 68 + return (int)PTR_ERR(thread->task); 69 + 70 + return 0; 71 + } 72 + 73 + static inline int rsi_kill_thread(struct rsi_thread *handle) 74 + { 75 + atomic_inc(&handle->thread_done); 76 + rsi_set_event(&handle->event); 77 + 78 + wait_for_completion(&handle->completion); 79 + return kthread_stop(handle->task); 80 + } 81 + 82 + void rsi_mac80211_detach(struct rsi_hw *hw); 83 + u16 rsi_get_connected_channel(struct rsi_hw *adapter); 84 + struct rsi_hw *rsi_91x_init(void); 85 + void rsi_91x_deinit(struct rsi_hw *adapter); 86 + int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len); 87 + #endif
+48
drivers/net/wireless/rsi/rsi_debugfs.h
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #ifndef __RSI_DEBUGFS_H__ 18 + #define __RSI_DEBUGFS_H__ 19 + 20 + #include "rsi_main.h" 21 + #include <linux/debugfs.h> 22 + 23 + #ifndef CONFIG_RSI_DEBUGFS 24 + static inline int rsi_init_dbgfs(struct rsi_hw *adapter) 25 + { 26 + return 0; 27 + } 28 + 29 + static inline void rsi_remove_dbgfs(struct rsi_hw *adapter) 30 + { 31 + return; 32 + } 33 + #else 34 + struct rsi_dbg_files { 35 + const char *name; 36 + umode_t perms; 37 + const struct file_operations fops; 38 + }; 39 + 40 + struct rsi_debugfs { 41 + struct dentry *subdir; 42 + struct rsi_dbg_ops *dfs_get_ops; 43 + struct dentry *rsi_files[MAX_DEBUGFS_ENTRIES]; 44 + }; 45 + int rsi_init_dbgfs(struct rsi_hw *adapter); 46 + void rsi_remove_dbgfs(struct rsi_hw *adapter); 47 + #endif 48 + #endif
+232
drivers/net/wireless/rsi/rsi_main.h
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #ifndef __RSI_MAIN_H__ 18 + #define __RSI_MAIN_H__ 19 + 20 + #include <linux/string.h> 21 + #include <linux/skbuff.h> 22 + #include <net/mac80211.h> 23 + 24 + #define ERR_ZONE BIT(0) /* For Error Msgs */ 25 + #define INFO_ZONE BIT(1) /* For General Status Msgs */ 26 + #define INIT_ZONE BIT(2) /* For Driver Init Seq Msgs */ 27 + #define MGMT_TX_ZONE BIT(3) /* For TX Mgmt Path Msgs */ 28 + #define MGMT_RX_ZONE BIT(4) /* For RX Mgmt Path Msgs */ 29 + #define DATA_TX_ZONE BIT(5) /* For TX Data Path Msgs */ 30 + #define DATA_RX_ZONE BIT(6) /* For RX Data Path Msgs */ 31 + #define FSM_ZONE BIT(7) /* For State Machine Msgs */ 32 + #define ISR_ZONE BIT(8) /* For Interrupt Msgs */ 33 + 34 + #define FSM_CARD_NOT_READY 0 35 + #define FSM_BOOT_PARAMS_SENT 1 36 + #define FSM_EEPROM_READ_MAC_ADDR 2 37 + #define FSM_RESET_MAC_SENT 3 38 + #define FSM_RADIO_CAPS_SENT 4 39 + #define FSM_BB_RF_PROG_SENT 5 40 + #define FSM_MAC_INIT_DONE 6 41 + 42 + extern u32 rsi_zone_enabled; 43 + 44 + static inline void rsi_dbg(u32 zone, const char *fmt, ...) 45 + { 46 + struct va_format vaf; 47 + va_list args; 48 + 49 + va_start(args, fmt); 50 + 51 + vaf.fmt = fmt; 52 + vaf.va = &args; 53 + 54 + if (zone & rsi_zone_enabled) 55 + pr_info("%pV", &vaf); 56 + va_end(args); 57 + } 58 + 59 + #define RSI_MAX_VIFS 1 60 + #define NUM_EDCA_QUEUES 4 61 + #define IEEE80211_ADDR_LEN 6 62 + #define FRAME_DESC_SZ 16 63 + #define MIN_802_11_HDR_LEN 24 64 + 65 + #define DATA_QUEUE_WATER_MARK 400 66 + #define MIN_DATA_QUEUE_WATER_MARK 300 67 + #define MULTICAST_WATER_MARK 200 68 + #define MAC_80211_HDR_FRAME_CONTROL 0 69 + #define WME_NUM_AC 4 70 + #define NUM_SOFT_QUEUES 5 71 + #define MAX_HW_QUEUES 8 72 + #define INVALID_QUEUE 0xff 73 + #define MAX_CONTINUOUS_VO_PKTS 8 74 + #define MAX_CONTINUOUS_VI_PKTS 4 75 + 76 + /* Queue information */ 77 + #define RSI_WIFI_MGMT_Q 0x4 78 + #define RSI_WIFI_DATA_Q 0x5 79 + #define IEEE80211_MGMT_FRAME 0x00 80 + #define IEEE80211_CTL_FRAME 0x04 81 + 82 + #define IEEE80211_QOS_TID 0x0f 83 + #define IEEE80211_NONQOS_TID 16 84 + 85 + #define MAX_DEBUGFS_ENTRIES 4 86 + 87 + #define TID_TO_WME_AC(_tid) ( \ 88 + ((_tid) == 0 || (_tid) == 3) ? BE_Q : \ 89 + ((_tid) < 3) ? BK_Q : \ 90 + ((_tid) < 6) ? VI_Q : \ 91 + VO_Q) 92 + 93 + #define WME_AC(_q) ( \ 94 + ((_q) == BK_Q) ? IEEE80211_AC_BK : \ 95 + ((_q) == BE_Q) ? IEEE80211_AC_BE : \ 96 + ((_q) == VI_Q) ? IEEE80211_AC_VI : \ 97 + IEEE80211_AC_VO) 98 + 99 + struct version_info { 100 + u16 major; 101 + u16 minor; 102 + u16 release_num; 103 + u16 patch_num; 104 + } __packed; 105 + 106 + struct skb_info { 107 + s8 rssi; 108 + u32 flags; 109 + u16 channel; 110 + s8 tid; 111 + s8 sta_id; 112 + }; 113 + 114 + enum edca_queue { 115 + BK_Q, 116 + BE_Q, 117 + VI_Q, 118 + VO_Q, 119 + MGMT_SOFT_Q 120 + }; 121 + 122 + struct security_info { 123 + bool security_enable; 124 + u32 ptk_cipher; 125 + u32 gtk_cipher; 126 + }; 127 + 128 + struct wmm_qinfo { 129 + s32 weight; 130 + s32 wme_params; 131 + s32 pkt_contended; 132 + }; 133 + 134 + struct transmit_q_stats { 135 + u32 total_tx_pkt_send[NUM_EDCA_QUEUES + 1]; 136 + u32 total_tx_pkt_freed[NUM_EDCA_QUEUES + 1]; 137 + }; 138 + 139 + struct vif_priv { 140 + bool is_ht; 141 + bool sgi; 142 + u16 seq_start; 143 + }; 144 + 145 + struct rsi_event { 146 + atomic_t event_condition; 147 + wait_queue_head_t event_queue; 148 + }; 149 + 150 + struct rsi_thread { 151 + void (*thread_function)(void *); 152 + struct completion completion; 153 + struct task_struct *task; 154 + struct rsi_event event; 155 + atomic_t thread_done; 156 + }; 157 + 158 + struct rsi_hw; 159 + 160 + struct rsi_common { 161 + struct rsi_hw *priv; 162 + struct vif_priv vif_info[RSI_MAX_VIFS]; 163 + 164 + bool mgmt_q_block; 165 + struct version_info driver_ver; 166 + struct version_info fw_ver; 167 + 168 + struct rsi_thread tx_thread; 169 + struct sk_buff_head tx_queue[NUM_EDCA_QUEUES + 1]; 170 + /* Mutex declaration */ 171 + struct mutex mutex; 172 + /* Mutex used between tx/rx threads */ 173 + struct mutex tx_rxlock; 174 + u8 endpoint; 175 + 176 + /* Channel/band related */ 177 + u8 band; 178 + u8 channel_width; 179 + 180 + u16 rts_threshold; 181 + u16 bitrate_mask[2]; 182 + u32 fixedrate_mask[2]; 183 + 184 + u8 rf_reset; 185 + struct transmit_q_stats tx_stats; 186 + struct security_info secinfo; 187 + struct wmm_qinfo tx_qinfo[NUM_EDCA_QUEUES]; 188 + struct ieee80211_tx_queue_params edca_params[NUM_EDCA_QUEUES]; 189 + u8 mac_addr[IEEE80211_ADDR_LEN]; 190 + 191 + /* state related */ 192 + u32 fsm_state; 193 + bool init_done; 194 + u8 bb_rf_prog_count; 195 + bool iface_down; 196 + 197 + /* Generic */ 198 + u8 channel; 199 + u8 *rx_data_pkt; 200 + u8 mac_id; 201 + u8 radio_id; 202 + u16 rate_pwr[20]; 203 + u16 min_rate; 204 + 205 + /* WMM algo related */ 206 + u8 selected_qnum; 207 + u32 pkt_cnt; 208 + u8 min_weight; 209 + }; 210 + 211 + struct rsi_hw { 212 + struct rsi_common *priv; 213 + struct ieee80211_hw *hw; 214 + struct ieee80211_vif *vifs[RSI_MAX_VIFS]; 215 + struct ieee80211_tx_queue_params edca_params[NUM_EDCA_QUEUES]; 216 + struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; 217 + 218 + struct device *device; 219 + u8 sc_nvifs; 220 + 221 + #ifdef CONFIG_RSI_DEBUGFS 222 + struct rsi_debugfs *dfsentry; 223 + u8 num_debugfs_entries; 224 + #endif 225 + void *rsi_dev; 226 + int (*host_intf_read_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); 227 + int (*host_intf_write_pkt)(struct rsi_hw *adapter, u8 *pkt, u32 len); 228 + int (*check_hw_queue_status)(struct rsi_hw *adapter, u8 q_num); 229 + int (*rx_urb_submit)(struct rsi_hw *adapter); 230 + int (*determine_event_timeout)(struct rsi_hw *adapter); 231 + }; 232 + #endif
+285
drivers/net/wireless/rsi/rsi_mgmt.h
··· 1 + /** 2 + * Copyright (c) 2014 Redpine Signals Inc. 3 + * 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. 7 + * 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. 15 + */ 16 + 17 + #ifndef __RSI_MGMT_H__ 18 + #define __RSI_MGMT_H__ 19 + 20 + #include <linux/sort.h> 21 + #include "rsi_boot_params.h" 22 + #include "rsi_main.h" 23 + 24 + #define MAX_MGMT_PKT_SIZE 512 25 + #define RSI_NEEDED_HEADROOM 80 26 + #define RSI_RCV_BUFFER_LEN 2000 27 + 28 + #define RSI_11B_MODE 0 29 + #define RSI_11G_MODE BIT(7) 30 + #define RETRY_COUNT 8 31 + #define RETRY_LONG 4 32 + #define RETRY_SHORT 7 33 + #define WMM_SHORT_SLOT_TIME 9 34 + #define SIFS_DURATION 16 35 + 36 + #define KEY_TYPE_CLEAR 0 37 + #define RSI_PAIRWISE_KEY 1 38 + #define RSI_GROUP_KEY 2 39 + 40 + /* EPPROM_READ_ADDRESS */ 41 + #define WLAN_MAC_EEPROM_ADDR 40 42 + #define WLAN_MAC_MAGIC_WORD_LEN 0x01 43 + #define WLAN_HOST_MODE_LEN 0x04 44 + #define WLAN_FW_VERSION_LEN 0x08 45 + #define MAGIC_WORD 0x5A 46 + 47 + /* Receive Frame Types */ 48 + #define TA_CONFIRM_TYPE 0x01 49 + #define RX_DOT11_MGMT 0x02 50 + #define TX_STATUS_IND 0x04 51 + #define PROBEREQ_CONFIRM 2 52 + #define CARD_READY_IND 0x00 53 + 54 + #define RSI_DELETE_PEER 0x0 55 + #define RSI_ADD_PEER 0x1 56 + #define START_AMPDU_AGGR 0x1 57 + #define STOP_AMPDU_AGGR 0x0 58 + #define INTERNAL_MGMT_PKT 0x99 59 + 60 + #define PUT_BBP_RESET 0 61 + #define BBP_REG_WRITE 0 62 + #define RF_RESET_ENABLE BIT(3) 63 + #define RATE_INFO_ENABLE BIT(0) 64 + #define RSI_BROADCAST_PKT BIT(9) 65 + 66 + #define UPPER_20_ENABLE (0x2 << 12) 67 + #define LOWER_20_ENABLE (0x4 << 12) 68 + #define FULL40M_ENABLE 0x6 69 + 70 + #define RSI_LMAC_CLOCK_80MHZ 0x1 71 + #define RSI_ENABLE_40MHZ (0x1 << 3) 72 + 73 + #define RX_BA_INDICATION 1 74 + #define RSI_TBL_SZ 40 75 + #define MAX_RETRIES 8 76 + 77 + #define STD_RATE_MCS7 0x07 78 + #define STD_RATE_MCS6 0x06 79 + #define STD_RATE_MCS5 0x05 80 + #define STD_RATE_MCS4 0x04 81 + #define STD_RATE_MCS3 0x03 82 + #define STD_RATE_MCS2 0x02 83 + #define STD_RATE_MCS1 0x01 84 + #define STD_RATE_MCS0 0x00 85 + #define STD_RATE_54 0x6c 86 + #define STD_RATE_48 0x60 87 + #define STD_RATE_36 0x48 88 + #define STD_RATE_24 0x30 89 + #define STD_RATE_18 0x24 90 + #define STD_RATE_12 0x18 91 + #define STD_RATE_11 0x16 92 + #define STD_RATE_09 0x12 93 + #define STD_RATE_06 0x0C 94 + #define STD_RATE_5_5 0x0B 95 + #define STD_RATE_02 0x04 96 + #define STD_RATE_01 0x02 97 + 98 + #define RSI_RF_TYPE 1 99 + #define RSI_RATE_00 0x00 100 + #define RSI_RATE_1 0x0 101 + #define RSI_RATE_2 0x2 102 + #define RSI_RATE_5_5 0x4 103 + #define RSI_RATE_11 0x6 104 + #define RSI_RATE_6 0x8b 105 + #define RSI_RATE_9 0x8f 106 + #define RSI_RATE_12 0x8a 107 + #define RSI_RATE_18 0x8e 108 + #define RSI_RATE_24 0x89 109 + #define RSI_RATE_36 0x8d 110 + #define RSI_RATE_48 0x88 111 + #define RSI_RATE_54 0x8c 112 + #define RSI_RATE_MCS0 0x100 113 + #define RSI_RATE_MCS1 0x101 114 + #define RSI_RATE_MCS2 0x102 115 + #define RSI_RATE_MCS3 0x103 116 + #define RSI_RATE_MCS4 0x104 117 + #define RSI_RATE_MCS5 0x105 118 + #define RSI_RATE_MCS6 0x106 119 + #define RSI_RATE_MCS7 0x107 120 + #define RSI_RATE_MCS7_SG 0x307 121 + 122 + #define BW_20MHZ 0 123 + #define BW_40MHZ 1 124 + 125 + #define RSI_SUPP_FILTERS (FIF_ALLMULTI | FIF_PROBE_REQ |\ 126 + FIF_BCN_PRBRESP_PROMISC) 127 + enum opmode { 128 + STA_OPMODE = 1, 129 + AP_OPMODE = 2 130 + }; 131 + 132 + extern struct ieee80211_rate rsi_rates[12]; 133 + extern const u16 rsi_mcsrates[8]; 134 + 135 + enum sta_notify_events { 136 + STA_CONNECTED = 0, 137 + STA_DISCONNECTED, 138 + STA_TX_ADDBA_DONE, 139 + STA_TX_DELBA, 140 + STA_RX_ADDBA_DONE, 141 + STA_RX_DELBA 142 + }; 143 + 144 + /* Send Frames Types */ 145 + enum cmd_frame_type { 146 + TX_DOT11_MGMT, 147 + RESET_MAC_REQ, 148 + RADIO_CAPABILITIES, 149 + BB_PROG_VALUES_REQUEST, 150 + RF_PROG_VALUES_REQUEST, 151 + WAKEUP_SLEEP_REQUEST, 152 + SCAN_REQUEST, 153 + TSF_UPDATE, 154 + PEER_NOTIFY, 155 + BLOCK_UNBLOCK, 156 + SET_KEY_REQ, 157 + AUTO_RATE_IND, 158 + BOOTUP_PARAMS_REQUEST, 159 + VAP_CAPABILITIES, 160 + EEPROM_READ_TYPE , 161 + EEPROM_WRITE, 162 + GPIO_PIN_CONFIG , 163 + SET_RX_FILTER, 164 + AMPDU_IND, 165 + STATS_REQUEST_FRAME, 166 + BB_BUF_PROG_VALUES_REQ, 167 + BBP_PROG_IN_TA, 168 + BG_SCAN_PARAMS, 169 + BG_SCAN_PROBE_REQ, 170 + CW_MODE_REQ, 171 + PER_CMD_PKT 172 + }; 173 + 174 + struct rsi_mac_frame { 175 + __le16 desc_word[8]; 176 + } __packed; 177 + 178 + struct rsi_boot_params { 179 + __le16 desc_word[8]; 180 + struct bootup_params bootup_params; 181 + } __packed; 182 + 183 + struct rsi_peer_notify { 184 + __le16 desc_word[8]; 185 + u8 mac_addr[6]; 186 + __le16 command; 187 + __le16 mpdu_density; 188 + __le16 reserved; 189 + __le32 sta_flags; 190 + } __packed; 191 + 192 + struct rsi_vap_caps { 193 + __le16 desc_word[8]; 194 + u8 mac_addr[6]; 195 + __le16 keep_alive_period; 196 + u8 bssid[6]; 197 + __le16 reserved; 198 + __le32 flags; 199 + __le16 frag_threshold; 200 + __le16 rts_threshold; 201 + __le32 default_mgmt_rate; 202 + __le32 default_ctrl_rate; 203 + __le32 default_data_rate; 204 + __le16 beacon_interval; 205 + __le16 dtim_period; 206 + } __packed; 207 + 208 + struct rsi_set_key { 209 + __le16 desc_word[8]; 210 + u8 key[4][32]; 211 + u8 tx_mic_key[8]; 212 + u8 rx_mic_key[8]; 213 + } __packed; 214 + 215 + struct rsi_auto_rate { 216 + __le16 desc_word[8]; 217 + __le16 failure_limit; 218 + __le16 initial_boundary; 219 + __le16 max_threshold_limt; 220 + __le16 num_supported_rates; 221 + __le16 aarf_rssi; 222 + __le16 moderate_rate_inx; 223 + __le16 collision_tolerance; 224 + __le16 supported_rates[40]; 225 + } __packed; 226 + 227 + struct qos_params { 228 + __le16 cont_win_min_q; 229 + __le16 cont_win_max_q; 230 + __le16 aifsn_val_q; 231 + __le16 txop_q; 232 + } __packed; 233 + 234 + struct rsi_radio_caps { 235 + __le16 desc_word[8]; 236 + struct qos_params qos_params[MAX_HW_QUEUES]; 237 + u8 num_11n_rates; 238 + u8 num_11ac_rates; 239 + __le16 gcpd_per_rate[20]; 240 + } __packed; 241 + 242 + static inline u32 rsi_get_queueno(u8 *addr, u16 offset) 243 + { 244 + return (le16_to_cpu(*(__le16 *)&addr[offset]) & 0x7000) >> 12; 245 + } 246 + 247 + static inline u32 rsi_get_length(u8 *addr, u16 offset) 248 + { 249 + return (le16_to_cpu(*(__le16 *)&addr[offset])) & 0x0fff; 250 + } 251 + 252 + static inline u8 rsi_get_extended_desc(u8 *addr, u16 offset) 253 + { 254 + return le16_to_cpu(*((__le16 *)&addr[offset + 4])) & 0x00ff; 255 + } 256 + 257 + static inline u8 rsi_get_rssi(u8 *addr) 258 + { 259 + return *(u8 *)(addr + FRAME_DESC_SZ); 260 + } 261 + 262 + static inline u8 rsi_get_channel(u8 *addr) 263 + { 264 + return *(char *)(addr + 15); 265 + } 266 + 267 + int rsi_mgmt_pkt_recv(struct rsi_common *common, u8 *msg); 268 + int rsi_set_vap_capabilities(struct rsi_common *common, enum opmode mode); 269 + int rsi_send_aggregation_params_frame(struct rsi_common *common, u16 tid, 270 + u16 ssn, u8 buf_size, u8 event); 271 + int rsi_hal_load_key(struct rsi_common *common, u8 *data, u16 key_len, 272 + u8 key_type, u8 key_id, u32 cipher); 273 + int rsi_set_channel(struct rsi_common *common, u16 chno); 274 + void rsi_inform_bss_status(struct rsi_common *common, u8 status, 275 + const u8 *bssid, u8 qos_enable, u16 aid); 276 + void rsi_indicate_pkt_to_os(struct rsi_common *common, struct sk_buff *skb); 277 + int rsi_mac80211_attach(struct rsi_common *common); 278 + void rsi_indicate_tx_status(struct rsi_hw *common, struct sk_buff *skb, 279 + int status); 280 + bool rsi_is_cipher_wep(struct rsi_common *common); 281 + void rsi_core_qos_processor(struct rsi_common *common); 282 + void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb); 283 + int rsi_send_mgmt_pkt(struct rsi_common *common, struct sk_buff *skb); 284 + int rsi_send_data_pkt(struct rsi_common *common, struct sk_buff *skb); 285 + #endif
+129
drivers/net/wireless/rsi/rsi_sdio.h
··· 1 + /** 2 + * @section LICENSE 3 + * Copyright (c) 2014 Redpine Signals Inc. 4 + * 5 + * Permission to use, copy, modify, and/or distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + * 17 + */ 18 + 19 + #ifndef __RSI_SDIO_INTF__ 20 + #define __RSI_SDIO_INTF__ 21 + 22 + #include <linux/mmc/card.h> 23 + #include <linux/mmc/mmc.h> 24 + #include <linux/mmc/host.h> 25 + #include <linux/mmc/sdio_func.h> 26 + #include <linux/mmc/sdio.h> 27 + #include <linux/mmc/sd.h> 28 + #include <linux/mmc/sdio_ids.h> 29 + #include "rsi_main.h" 30 + 31 + enum sdio_interrupt_type { 32 + BUFFER_FULL = 0x0, 33 + BUFFER_AVAILABLE = 0x1, 34 + FIRMWARE_ASSERT_IND = 0x3, 35 + MSDU_PACKET_PENDING = 0x4, 36 + UNKNOWN_INT = 0XE 37 + }; 38 + 39 + /* Buffer status register related info */ 40 + #define PKT_BUFF_SEMI_FULL 0 41 + #define PKT_BUFF_FULL 1 42 + #define PKT_MGMT_BUFF_FULL 2 43 + #define MSDU_PKT_PENDING 3 44 + /* Interrupt Bit Related Macros */ 45 + #define PKT_BUFF_AVAILABLE 0 46 + #define FW_ASSERT_IND 2 47 + 48 + #define RSI_DEVICE_BUFFER_STATUS_REGISTER 0xf3 49 + #define RSI_FN1_INT_REGISTER 0xf9 50 + #define RSI_SD_REQUEST_MASTER 0x10000 51 + 52 + /* FOR SD CARD ONLY */ 53 + #define SDIO_RX_NUM_BLOCKS_REG 0x000F1 54 + #define SDIO_FW_STATUS_REG 0x000F2 55 + #define SDIO_NXT_RD_DELAY2 0x000F5 56 + #define SDIO_MASTER_ACCESS_MSBYTE 0x000FA 57 + #define SDIO_MASTER_ACCESS_LSBYTE 0x000FB 58 + #define SDIO_READ_START_LVL 0x000FC 59 + #define SDIO_READ_FIFO_CTL 0x000FD 60 + #define SDIO_WRITE_FIFO_CTL 0x000FE 61 + #define SDIO_FUN1_INTR_CLR_REG 0x0008 62 + #define SDIO_REG_HIGH_SPEED 0x0013 63 + 64 + #define RSI_GET_SDIO_INTERRUPT_TYPE(_I, TYPE) \ 65 + { \ 66 + TYPE = \ 67 + (_I & (1 << PKT_BUFF_AVAILABLE)) ? \ 68 + BUFFER_AVAILABLE : \ 69 + (_I & (1 << MSDU_PKT_PENDING)) ? \ 70 + MSDU_PACKET_PENDING : \ 71 + (_I & (1 << FW_ASSERT_IND)) ? \ 72 + FIRMWARE_ASSERT_IND : UNKNOWN_INT; \ 73 + } 74 + 75 + /* common registers in SDIO function1 */ 76 + #define TA_SOFT_RESET_REG 0x0004 77 + #define TA_TH0_PC_REG 0x0400 78 + #define TA_HOLD_THREAD_REG 0x0844 79 + #define TA_RELEASE_THREAD_REG 0x0848 80 + 81 + #define TA_SOFT_RST_CLR 0 82 + #define TA_SOFT_RST_SET BIT(0) 83 + #define TA_PC_ZERO 0 84 + #define TA_HOLD_THREAD_VALUE cpu_to_le32(0xF) 85 + #define TA_RELEASE_THREAD_VALUE cpu_to_le32(0xF) 86 + #define TA_BASE_ADDR 0x2200 87 + #define MISC_CFG_BASE_ADDR 0x4150 88 + 89 + struct receive_info { 90 + bool buffer_full; 91 + bool semi_buffer_full; 92 + bool mgmt_buffer_full; 93 + u32 mgmt_buf_full_counter; 94 + u32 buf_semi_full_counter; 95 + u8 watch_bufferfull_count; 96 + u32 sdio_intr_status_zero; 97 + u32 sdio_int_counter; 98 + u32 total_sdio_msdu_pending_intr; 99 + u32 total_sdio_unknown_intr; 100 + u32 buf_full_counter; 101 + u32 buf_avilable_counter; 102 + }; 103 + 104 + struct rsi_91x_sdiodev { 105 + struct sdio_func *pfunction; 106 + struct task_struct *in_sdio_litefi_irq; 107 + struct receive_info rx_info; 108 + u32 next_read_delay; 109 + u32 sdio_high_speed_enable; 110 + u8 sdio_clock_speed; 111 + u32 cardcapability; 112 + u8 prev_desc[16]; 113 + u32 tx_blk_size; 114 + u8 write_fail; 115 + }; 116 + 117 + void rsi_interrupt_handler(struct rsi_hw *adapter); 118 + int rsi_init_sdio_slave_regs(struct rsi_hw *adapter); 119 + int rsi_sdio_device_init(struct rsi_common *common); 120 + int rsi_sdio_read_register(struct rsi_hw *adapter, u32 addr, u8 *data); 121 + int rsi_sdio_host_intf_read_pkt(struct rsi_hw *adapter, u8 *pkt, u32 length); 122 + int rsi_sdio_write_register(struct rsi_hw *adapter, u8 function, 123 + u32 addr, u8 *data); 124 + int rsi_sdio_write_register_multiple(struct rsi_hw *adapter, u32 addr, 125 + u8 *data, u32 count); 126 + void rsi_sdio_ack_intr(struct rsi_hw *adapter, u8 int_bit); 127 + int rsi_sdio_determine_event_timeout(struct rsi_hw *adapter); 128 + int rsi_sdio_read_buffer_status_register(struct rsi_hw *adapter, u8 q_num); 129 + #endif
+68
drivers/net/wireless/rsi/rsi_usb.h
··· 1 + /** 2 + * @section LICENSE 3 + * Copyright (c) 2014 Redpine Signals Inc. 4 + * 5 + * Permission to use, copy, modify, and/or distribute this software for any 6 + * purpose with or without fee is hereby granted, provided that the above 7 + * copyright notice and this permission notice appear in all copies. 8 + * 9 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 + */ 17 + 18 + #ifndef __RSI_USB_INTF__ 19 + #define __RSI_USB_INTF__ 20 + 21 + #include <linux/usb.h> 22 + #include "rsi_main.h" 23 + #include "rsi_common.h" 24 + 25 + #define USB_INTERNAL_REG_1 0x25000 26 + #define RSI_USB_READY_MAGIC_NUM 0xab 27 + #define FW_STATUS_REG 0x41050012 28 + 29 + #define USB_VENDOR_REGISTER_READ 0x15 30 + #define USB_VENDOR_REGISTER_WRITE 0x16 31 + #define RSI_USB_TX_HEAD_ROOM 128 32 + 33 + #define MAX_RX_URBS 1 34 + #define MAX_BULK_EP 8 35 + #define MGMT_EP 1 36 + #define DATA_EP 2 37 + 38 + struct rsi_91x_usbdev { 39 + struct rsi_thread rx_thread; 40 + u8 endpoint; 41 + struct usb_device *usbdev; 42 + struct usb_interface *pfunction; 43 + struct urb *rx_usb_urb[MAX_RX_URBS]; 44 + u8 *tx_buffer; 45 + __le16 bulkin_size; 46 + u8 bulkin_endpoint_addr; 47 + __le16 bulkout_size[MAX_BULK_EP]; 48 + u8 bulkout_endpoint_addr[MAX_BULK_EP]; 49 + u32 tx_blk_size; 50 + u8 write_fail; 51 + }; 52 + 53 + static inline int rsi_usb_check_queue_status(struct rsi_hw *adapter, u8 q_num) 54 + { 55 + /* In USB, there isn't any need to check the queue status */ 56 + return QUEUE_NOT_FULL; 57 + } 58 + 59 + static inline int rsi_usb_event_timeout(struct rsi_hw *adapter) 60 + { 61 + return EVENT_WAIT_FOREVER; 62 + } 63 + 64 + int rsi_usb_device_init(struct rsi_common *common); 65 + int rsi_usb_write_register_multiple(struct rsi_hw *adapter, u32 addr, 66 + u8 *data, u32 count); 67 + void rsi_usb_rx_thread(struct rsi_common *common); 68 + #endif