3215 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * NXP Wireless LAN device driver: SDIO specific handling4 *5 * Copyright 2011-2020 NXP6 */7 8#include <linux/firmware.h>9 10#include "decl.h"11#include "ioctl.h"12#include "util.h"13#include "fw.h"14#include "main.h"15#include "wmm.h"16#include "11n.h"17#include "sdio.h"18 19 20#define SDIO_VERSION "1.0"21 22static void mwifiex_sdio_work(struct work_struct *work);23 24static struct mwifiex_if_ops sdio_ops;25 26static const struct mwifiex_sdio_card_reg mwifiex_reg_sd87xx = {27 .start_rd_port = 1,28 .start_wr_port = 1,29 .base_0_reg = 0x0040,30 .base_1_reg = 0x0041,31 .poll_reg = 0x30,32 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK,33 .host_int_rsr_reg = 0x1,34 .host_int_mask_reg = 0x02,35 .host_int_status_reg = 0x03,36 .status_reg_0 = 0x60,37 .status_reg_1 = 0x61,38 .sdio_int_mask = 0x3f,39 .data_port_mask = 0x0000fffe,40 .io_port_0_reg = 0x78,41 .io_port_1_reg = 0x79,42 .io_port_2_reg = 0x7A,43 .max_mp_regs = 64,44 .rd_bitmap_l = 0x04,45 .rd_bitmap_u = 0x05,46 .wr_bitmap_l = 0x06,47 .wr_bitmap_u = 0x07,48 .rd_len_p0_l = 0x08,49 .rd_len_p0_u = 0x09,50 .card_misc_cfg_reg = 0x6c,51 .func1_dump_reg_start = 0x0,52 .func1_dump_reg_end = 0x9,53 .func1_scratch_reg = 0x60,54 .func1_spec_reg_num = 5,55 .func1_spec_reg_table = {0x28, 0x30, 0x34, 0x38, 0x3c},56};57 58static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8897 = {59 .start_rd_port = 0,60 .start_wr_port = 0,61 .base_0_reg = 0x60,62 .base_1_reg = 0x61,63 .poll_reg = 0x50,64 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |65 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,66 .host_int_rsr_reg = 0x1,67 .host_int_status_reg = 0x03,68 .host_int_mask_reg = 0x02,69 .status_reg_0 = 0xc0,70 .status_reg_1 = 0xc1,71 .sdio_int_mask = 0xff,72 .data_port_mask = 0xffffffff,73 .io_port_0_reg = 0xD8,74 .io_port_1_reg = 0xD9,75 .io_port_2_reg = 0xDA,76 .max_mp_regs = 184,77 .rd_bitmap_l = 0x04,78 .rd_bitmap_u = 0x05,79 .rd_bitmap_1l = 0x06,80 .rd_bitmap_1u = 0x07,81 .wr_bitmap_l = 0x08,82 .wr_bitmap_u = 0x09,83 .wr_bitmap_1l = 0x0a,84 .wr_bitmap_1u = 0x0b,85 .rd_len_p0_l = 0x0c,86 .rd_len_p0_u = 0x0d,87 .card_misc_cfg_reg = 0xcc,88 .card_cfg_2_1_reg = 0xcd,89 .cmd_rd_len_0 = 0xb4,90 .cmd_rd_len_1 = 0xb5,91 .cmd_rd_len_2 = 0xb6,92 .cmd_rd_len_3 = 0xb7,93 .cmd_cfg_0 = 0xb8,94 .cmd_cfg_1 = 0xb9,95 .cmd_cfg_2 = 0xba,96 .cmd_cfg_3 = 0xbb,97 .fw_dump_host_ready = 0xee,98 .fw_dump_ctrl = 0xe2,99 .fw_dump_start = 0xe3,100 .fw_dump_end = 0xea,101 .func1_dump_reg_start = 0x0,102 .func1_dump_reg_end = 0xb,103 .func1_scratch_reg = 0xc0,104 .func1_spec_reg_num = 8,105 .func1_spec_reg_table = {0x4C, 0x50, 0x54, 0x55, 0x58,106 0x59, 0x5c, 0x5d},107};108 109static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8977 = {110 .start_rd_port = 0,111 .start_wr_port = 0,112 .base_0_reg = 0xF8,113 .base_1_reg = 0xF9,114 .poll_reg = 0x5C,115 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |116 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,117 .host_int_rsr_reg = 0x4,118 .host_int_status_reg = 0x0C,119 .host_int_mask_reg = 0x08,120 .status_reg_0 = 0xE8,121 .status_reg_1 = 0xE9,122 .sdio_int_mask = 0xff,123 .data_port_mask = 0xffffffff,124 .io_port_0_reg = 0xE4,125 .io_port_1_reg = 0xE5,126 .io_port_2_reg = 0xE6,127 .max_mp_regs = 196,128 .rd_bitmap_l = 0x10,129 .rd_bitmap_u = 0x11,130 .rd_bitmap_1l = 0x12,131 .rd_bitmap_1u = 0x13,132 .wr_bitmap_l = 0x14,133 .wr_bitmap_u = 0x15,134 .wr_bitmap_1l = 0x16,135 .wr_bitmap_1u = 0x17,136 .rd_len_p0_l = 0x18,137 .rd_len_p0_u = 0x19,138 .card_misc_cfg_reg = 0xd8,139 .card_cfg_2_1_reg = 0xd9,140 .cmd_rd_len_0 = 0xc0,141 .cmd_rd_len_1 = 0xc1,142 .cmd_rd_len_2 = 0xc2,143 .cmd_rd_len_3 = 0xc3,144 .cmd_cfg_0 = 0xc4,145 .cmd_cfg_1 = 0xc5,146 .cmd_cfg_2 = 0xc6,147 .cmd_cfg_3 = 0xc7,148 .fw_dump_host_ready = 0xcc,149 .fw_dump_ctrl = 0xf0,150 .fw_dump_start = 0xf1,151 .fw_dump_end = 0xf8,152 .func1_dump_reg_start = 0x10,153 .func1_dump_reg_end = 0x17,154 .func1_scratch_reg = 0xe8,155 .func1_spec_reg_num = 13,156 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D,157 0x60, 0x61, 0x62, 0x64,158 0x65, 0x66, 0x68, 0x69,159 0x6a},160};161 162static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8997 = {163 .start_rd_port = 0,164 .start_wr_port = 0,165 .base_0_reg = 0xF8,166 .base_1_reg = 0xF9,167 .poll_reg = 0x5C,168 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |169 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,170 .host_int_rsr_reg = 0x4,171 .host_int_status_reg = 0x0C,172 .host_int_mask_reg = 0x08,173 .host_strap_reg = 0xF4,174 .host_strap_mask = 0x01,175 .host_strap_value = 0x00,176 .status_reg_0 = 0xE8,177 .status_reg_1 = 0xE9,178 .sdio_int_mask = 0xff,179 .data_port_mask = 0xffffffff,180 .io_port_0_reg = 0xE4,181 .io_port_1_reg = 0xE5,182 .io_port_2_reg = 0xE6,183 .max_mp_regs = 196,184 .rd_bitmap_l = 0x10,185 .rd_bitmap_u = 0x11,186 .rd_bitmap_1l = 0x12,187 .rd_bitmap_1u = 0x13,188 .wr_bitmap_l = 0x14,189 .wr_bitmap_u = 0x15,190 .wr_bitmap_1l = 0x16,191 .wr_bitmap_1u = 0x17,192 .rd_len_p0_l = 0x18,193 .rd_len_p0_u = 0x19,194 .card_misc_cfg_reg = 0xd8,195 .card_cfg_2_1_reg = 0xd9,196 .cmd_rd_len_0 = 0xc0,197 .cmd_rd_len_1 = 0xc1,198 .cmd_rd_len_2 = 0xc2,199 .cmd_rd_len_3 = 0xc3,200 .cmd_cfg_0 = 0xc4,201 .cmd_cfg_1 = 0xc5,202 .cmd_cfg_2 = 0xc6,203 .cmd_cfg_3 = 0xc7,204 .fw_dump_host_ready = 0xcc,205 .fw_dump_ctrl = 0xf0,206 .fw_dump_start = 0xf1,207 .fw_dump_end = 0xf8,208 .func1_dump_reg_start = 0x10,209 .func1_dump_reg_end = 0x17,210 .func1_scratch_reg = 0xe8,211 .func1_spec_reg_num = 13,212 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D,213 0x60, 0x61, 0x62, 0x64,214 0x65, 0x66, 0x68, 0x69,215 0x6a},216};217 218static const struct mwifiex_sdio_card_reg mwifiex_reg_sd8887 = {219 .start_rd_port = 0,220 .start_wr_port = 0,221 .base_0_reg = 0x6C,222 .base_1_reg = 0x6D,223 .poll_reg = 0x5C,224 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |225 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,226 .host_int_rsr_reg = 0x4,227 .host_int_status_reg = 0x0C,228 .host_int_mask_reg = 0x08,229 .status_reg_0 = 0x90,230 .status_reg_1 = 0x91,231 .sdio_int_mask = 0xff,232 .data_port_mask = 0xffffffff,233 .io_port_0_reg = 0xE4,234 .io_port_1_reg = 0xE5,235 .io_port_2_reg = 0xE6,236 .max_mp_regs = 196,237 .rd_bitmap_l = 0x10,238 .rd_bitmap_u = 0x11,239 .rd_bitmap_1l = 0x12,240 .rd_bitmap_1u = 0x13,241 .wr_bitmap_l = 0x14,242 .wr_bitmap_u = 0x15,243 .wr_bitmap_1l = 0x16,244 .wr_bitmap_1u = 0x17,245 .rd_len_p0_l = 0x18,246 .rd_len_p0_u = 0x19,247 .card_misc_cfg_reg = 0xd8,248 .card_cfg_2_1_reg = 0xd9,249 .cmd_rd_len_0 = 0xc0,250 .cmd_rd_len_1 = 0xc1,251 .cmd_rd_len_2 = 0xc2,252 .cmd_rd_len_3 = 0xc3,253 .cmd_cfg_0 = 0xc4,254 .cmd_cfg_1 = 0xc5,255 .cmd_cfg_2 = 0xc6,256 .cmd_cfg_3 = 0xc7,257 .func1_dump_reg_start = 0x10,258 .func1_dump_reg_end = 0x17,259 .func1_scratch_reg = 0x90,260 .func1_spec_reg_num = 13,261 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D, 0x60,262 0x61, 0x62, 0x64, 0x65, 0x66,263 0x68, 0x69, 0x6a},264};265 266static const struct mwifiex_sdio_card_reg mwifiex_reg_sd89xx = {267 .start_rd_port = 0,268 .start_wr_port = 0,269 .base_0_reg = 0xF8,270 .base_1_reg = 0xF9,271 .poll_reg = 0x5C,272 .host_int_enable = UP_LD_HOST_INT_MASK | DN_LD_HOST_INT_MASK |273 CMD_PORT_UPLD_INT_MASK | CMD_PORT_DNLD_INT_MASK,274 .host_int_rsr_reg = 0x4,275 .host_int_status_reg = 0x0C,276 .host_int_mask_reg = 0x08,277 .host_strap_reg = 0xF4,278 .host_strap_mask = 0x01,279 .host_strap_value = 0x00,280 .status_reg_0 = 0xE8,281 .status_reg_1 = 0xE9,282 .sdio_int_mask = 0xff,283 .data_port_mask = 0xffffffff,284 .io_port_0_reg = 0xE4,285 .io_port_1_reg = 0xE5,286 .io_port_2_reg = 0xE6,287 .max_mp_regs = 196,288 .rd_bitmap_l = 0x10,289 .rd_bitmap_u = 0x11,290 .rd_bitmap_1l = 0x12,291 .rd_bitmap_1u = 0x13,292 .wr_bitmap_l = 0x14,293 .wr_bitmap_u = 0x15,294 .wr_bitmap_1l = 0x16,295 .wr_bitmap_1u = 0x17,296 .rd_len_p0_l = 0x18,297 .rd_len_p0_u = 0x19,298 .card_misc_cfg_reg = 0xd8,299 .card_cfg_2_1_reg = 0xd9,300 .cmd_rd_len_0 = 0xc0,301 .cmd_rd_len_1 = 0xc1,302 .cmd_rd_len_2 = 0xc2,303 .cmd_rd_len_3 = 0xc3,304 .cmd_cfg_0 = 0xc4,305 .cmd_cfg_1 = 0xc5,306 .cmd_cfg_2 = 0xc6,307 .cmd_cfg_3 = 0xc7,308 .fw_dump_host_ready = 0xcc,309 .fw_dump_ctrl = 0xf9,310 .fw_dump_start = 0xf1,311 .fw_dump_end = 0xf8,312 .func1_dump_reg_start = 0x10,313 .func1_dump_reg_end = 0x17,314 .func1_scratch_reg = 0xE8,315 .func1_spec_reg_num = 13,316 .func1_spec_reg_table = {0x08, 0x58, 0x5C, 0x5D, 0x60,317 0x61, 0x62, 0x64, 0x65, 0x66,318 0x68, 0x69, 0x6a},319};320 321static const struct mwifiex_sdio_device mwifiex_sdio_sd8786 = {322 .firmware = SD8786_DEFAULT_FW_NAME,323 .reg = &mwifiex_reg_sd87xx,324 .max_ports = 16,325 .mp_agg_pkt_limit = 8,326 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,327 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,328 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,329 .supports_sdio_new_mode = false,330 .has_control_mask = true,331 .can_dump_fw = false,332 .can_auto_tdls = false,333 .can_ext_scan = false,334 .fw_ready_extra_delay = false,335 .host_mlme = false,336};337 338static const struct mwifiex_sdio_device mwifiex_sdio_sd8787 = {339 .firmware = SD8787_DEFAULT_FW_NAME,340 .reg = &mwifiex_reg_sd87xx,341 .max_ports = 16,342 .mp_agg_pkt_limit = 8,343 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,344 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,345 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,346 .supports_sdio_new_mode = false,347 .has_control_mask = true,348 .can_dump_fw = false,349 .can_auto_tdls = false,350 .can_ext_scan = true,351 .fw_ready_extra_delay = false,352 .host_mlme = false,353};354 355static const struct mwifiex_sdio_device mwifiex_sdio_sd8797 = {356 .firmware = SD8797_DEFAULT_FW_NAME,357 .reg = &mwifiex_reg_sd87xx,358 .max_ports = 16,359 .mp_agg_pkt_limit = 8,360 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,361 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,362 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,363 .supports_sdio_new_mode = false,364 .has_control_mask = true,365 .can_dump_fw = false,366 .can_auto_tdls = false,367 .can_ext_scan = true,368 .fw_ready_extra_delay = false,369 .host_mlme = false,370};371 372static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {373 .firmware = SD8897_DEFAULT_FW_NAME,374 .reg = &mwifiex_reg_sd8897,375 .max_ports = 32,376 .mp_agg_pkt_limit = 16,377 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,378 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,379 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,380 .supports_sdio_new_mode = true,381 .has_control_mask = false,382 .can_dump_fw = true,383 .can_auto_tdls = false,384 .can_ext_scan = true,385 .fw_ready_extra_delay = false,386 .host_mlme = false,387};388 389static const struct mwifiex_sdio_device mwifiex_sdio_sd8977 = {390 .firmware = SD8977_DEFAULT_FW_NAME,391 .reg = &mwifiex_reg_sd8977,392 .max_ports = 32,393 .mp_agg_pkt_limit = 16,394 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,395 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,396 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,397 .supports_sdio_new_mode = true,398 .has_control_mask = false,399 .can_dump_fw = true,400 .fw_dump_enh = true,401 .can_auto_tdls = false,402 .can_ext_scan = true,403 .fw_ready_extra_delay = false,404 .host_mlme = false,405};406 407static const struct mwifiex_sdio_device mwifiex_sdio_sd8978 = {408 .firmware_sdiouart = SD8978_SDIOUART_FW_NAME,409 .reg = &mwifiex_reg_sd89xx,410 .max_ports = 32,411 .mp_agg_pkt_limit = 16,412 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,413 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,414 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,415 .supports_sdio_new_mode = true,416 .has_control_mask = false,417 .can_dump_fw = true,418 .fw_dump_enh = true,419 .can_auto_tdls = false,420 .can_ext_scan = true,421 .fw_ready_extra_delay = true,422 .host_mlme = true,423};424 425static const struct mwifiex_sdio_device mwifiex_sdio_sd8997 = {426 .firmware = SD8997_DEFAULT_FW_NAME,427 .firmware_sdiouart = SD8997_SDIOUART_FW_NAME,428 .reg = &mwifiex_reg_sd8997,429 .max_ports = 32,430 .mp_agg_pkt_limit = 16,431 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,432 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,433 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,434 .supports_sdio_new_mode = true,435 .has_control_mask = false,436 .can_dump_fw = true,437 .fw_dump_enh = true,438 .can_auto_tdls = false,439 .can_ext_scan = true,440 .fw_ready_extra_delay = false,441 .host_mlme = false,442};443 444static const struct mwifiex_sdio_device mwifiex_sdio_sd8887 = {445 .firmware = SD8887_DEFAULT_FW_NAME,446 .reg = &mwifiex_reg_sd8887,447 .max_ports = 32,448 .mp_agg_pkt_limit = 16,449 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,450 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,451 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K,452 .supports_sdio_new_mode = true,453 .has_control_mask = false,454 .can_dump_fw = false,455 .can_auto_tdls = true,456 .can_ext_scan = true,457 .fw_ready_extra_delay = false,458 .host_mlme = false,459};460 461static const struct mwifiex_sdio_device mwifiex_sdio_sd8987 = {462 .firmware = SD8987_DEFAULT_FW_NAME,463 .reg = &mwifiex_reg_sd89xx,464 .max_ports = 32,465 .mp_agg_pkt_limit = 16,466 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,467 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,468 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,469 .supports_sdio_new_mode = true,470 .has_control_mask = false,471 .can_dump_fw = true,472 .fw_dump_enh = true,473 .can_auto_tdls = true,474 .can_ext_scan = true,475 .fw_ready_extra_delay = false,476 .host_mlme = false,477};478 479static const struct mwifiex_sdio_device mwifiex_sdio_sd8801 = {480 .firmware = SD8801_DEFAULT_FW_NAME,481 .reg = &mwifiex_reg_sd87xx,482 .max_ports = 16,483 .mp_agg_pkt_limit = 8,484 .supports_sdio_new_mode = false,485 .has_control_mask = true,486 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K,487 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,488 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_16K,489 .can_dump_fw = false,490 .can_auto_tdls = false,491 .can_ext_scan = true,492 .fw_ready_extra_delay = false,493 .host_mlme = false,494};495 496static struct memory_type_mapping generic_mem_type_map[] = {497 {"DUMP", NULL, 0, 0xDD},498};499 500static struct memory_type_mapping mem_type_mapping_tbl[] = {501 {"ITCM", NULL, 0, 0xF0},502 {"DTCM", NULL, 0, 0xF1},503 {"SQRAM", NULL, 0, 0xF2},504 {"APU", NULL, 0, 0xF3},505 {"CIU", NULL, 0, 0xF4},506 {"ICU", NULL, 0, 0xF5},507 {"MAC", NULL, 0, 0xF6},508 {"EXT7", NULL, 0, 0xF7},509 {"EXT8", NULL, 0, 0xF8},510 {"EXT9", NULL, 0, 0xF9},511 {"EXT10", NULL, 0, 0xFA},512 {"EXT11", NULL, 0, 0xFB},513 {"EXT12", NULL, 0, 0xFC},514 {"EXT13", NULL, 0, 0xFD},515 {"EXTLAST", NULL, 0, 0xFE},516};517 518static const struct of_device_id mwifiex_sdio_of_match_table[] __maybe_unused = {519 { .compatible = "marvell,sd8787" },520 { .compatible = "marvell,sd8897" },521 { .compatible = "marvell,sd8978" },522 { .compatible = "marvell,sd8997" },523 { .compatible = "nxp,iw416" },524 { }525};526 527/* This function parse device tree node using mmc subnode devicetree API.528 * The device node is saved in card->plt_of_node.529 * if the device tree node exist and include interrupts attributes, this530 * function will also request platform specific wakeup interrupt.531 */532static int mwifiex_sdio_probe_of(struct device *dev)533{534 if (!of_match_node(mwifiex_sdio_of_match_table, dev->of_node)) {535 dev_err(dev, "required compatible string missing\n");536 return -EINVAL;537 }538 539 return 0;540}541 542/*543 * SDIO probe.544 *545 * This function probes an mwifiex device and registers it. It allocates546 * the card structure, enables SDIO function number and initiates the547 * device registration and initialization procedure by adding a logical548 * interface.549 */550static int551mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id)552{553 int ret;554 struct sdio_mmc_card *card = NULL;555 556 pr_debug("info: vendor=0x%4.04X device=0x%4.04X class=%d function=%d\n",557 func->vendor, func->device, func->class, func->num);558 559 card = devm_kzalloc(&func->dev, sizeof(*card), GFP_KERNEL);560 if (!card)561 return -ENOMEM;562 563 init_completion(&card->fw_done);564 565 card->func = func;566 567 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;568 569 if (id->driver_data) {570 struct mwifiex_sdio_device *data = (void *)id->driver_data;571 572 card->firmware = data->firmware;573 card->firmware_sdiouart = data->firmware_sdiouart;574 card->reg = data->reg;575 card->max_ports = data->max_ports;576 card->mp_agg_pkt_limit = data->mp_agg_pkt_limit;577 card->supports_sdio_new_mode = data->supports_sdio_new_mode;578 card->has_control_mask = data->has_control_mask;579 card->tx_buf_size = data->tx_buf_size;580 card->mp_tx_agg_buf_size = data->mp_tx_agg_buf_size;581 card->mp_rx_agg_buf_size = data->mp_rx_agg_buf_size;582 card->can_dump_fw = data->can_dump_fw;583 card->fw_dump_enh = data->fw_dump_enh;584 card->can_auto_tdls = data->can_auto_tdls;585 card->can_ext_scan = data->can_ext_scan;586 card->fw_ready_extra_delay = data->fw_ready_extra_delay;587 card->host_mlme = data->host_mlme;588 INIT_WORK(&card->work, mwifiex_sdio_work);589 }590 591 sdio_claim_host(func);592 ret = sdio_enable_func(func);593 sdio_release_host(func);594 595 if (ret) {596 dev_err(&func->dev, "failed to enable function\n");597 return ret;598 }599 600 /* device tree node parsing and platform specific configuration*/601 if (func->dev.of_node) {602 ret = mwifiex_sdio_probe_of(&func->dev);603 if (ret)604 goto err_disable;605 }606 607 ret = mwifiex_add_card(card, &card->fw_done, &sdio_ops,608 MWIFIEX_SDIO, &func->dev);609 if (ret) {610 dev_err(&func->dev, "add card failed\n");611 goto err_disable;612 }613 614 return 0;615 616err_disable:617 sdio_claim_host(func);618 sdio_disable_func(func);619 sdio_release_host(func);620 621 return ret;622}623 624/*625 * SDIO resume.626 *627 * Kernel needs to suspend all functions separately. Therefore all628 * registered functions must have drivers with suspend and resume629 * methods. Failing that the kernel simply removes the whole card.630 *631 * If already not resumed, this function turns on the traffic and632 * sends a host sleep cancel request to the firmware.633 */634static int mwifiex_sdio_resume(struct device *dev)635{636 struct sdio_func *func = dev_to_sdio_func(dev);637 struct sdio_mmc_card *card;638 struct mwifiex_adapter *adapter;639 640 card = sdio_get_drvdata(func);641 if (!card || !card->adapter) {642 dev_err(dev, "resume: invalid card or adapter\n");643 return 0;644 }645 646 adapter = card->adapter;647 648 if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {649 mwifiex_dbg(adapter, WARN,650 "device already resumed\n");651 return 0;652 }653 654 clear_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);655 656 /* Disable Host Sleep */657 mwifiex_cancel_hs(mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),658 MWIFIEX_SYNC_CMD);659 660 mwifiex_disable_wake(adapter);661 662 return 0;663}664 665/* Write data into SDIO card register. Caller claims SDIO device. */666static int667mwifiex_write_reg_locked(struct sdio_func *func, u32 reg, u8 data)668{669 int ret = -1;670 671 sdio_writeb(func, data, reg, &ret);672 return ret;673}674 675/* This function writes data into SDIO card register.676 */677static int678mwifiex_write_reg(struct mwifiex_adapter *adapter, u32 reg, u8 data)679{680 struct sdio_mmc_card *card = adapter->card;681 int ret;682 683 sdio_claim_host(card->func);684 ret = mwifiex_write_reg_locked(card->func, reg, data);685 sdio_release_host(card->func);686 687 return ret;688}689 690/* This function reads data from SDIO card register.691 */692static int693mwifiex_read_reg(struct mwifiex_adapter *adapter, u32 reg, u8 *data)694{695 struct sdio_mmc_card *card = adapter->card;696 int ret = -1;697 u8 val;698 699 sdio_claim_host(card->func);700 val = sdio_readb(card->func, reg, &ret);701 sdio_release_host(card->func);702 703 *data = val;704 705 return ret;706}707 708/* This function writes multiple data into SDIO card memory.709 *710 * This does not work in suspended mode.711 */712static int713mwifiex_write_data_sync(struct mwifiex_adapter *adapter,714 u8 *buffer, u32 pkt_len, u32 port)715{716 struct sdio_mmc_card *card = adapter->card;717 int ret;718 u8 blk_mode =719 (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE : BLOCK_MODE;720 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;721 u32 blk_cnt =722 (blk_mode ==723 BLOCK_MODE) ? (pkt_len /724 MWIFIEX_SDIO_BLOCK_SIZE) : pkt_len;725 u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);726 727 if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) {728 mwifiex_dbg(adapter, ERROR,729 "%s: not allowed while suspended\n", __func__);730 return -1;731 }732 733 sdio_claim_host(card->func);734 735 ret = sdio_writesb(card->func, ioport, buffer, blk_cnt * blk_size);736 737 sdio_release_host(card->func);738 739 return ret;740}741 742/* This function reads multiple data from SDIO card memory.743 */744static int mwifiex_read_data_sync(struct mwifiex_adapter *adapter, u8 *buffer,745 u32 len, u32 port, u8 claim)746{747 struct sdio_mmc_card *card = adapter->card;748 int ret;749 u8 blk_mode = (port & MWIFIEX_SDIO_BYTE_MODE_MASK) ? BYTE_MODE750 : BLOCK_MODE;751 u32 blk_size = (blk_mode == BLOCK_MODE) ? MWIFIEX_SDIO_BLOCK_SIZE : 1;752 u32 blk_cnt = (blk_mode == BLOCK_MODE) ? (len / MWIFIEX_SDIO_BLOCK_SIZE)753 : len;754 u32 ioport = (port & MWIFIEX_SDIO_IO_PORT_MASK);755 756 if (claim)757 sdio_claim_host(card->func);758 759 ret = sdio_readsb(card->func, buffer, ioport, blk_cnt * blk_size);760 761 if (claim)762 sdio_release_host(card->func);763 764 return ret;765}766 767/* This function reads the firmware status.768 */769static int770mwifiex_sdio_read_fw_status(struct mwifiex_adapter *adapter, u16 *dat)771{772 struct sdio_mmc_card *card = adapter->card;773 const struct mwifiex_sdio_card_reg *reg = card->reg;774 u8 fws0, fws1;775 776 if (mwifiex_read_reg(adapter, reg->status_reg_0, &fws0))777 return -1;778 779 if (mwifiex_read_reg(adapter, reg->status_reg_1, &fws1))780 return -1;781 782 *dat = (u16)((fws1 << 8) | fws0);783 return 0;784}785 786/* This function checks the firmware status in card.787 */788static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,789 u32 poll_num)790{791 struct sdio_mmc_card *card = adapter->card;792 int ret = 0;793 u16 firmware_stat = 0;794 u32 tries;795 796 for (tries = 0; tries < poll_num; tries++) {797 ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);798 if (ret)799 continue;800 if (firmware_stat == FIRMWARE_READY_SDIO) {801 ret = 0;802 break;803 }804 805 msleep(100);806 ret = -1;807 }808 809 if (card->fw_ready_extra_delay &&810 firmware_stat == FIRMWARE_READY_SDIO)811 /* firmware might pretend to be ready, when it's not.812 * Wait a little bit more as a workaround.813 */814 msleep(100);815 816 return ret;817}818 819/* This function checks if WLAN is the winner.820 */821static int mwifiex_check_winner_status(struct mwifiex_adapter *adapter)822{823 int ret = 0;824 u8 winner = 0;825 struct sdio_mmc_card *card = adapter->card;826 827 if (mwifiex_read_reg(adapter, card->reg->status_reg_0, &winner))828 return -1;829 830 if (winner)831 adapter->winner = 0;832 else833 adapter->winner = 1;834 835 return ret;836}837 838/*839 * SDIO remove.840 *841 * This function removes the interface and frees up the card structure.842 */843static void844mwifiex_sdio_remove(struct sdio_func *func)845{846 struct sdio_mmc_card *card;847 struct mwifiex_adapter *adapter;848 struct mwifiex_private *priv;849 int ret = 0;850 u16 firmware_stat;851 852 card = sdio_get_drvdata(func);853 if (!card)854 return;855 856 wait_for_completion(&card->fw_done);857 858 adapter = card->adapter;859 if (!adapter || !adapter->priv_num)860 return;861 862 mwifiex_dbg(adapter, INFO, "info: SDIO func num=%d\n", func->num);863 864 ret = mwifiex_sdio_read_fw_status(adapter, &firmware_stat);865 if (!ret && firmware_stat == FIRMWARE_READY_SDIO &&866 !adapter->mfg_mode) {867 mwifiex_deauthenticate_all(adapter);868 869 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);870 mwifiex_disable_auto_ds(priv);871 mwifiex_init_shutdown_fw(priv, MWIFIEX_FUNC_SHUTDOWN);872 }873 874 mwifiex_remove_card(adapter);875}876 877/*878 * SDIO suspend.879 *880 * Kernel needs to suspend all functions separately. Therefore all881 * registered functions must have drivers with suspend and resume882 * methods. Failing that the kernel simply removes the whole card.883 *884 * If already not suspended, this function allocates and sends a host885 * sleep activate request to the firmware and turns off the traffic.886 */887static int mwifiex_sdio_suspend(struct device *dev)888{889 struct sdio_func *func = dev_to_sdio_func(dev);890 struct sdio_mmc_card *card;891 struct mwifiex_adapter *adapter;892 mmc_pm_flag_t pm_flag = 0;893 int ret = 0;894 895 pm_flag = sdio_get_host_pm_caps(func);896 pr_debug("cmd: %s: suspend: PM flag = 0x%x\n",897 sdio_func_id(func), pm_flag);898 if (!(pm_flag & MMC_PM_KEEP_POWER)) {899 dev_err(dev, "%s: cannot remain alive while host is"900 " suspended\n", sdio_func_id(func));901 return -ENOSYS;902 }903 904 card = sdio_get_drvdata(func);905 if (!card) {906 dev_err(dev, "suspend: invalid card\n");907 return 0;908 }909 910 /* Might still be loading firmware */911 wait_for_completion(&card->fw_done);912 913 adapter = card->adapter;914 if (!adapter) {915 dev_err(dev, "adapter is not valid\n");916 return 0;917 }918 919 if (!adapter->is_up)920 return -EBUSY;921 922 mwifiex_enable_wake(adapter);923 924 /* Enable the Host Sleep */925 if (!mwifiex_enable_hs(adapter)) {926 mwifiex_dbg(adapter, ERROR,927 "cmd: failed to suspend\n");928 clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);929 mwifiex_disable_wake(adapter);930 return -EFAULT;931 }932 933 mwifiex_dbg(adapter, INFO,934 "cmd: suspend with MMC_PM_KEEP_POWER\n");935 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);936 937 /* Indicate device suspended */938 set_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags);939 clear_bit(MWIFIEX_IS_HS_ENABLING, &adapter->work_flags);940 941 return ret;942}943 944static void mwifiex_sdio_coredump(struct device *dev)945{946 struct sdio_func *func = dev_to_sdio_func(dev);947 struct sdio_mmc_card *card;948 949 card = sdio_get_drvdata(func);950 if (!test_and_set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,951 &card->work_flags))952 schedule_work(&card->work);953}954 955/* WLAN IDs */956static const struct sdio_device_id mwifiex_ids[] = {957 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8786_WLAN),958 .driver_data = (unsigned long) &mwifiex_sdio_sd8786},959 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8787_WLAN),960 .driver_data = (unsigned long) &mwifiex_sdio_sd8787},961 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_WLAN),962 .driver_data = (unsigned long) &mwifiex_sdio_sd8797},963 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897_WLAN),964 .driver_data = (unsigned long) &mwifiex_sdio_sd8897},965 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8887_WLAN),966 .driver_data = (unsigned long)&mwifiex_sdio_sd8887},967 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8801_WLAN),968 .driver_data = (unsigned long)&mwifiex_sdio_sd8801},969 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8977_WLAN),970 .driver_data = (unsigned long)&mwifiex_sdio_sd8977},971 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8978_WLAN),972 .driver_data = (unsigned long)&mwifiex_sdio_sd8978},973 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8987_WLAN),974 .driver_data = (unsigned long)&mwifiex_sdio_sd8987},975 {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8997_WLAN),976 .driver_data = (unsigned long)&mwifiex_sdio_sd8997},977 {},978};979 980MODULE_DEVICE_TABLE(sdio, mwifiex_ids);981 982static const struct dev_pm_ops mwifiex_sdio_pm_ops = {983 .suspend = mwifiex_sdio_suspend,984 .resume = mwifiex_sdio_resume,985};986 987static struct sdio_driver mwifiex_sdio = {988 .name = "mwifiex_sdio",989 .id_table = mwifiex_ids,990 .probe = mwifiex_sdio_probe,991 .remove = mwifiex_sdio_remove,992 .drv = {993 .coredump = mwifiex_sdio_coredump,994 .pm = &mwifiex_sdio_pm_ops,995 }996};997 998/*999 * This function wakes up the card.1000 *1001 * A host power up command is written to the card configuration1002 * register to wake up the card.1003 */1004static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)1005{1006 mwifiex_dbg(adapter, EVENT,1007 "event: wakeup device...\n");1008 1009 return mwifiex_write_reg(adapter, CONFIGURATION_REG, HOST_POWER_UP);1010}1011 1012/*1013 * This function is called after the card has woken up.1014 *1015 * The card configuration register is reset.1016 */1017static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter)1018{1019 mwifiex_dbg(adapter, EVENT,1020 "cmd: wakeup device completed\n");1021 1022 return mwifiex_write_reg(adapter, CONFIGURATION_REG, 0);1023}1024 1025static int mwifiex_sdio_dnld_fw(struct mwifiex_adapter *adapter,1026 struct mwifiex_fw_image *fw)1027{1028 struct sdio_mmc_card *card = adapter->card;1029 int ret;1030 1031 sdio_claim_host(card->func);1032 ret = mwifiex_dnld_fw(adapter, fw);1033 sdio_release_host(card->func);1034 1035 return ret;1036}1037 1038/*1039 * This function is used to initialize IO ports for the1040 * chipsets supporting SDIO new mode eg SD8897.1041 */1042static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter)1043{1044 u8 reg;1045 struct sdio_mmc_card *card = adapter->card;1046 1047 adapter->ioport = MEM_PORT;1048 1049 /* enable sdio new mode */1050 if (mwifiex_read_reg(adapter, card->reg->card_cfg_2_1_reg, ®))1051 return -1;1052 if (mwifiex_write_reg(adapter, card->reg->card_cfg_2_1_reg,1053 reg | CMD53_NEW_MODE))1054 return -1;1055 1056 /* Configure cmd port and enable reading rx length from the register */1057 if (mwifiex_read_reg(adapter, card->reg->cmd_cfg_0, ®))1058 return -1;1059 if (mwifiex_write_reg(adapter, card->reg->cmd_cfg_0,1060 reg | CMD_PORT_RD_LEN_EN))1061 return -1;1062 1063 /* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is1064 * completed1065 */1066 if (mwifiex_read_reg(adapter, card->reg->cmd_cfg_1, ®))1067 return -1;1068 if (mwifiex_write_reg(adapter, card->reg->cmd_cfg_1,1069 reg | CMD_PORT_AUTO_EN))1070 return -1;1071 1072 return 0;1073}1074 1075/* This function initializes the IO ports.1076 *1077 * The following operations are performed -1078 * - Read the IO ports (0, 1 and 2)1079 * - Set host interrupt Reset-To-Read to clear1080 * - Set auto re-enable interrupt1081 */1082static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter)1083{1084 u8 reg;1085 struct sdio_mmc_card *card = adapter->card;1086 1087 adapter->ioport = 0;1088 1089 if (card->supports_sdio_new_mode) {1090 if (mwifiex_init_sdio_new_mode(adapter))1091 return -1;1092 goto cont;1093 }1094 1095 /* Read the IO port */1096 if (!mwifiex_read_reg(adapter, card->reg->io_port_0_reg, ®))1097 adapter->ioport |= (reg & 0xff);1098 else1099 return -1;1100 1101 if (!mwifiex_read_reg(adapter, card->reg->io_port_1_reg, ®))1102 adapter->ioport |= ((reg & 0xff) << 8);1103 else1104 return -1;1105 1106 if (!mwifiex_read_reg(adapter, card->reg->io_port_2_reg, ®))1107 adapter->ioport |= ((reg & 0xff) << 16);1108 else1109 return -1;1110cont:1111 mwifiex_dbg(adapter, INFO,1112 "info: SDIO FUNC1 IO port: %#x\n", adapter->ioport);1113 1114 /* Set Host interrupt reset to read to clear */1115 if (mwifiex_read_reg(adapter, card->reg->host_int_rsr_reg, ®))1116 return -1;1117 if (mwifiex_write_reg(adapter, card->reg->host_int_rsr_reg,1118 reg | card->reg->sdio_int_mask))1119 return -1;1120 1121 /* Dnld/Upld ready set to auto reset */1122 if (mwifiex_read_reg(adapter, card->reg->card_misc_cfg_reg, ®))1123 return -1;1124 if (mwifiex_write_reg(adapter, card->reg->card_misc_cfg_reg,1125 reg | AUTO_RE_ENABLE_INT))1126 return -1;1127 1128 return 0;1129}1130 1131/*1132 * This function sends data to the card.1133 */1134static int mwifiex_write_data_to_card(struct mwifiex_adapter *adapter,1135 u8 *payload, u32 pkt_len, u32 port)1136{1137 u32 i = 0;1138 int ret;1139 1140 do {1141 ret = mwifiex_write_data_sync(adapter, payload, pkt_len, port);1142 if (ret) {1143 i++;1144 mwifiex_dbg(adapter, ERROR,1145 "host_to_card, write iomem\t"1146 "(%d) failed: %d\n", i, ret);1147 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))1148 mwifiex_dbg(adapter, ERROR,1149 "write CFG reg failed\n");1150 1151 ret = -1;1152 if (i > MAX_WRITE_IOMEM_RETRY)1153 return ret;1154 }1155 } while (ret == -1);1156 1157 return ret;1158}1159 1160/*1161 * This function gets the read port.1162 *1163 * If control port bit is set in MP read bitmap, the control port1164 * is returned, otherwise the current read port is returned and1165 * the value is increased (provided it does not reach the maximum1166 * limit, in which case it is reset to 1)1167 */1168static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port)1169{1170 struct sdio_mmc_card *card = adapter->card;1171 const struct mwifiex_sdio_card_reg *reg = card->reg;1172 u32 rd_bitmap = card->mp_rd_bitmap;1173 1174 mwifiex_dbg(adapter, DATA,1175 "data: mp_rd_bitmap=0x%08x\n", rd_bitmap);1176 1177 if (card->supports_sdio_new_mode) {1178 if (!(rd_bitmap & reg->data_port_mask))1179 return -1;1180 } else {1181 if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask)))1182 return -1;1183 }1184 1185 if ((card->has_control_mask) &&1186 (card->mp_rd_bitmap & CTRL_PORT_MASK)) {1187 card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK);1188 *port = CTRL_PORT;1189 mwifiex_dbg(adapter, DATA,1190 "data: port=%d mp_rd_bitmap=0x%08x\n",1191 *port, card->mp_rd_bitmap);1192 return 0;1193 }1194 1195 if (!(card->mp_rd_bitmap & (1 << card->curr_rd_port)))1196 return -1;1197 1198 /* We are now handling the SDIO data ports */1199 card->mp_rd_bitmap &= (u32)(~(1 << card->curr_rd_port));1200 *port = card->curr_rd_port;1201 1202 if (++card->curr_rd_port == card->max_ports)1203 card->curr_rd_port = reg->start_rd_port;1204 1205 mwifiex_dbg(adapter, DATA,1206 "data: port=%d mp_rd_bitmap=0x%08x -> 0x%08x\n",1207 *port, rd_bitmap, card->mp_rd_bitmap);1208 1209 return 0;1210}1211 1212/*1213 * This function gets the write port for data.1214 *1215 * The current write port is returned if available and the value is1216 * increased (provided it does not reach the maximum limit, in which1217 * case it is reset to 1)1218 */1219static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)1220{1221 struct sdio_mmc_card *card = adapter->card;1222 const struct mwifiex_sdio_card_reg *reg = card->reg;1223 u32 wr_bitmap = card->mp_wr_bitmap;1224 1225 mwifiex_dbg(adapter, DATA,1226 "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);1227 1228 if (!(wr_bitmap & card->mp_data_port_mask)) {1229 adapter->data_sent = true;1230 return -EBUSY;1231 }1232 1233 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {1234 card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));1235 *port = card->curr_wr_port;1236 if (++card->curr_wr_port == card->mp_end_port)1237 card->curr_wr_port = reg->start_wr_port;1238 } else {1239 adapter->data_sent = true;1240 return -EBUSY;1241 }1242 1243 if ((card->has_control_mask) && (*port == CTRL_PORT)) {1244 mwifiex_dbg(adapter, ERROR,1245 "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",1246 *port, card->curr_wr_port, wr_bitmap,1247 card->mp_wr_bitmap);1248 return -1;1249 }1250 1251 mwifiex_dbg(adapter, DATA,1252 "data: port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n",1253 *port, wr_bitmap, card->mp_wr_bitmap);1254 1255 return 0;1256}1257 1258/*1259 * This function polls the card status.1260 */1261static int1262mwifiex_sdio_poll_card_status(struct mwifiex_adapter *adapter, u8 bits)1263{1264 struct sdio_mmc_card *card = adapter->card;1265 u32 tries;1266 u8 cs;1267 1268 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {1269 if (mwifiex_read_reg(adapter, card->reg->poll_reg, &cs))1270 break;1271 else if ((cs & bits) == bits)1272 return 0;1273 1274 usleep_range(10, 20);1275 }1276 1277 mwifiex_dbg(adapter, ERROR,1278 "poll card status failed, tries = %d\n", tries);1279 1280 return -1;1281}1282 1283/*1284 * This function disables the host interrupt.1285 *1286 * The host interrupt mask is read, the disable bit is reset and1287 * written back to the card host interrupt mask register.1288 */1289static void mwifiex_sdio_disable_host_int(struct mwifiex_adapter *adapter)1290{1291 struct sdio_mmc_card *card = adapter->card;1292 struct sdio_func *func = card->func;1293 1294 sdio_claim_host(func);1295 mwifiex_write_reg_locked(func, card->reg->host_int_mask_reg, 0);1296 sdio_release_irq(func);1297 sdio_release_host(func);1298}1299 1300/*1301 * This function reads the interrupt status from card.1302 */1303static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter)1304{1305 struct sdio_mmc_card *card = adapter->card;1306 u8 sdio_ireg;1307 unsigned long flags;1308 1309 if (mwifiex_read_data_sync(adapter, card->mp_regs,1310 card->reg->max_mp_regs,1311 REG_PORT | MWIFIEX_SDIO_BYTE_MODE_MASK, 0)) {1312 mwifiex_dbg(adapter, ERROR, "read mp_regs failed\n");1313 return;1314 }1315 1316 sdio_ireg = card->mp_regs[card->reg->host_int_status_reg];1317 if (sdio_ireg) {1318 /*1319 * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS1320 * For SDIO new mode CMD port interrupts1321 * DN_LD_CMD_PORT_HOST_INT_STATUS and/or1322 * UP_LD_CMD_PORT_HOST_INT_STATUS1323 * Clear the interrupt status register1324 */1325 mwifiex_dbg(adapter, INTR,1326 "int: sdio_ireg = %#x\n", sdio_ireg);1327 spin_lock_irqsave(&adapter->int_lock, flags);1328 adapter->int_status |= sdio_ireg;1329 spin_unlock_irqrestore(&adapter->int_lock, flags);1330 }1331}1332 1333/*1334 * SDIO interrupt handler.1335 *1336 * This function reads the interrupt status from firmware and handles1337 * the interrupt in current thread (ksdioirqd) right away.1338 */1339static void1340mwifiex_sdio_interrupt(struct sdio_func *func)1341{1342 struct mwifiex_adapter *adapter;1343 struct sdio_mmc_card *card;1344 1345 card = sdio_get_drvdata(func);1346 if (!card || !card->adapter) {1347 pr_err("int: func=%p card=%p adapter=%p\n",1348 func, card, card ? card->adapter : NULL);1349 return;1350 }1351 adapter = card->adapter;1352 1353 if (!adapter->pps_uapsd_mode && adapter->ps_state == PS_STATE_SLEEP)1354 adapter->ps_state = PS_STATE_AWAKE;1355 1356 mwifiex_interrupt_status(adapter);1357 mwifiex_main_process(adapter);1358}1359 1360/*1361 * This function enables the host interrupt.1362 *1363 * The host interrupt enable mask is written to the card1364 * host interrupt mask register.1365 */1366static int mwifiex_sdio_enable_host_int(struct mwifiex_adapter *adapter)1367{1368 struct sdio_mmc_card *card = adapter->card;1369 struct sdio_func *func = card->func;1370 int ret;1371 1372 sdio_claim_host(func);1373 1374 /* Request the SDIO IRQ */1375 ret = sdio_claim_irq(func, mwifiex_sdio_interrupt);1376 if (ret) {1377 mwifiex_dbg(adapter, ERROR,1378 "claim irq failed: ret=%d\n", ret);1379 goto out;1380 }1381 1382 /* Simply write the mask to the register */1383 ret = mwifiex_write_reg_locked(func, card->reg->host_int_mask_reg,1384 card->reg->host_int_enable);1385 if (ret) {1386 mwifiex_dbg(adapter, ERROR,1387 "enable host interrupt failed\n");1388 sdio_release_irq(func);1389 }1390 1391out:1392 sdio_release_host(func);1393 return ret;1394}1395 1396/*1397 * This function sends a data buffer to the card.1398 */1399static int mwifiex_sdio_card_to_host(struct mwifiex_adapter *adapter,1400 u32 *type, u8 *buffer,1401 u32 npayload, u32 ioport)1402{1403 int ret;1404 u32 nb;1405 1406 if (!buffer) {1407 mwifiex_dbg(adapter, ERROR,1408 "%s: buffer is NULL\n", __func__);1409 return -1;1410 }1411 1412 ret = mwifiex_read_data_sync(adapter, buffer, npayload, ioport, 1);1413 1414 if (ret) {1415 mwifiex_dbg(adapter, ERROR,1416 "%s: read iomem failed: %d\n", __func__,1417 ret);1418 return -1;1419 }1420 1421 nb = get_unaligned_le16((buffer));1422 if (nb > npayload) {1423 mwifiex_dbg(adapter, ERROR,1424 "%s: invalid packet, nb=%d npayload=%d\n",1425 __func__, nb, npayload);1426 return -1;1427 }1428 1429 *type = get_unaligned_le16((buffer + 2));1430 1431 return ret;1432}1433 1434/*1435 * This function downloads the firmware to the card.1436 *1437 * Firmware is downloaded to the card in blocks. Every block download1438 * is tested for CRC errors, and retried a number of times before1439 * returning failure.1440 */1441static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,1442 struct mwifiex_fw_image *fw)1443{1444 struct sdio_mmc_card *card = adapter->card;1445 const struct mwifiex_sdio_card_reg *reg = card->reg;1446 int ret;1447 u8 *firmware = fw->fw_buf;1448 u32 firmware_len = fw->fw_len;1449 u32 offset = 0;1450 u8 base0, base1;1451 u8 *fwbuf;1452 u16 len = 0;1453 u32 txlen, tx_blocks = 0, tries;1454 u32 i = 0;1455 1456 if (!firmware_len) {1457 mwifiex_dbg(adapter, ERROR,1458 "firmware image not found! Terminating download\n");1459 return -1;1460 }1461 1462 mwifiex_dbg(adapter, INFO,1463 "info: downloading FW image (%d bytes)\n",1464 firmware_len);1465 1466 /* Assume that the allocated buffer is 8-byte aligned */1467 fwbuf = kzalloc(MWIFIEX_UPLD_SIZE, GFP_KERNEL);1468 if (!fwbuf)1469 return -ENOMEM;1470 1471 sdio_claim_host(card->func);1472 1473 /* Perform firmware data transfer */1474 do {1475 /* The host polls for the DN_LD_CARD_RDY and CARD_IO_READY1476 bits */1477 ret = mwifiex_sdio_poll_card_status(adapter, CARD_IO_READY |1478 DN_LD_CARD_RDY);1479 if (ret) {1480 mwifiex_dbg(adapter, ERROR,1481 "FW download with helper:\t"1482 "poll status timeout @ %d\n", offset);1483 goto done;1484 }1485 1486 /* More data? */1487 if (offset >= firmware_len)1488 break;1489 1490 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {1491 ret = mwifiex_read_reg(adapter, reg->base_0_reg,1492 &base0);1493 if (ret) {1494 mwifiex_dbg(adapter, ERROR,1495 "dev BASE0 register read failed:\t"1496 "base0=%#04X(%d). Terminating dnld\n",1497 base0, base0);1498 goto done;1499 }1500 ret = mwifiex_read_reg(adapter, reg->base_1_reg,1501 &base1);1502 if (ret) {1503 mwifiex_dbg(adapter, ERROR,1504 "dev BASE1 register read failed:\t"1505 "base1=%#04X(%d). Terminating dnld\n",1506 base1, base1);1507 goto done;1508 }1509 len = (u16) (((base1 & 0xff) << 8) | (base0 & 0xff));1510 1511 if (len)1512 break;1513 1514 usleep_range(10, 20);1515 }1516 1517 if (!len) {1518 break;1519 } else if (len > MWIFIEX_UPLD_SIZE) {1520 mwifiex_dbg(adapter, ERROR,1521 "FW dnld failed @ %d, invalid length %d\n",1522 offset, len);1523 ret = -1;1524 goto done;1525 }1526 1527 txlen = len;1528 1529 if (len & BIT(0)) {1530 i++;1531 if (i > MAX_WRITE_IOMEM_RETRY) {1532 mwifiex_dbg(adapter, ERROR,1533 "FW dnld failed @ %d, over max retry\n",1534 offset);1535 ret = -1;1536 goto done;1537 }1538 mwifiex_dbg(adapter, ERROR,1539 "CRC indicated by the helper:\t"1540 "len = 0x%04X, txlen = %d\n", len, txlen);1541 len &= ~BIT(0);1542 /* Setting this to 0 to resend from same offset */1543 txlen = 0;1544 } else {1545 i = 0;1546 1547 /* Set blocksize to transfer - checking for last1548 block */1549 if (firmware_len - offset < txlen)1550 txlen = firmware_len - offset;1551 1552 tx_blocks = (txlen + MWIFIEX_SDIO_BLOCK_SIZE - 1)1553 / MWIFIEX_SDIO_BLOCK_SIZE;1554 1555 /* Copy payload to buffer */1556 memmove(fwbuf, &firmware[offset], txlen);1557 }1558 1559 ret = mwifiex_write_data_sync(adapter, fwbuf, tx_blocks *1560 MWIFIEX_SDIO_BLOCK_SIZE,1561 adapter->ioport);1562 if (ret) {1563 mwifiex_dbg(adapter, ERROR,1564 "FW download, write iomem (%d) failed @ %d\n",1565 i, offset);1566 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, 0x04))1567 mwifiex_dbg(adapter, ERROR,1568 "write CFG reg failed\n");1569 1570 ret = -1;1571 goto done;1572 }1573 1574 offset += txlen;1575 } while (true);1576 1577 mwifiex_dbg(adapter, MSG,1578 "info: FW download over, size %d bytes\n", offset);1579 1580 ret = 0;1581done:1582 sdio_release_host(card->func);1583 kfree(fwbuf);1584 return ret;1585}1586 1587/*1588 * This function decodes sdio aggregation pkt.1589 *1590 * Based on the data block size and pkt_len,1591 * skb data will be decoded to few packets.1592 */1593static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,1594 struct sk_buff *skb)1595{1596 u32 total_pkt_len, pkt_len;1597 struct sk_buff *skb_deaggr;1598 u16 blk_size;1599 u8 blk_num;1600 u8 *data;1601 1602 data = skb->data;1603 total_pkt_len = skb->len;1604 1605 while (total_pkt_len >= (SDIO_HEADER_OFFSET + adapter->intf_hdr_len)) {1606 if (total_pkt_len < adapter->sdio_rx_block_size)1607 break;1608 blk_num = *(data + BLOCK_NUMBER_OFFSET);1609 blk_size = adapter->sdio_rx_block_size * blk_num;1610 if (blk_size > total_pkt_len) {1611 mwifiex_dbg(adapter, ERROR,1612 "%s: error in blk_size,\t"1613 "blk_num=%d, blk_size=%d, total_pkt_len=%d\n",1614 __func__, blk_num, blk_size, total_pkt_len);1615 break;1616 }1617 pkt_len = get_unaligned_le16((data +1618 SDIO_HEADER_OFFSET));1619 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {1620 mwifiex_dbg(adapter, ERROR,1621 "%s: error in pkt_len,\t"1622 "pkt_len=%d, blk_size=%d\n",1623 __func__, pkt_len, blk_size);1624 break;1625 }1626 1627 skb_deaggr = mwifiex_alloc_dma_align_buf(pkt_len, GFP_KERNEL);1628 if (!skb_deaggr)1629 break;1630 skb_put(skb_deaggr, pkt_len);1631 memcpy(skb_deaggr->data, data + SDIO_HEADER_OFFSET, pkt_len);1632 skb_pull(skb_deaggr, adapter->intf_hdr_len);1633 1634 mwifiex_handle_rx_packet(adapter, skb_deaggr);1635 data += blk_size;1636 total_pkt_len -= blk_size;1637 }1638}1639 1640/*1641 * This function decodes a received packet.1642 *1643 * Based on the type, the packet is treated as either a data, or1644 * a command response, or an event, and the correct handler1645 * function is invoked.1646 */1647static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,1648 struct sk_buff *skb, u32 upld_typ)1649{1650 u8 *cmd_buf;1651 u16 pkt_len;1652 struct mwifiex_rxinfo *rx_info;1653 1654 pkt_len = get_unaligned_le16(skb->data);1655 1656 if (upld_typ != MWIFIEX_TYPE_AGGR_DATA) {1657 skb_trim(skb, pkt_len);1658 skb_pull(skb, adapter->intf_hdr_len);1659 }1660 1661 switch (upld_typ) {1662 case MWIFIEX_TYPE_AGGR_DATA:1663 mwifiex_dbg(adapter, INFO,1664 "info: --- Rx: Aggr Data packet ---\n");1665 rx_info = MWIFIEX_SKB_RXCB(skb);1666 rx_info->buf_type = MWIFIEX_TYPE_AGGR_DATA;1667 if (adapter->rx_work_enabled) {1668 skb_queue_tail(&adapter->rx_data_q, skb);1669 atomic_inc(&adapter->rx_pending);1670 adapter->data_received = true;1671 } else {1672 mwifiex_deaggr_sdio_pkt(adapter, skb);1673 dev_kfree_skb_any(skb);1674 }1675 break;1676 1677 case MWIFIEX_TYPE_DATA:1678 mwifiex_dbg(adapter, DATA,1679 "info: --- Rx: Data packet ---\n");1680 if (adapter->rx_work_enabled) {1681 skb_queue_tail(&adapter->rx_data_q, skb);1682 adapter->data_received = true;1683 atomic_inc(&adapter->rx_pending);1684 } else {1685 mwifiex_handle_rx_packet(adapter, skb);1686 }1687 break;1688 1689 case MWIFIEX_TYPE_CMD:1690 mwifiex_dbg(adapter, CMD,1691 "info: --- Rx: Cmd Response ---\n");1692 /* take care of curr_cmd = NULL case */1693 if (!adapter->curr_cmd) {1694 cmd_buf = adapter->upld_buf;1695 1696 if (adapter->ps_state == PS_STATE_SLEEP_CFM)1697 mwifiex_process_sleep_confirm_resp(adapter,1698 skb->data,1699 skb->len);1700 1701 memcpy(cmd_buf, skb->data,1702 min_t(u32, MWIFIEX_SIZE_OF_CMD_BUFFER,1703 skb->len));1704 1705 dev_kfree_skb_any(skb);1706 } else {1707 adapter->cmd_resp_received = true;1708 adapter->curr_cmd->resp_skb = skb;1709 }1710 break;1711 1712 case MWIFIEX_TYPE_EVENT:1713 mwifiex_dbg(adapter, EVENT,1714 "info: --- Rx: Event ---\n");1715 adapter->event_cause = get_unaligned_le32(skb->data);1716 1717 if ((skb->len > 0) && (skb->len < MAX_EVENT_SIZE))1718 memcpy(adapter->event_body,1719 skb->data + MWIFIEX_EVENT_HEADER_LEN,1720 skb->len);1721 1722 /* event cause has been saved to adapter->event_cause */1723 adapter->event_received = true;1724 adapter->event_skb = skb;1725 1726 break;1727 1728 default:1729 mwifiex_dbg(adapter, ERROR,1730 "unknown upload type %#x\n", upld_typ);1731 dev_kfree_skb_any(skb);1732 break;1733 }1734 1735 return 0;1736}1737 1738/*1739 * This function transfers received packets from card to driver, performing1740 * aggregation if required.1741 *1742 * For data received on control port, or if aggregation is disabled, the1743 * received buffers are uploaded as separate packets. However, if aggregation1744 * is enabled and required, the buffers are copied onto an aggregation buffer,1745 * provided there is space left, processed and finally uploaded.1746 */1747static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,1748 u16 rx_len, u8 port)1749{1750 struct sdio_mmc_card *card = adapter->card;1751 s32 f_do_rx_aggr = 0;1752 s32 f_do_rx_cur = 0;1753 s32 f_aggr_cur = 0;1754 s32 f_post_aggr_cur = 0;1755 struct sk_buff *skb_deaggr;1756 struct sk_buff *skb = NULL;1757 u32 pkt_len, pkt_type, mport, pind;1758 u8 *curr_ptr;1759 1760 if ((card->has_control_mask) && (port == CTRL_PORT)) {1761 /* Read the command Resp without aggr */1762 mwifiex_dbg(adapter, CMD,1763 "info: %s: no aggregation for cmd\t"1764 "response\n", __func__);1765 1766 f_do_rx_cur = 1;1767 goto rx_curr_single;1768 }1769 1770 if (!card->mpa_rx.enabled) {1771 mwifiex_dbg(adapter, WARN,1772 "info: %s: rx aggregation disabled\n",1773 __func__);1774 1775 f_do_rx_cur = 1;1776 goto rx_curr_single;1777 }1778 1779 if ((!card->has_control_mask && (card->mp_rd_bitmap &1780 card->reg->data_port_mask)) ||1781 (card->has_control_mask && (card->mp_rd_bitmap &1782 (~((u32) CTRL_PORT_MASK))))) {1783 /* Some more data RX pending */1784 mwifiex_dbg(adapter, INFO,1785 "info: %s: not last packet\n", __func__);1786 1787 if (MP_RX_AGGR_IN_PROGRESS(card)) {1788 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len)) {1789 f_aggr_cur = 1;1790 } else {1791 /* No room in Aggr buf, do rx aggr now */1792 f_do_rx_aggr = 1;1793 f_post_aggr_cur = 1;1794 }1795 } else {1796 /* Rx aggr not in progress */1797 f_aggr_cur = 1;1798 }1799 1800 } else {1801 /* No more data RX pending */1802 mwifiex_dbg(adapter, INFO,1803 "info: %s: last packet\n", __func__);1804 1805 if (MP_RX_AGGR_IN_PROGRESS(card)) {1806 f_do_rx_aggr = 1;1807 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len))1808 f_aggr_cur = 1;1809 else1810 /* No room in Aggr buf, do rx aggr now */1811 f_do_rx_cur = 1;1812 } else {1813 f_do_rx_cur = 1;1814 }1815 }1816 1817 if (f_aggr_cur) {1818 mwifiex_dbg(adapter, INFO,1819 "info: current packet aggregation\n");1820 /* Curr pkt can be aggregated */1821 mp_rx_aggr_setup(card, rx_len, port);1822 1823 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||1824 mp_rx_aggr_port_limit_reached(card)) {1825 mwifiex_dbg(adapter, INFO,1826 "info: %s: aggregated packet\t"1827 "limit reached\n", __func__);1828 /* No more pkts allowed in Aggr buf, rx it */1829 f_do_rx_aggr = 1;1830 }1831 }1832 1833 if (f_do_rx_aggr) {1834 /* do aggr RX now */1835 mwifiex_dbg(adapter, DATA,1836 "info: do_rx_aggr: num of packets: %d\n",1837 card->mpa_rx.pkt_cnt);1838 1839 if (card->supports_sdio_new_mode) {1840 int i;1841 u32 port_count;1842 1843 for (i = 0, port_count = 0; i < card->max_ports; i++)1844 if (card->mpa_rx.ports & BIT(i))1845 port_count++;1846 1847 /* Reading data from "start_port + 0" to "start_port +1848 * port_count -1", so decrease the count by 11849 */1850 port_count--;1851 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |1852 (port_count << 8)) + card->mpa_rx.start_port;1853 } else {1854 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |1855 (card->mpa_rx.ports << 4)) +1856 card->mpa_rx.start_port;1857 }1858 1859 if (card->mpa_rx.pkt_cnt == 1)1860 mport = adapter->ioport + card->mpa_rx.start_port;1861 1862 if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf,1863 card->mpa_rx.buf_len, mport, 1))1864 goto error;1865 1866 curr_ptr = card->mpa_rx.buf;1867 1868 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {1869 u32 *len_arr = card->mpa_rx.len_arr;1870 1871 /* get curr PKT len & type */1872 pkt_len = get_unaligned_le16(&curr_ptr[0]);1873 pkt_type = get_unaligned_le16(&curr_ptr[2]);1874 1875 /* copy pkt to deaggr buf */1876 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],1877 GFP_KERNEL);1878 if (!skb_deaggr) {1879 mwifiex_dbg(adapter, ERROR, "skb allocation failure\t"1880 "drop pkt len=%d type=%d\n",1881 pkt_len, pkt_type);1882 curr_ptr += len_arr[pind];1883 continue;1884 }1885 1886 skb_put(skb_deaggr, len_arr[pind]);1887 1888 if ((pkt_type == MWIFIEX_TYPE_DATA ||1889 (pkt_type == MWIFIEX_TYPE_AGGR_DATA &&1890 adapter->sdio_rx_aggr_enable)) &&1891 (pkt_len <= len_arr[pind])) {1892 1893 memcpy(skb_deaggr->data, curr_ptr, pkt_len);1894 1895 skb_trim(skb_deaggr, pkt_len);1896 1897 /* Process de-aggr packet */1898 mwifiex_decode_rx_packet(adapter, skb_deaggr,1899 pkt_type);1900 } else {1901 mwifiex_dbg(adapter, ERROR,1902 "drop wrong aggr pkt:\t"1903 "sdio_single_port_rx_aggr=%d\t"1904 "type=%d len=%d max_len=%d\n",1905 adapter->sdio_rx_aggr_enable,1906 pkt_type, pkt_len, len_arr[pind]);1907 dev_kfree_skb_any(skb_deaggr);1908 }1909 curr_ptr += len_arr[pind];1910 }1911 MP_RX_AGGR_BUF_RESET(card);1912 }1913 1914rx_curr_single:1915 if (f_do_rx_cur) {1916 mwifiex_dbg(adapter, INFO, "info: RX: port: %d, rx_len: %d\n",1917 port, rx_len);1918 1919 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL);1920 if (!skb) {1921 mwifiex_dbg(adapter, ERROR,1922 "single skb allocated fail,\t"1923 "drop pkt port=%d len=%d\n", port, rx_len);1924 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,1925 card->mpa_rx.buf, rx_len,1926 adapter->ioport + port))1927 goto error;1928 return 0;1929 }1930 1931 skb_put(skb, rx_len);1932 1933 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,1934 skb->data, skb->len,1935 adapter->ioport + port))1936 goto error;1937 if (!adapter->sdio_rx_aggr_enable &&1938 pkt_type == MWIFIEX_TYPE_AGGR_DATA) {1939 mwifiex_dbg(adapter, ERROR, "drop wrong pkt type %d\t"1940 "current SDIO RX Aggr not enabled\n",1941 pkt_type);1942 dev_kfree_skb_any(skb);1943 return 0;1944 }1945 1946 mwifiex_decode_rx_packet(adapter, skb, pkt_type);1947 }1948 if (f_post_aggr_cur) {1949 mwifiex_dbg(adapter, INFO,1950 "info: current packet aggregation\n");1951 /* Curr pkt can be aggregated */1952 mp_rx_aggr_setup(card, rx_len, port);1953 }1954 1955 return 0;1956error:1957 if (MP_RX_AGGR_IN_PROGRESS(card))1958 MP_RX_AGGR_BUF_RESET(card);1959 1960 if (f_do_rx_cur && skb)1961 /* Single transfer pending. Free curr buff also */1962 dev_kfree_skb_any(skb);1963 1964 return -1;1965}1966 1967/*1968 * This function checks the current interrupt status.1969 *1970 * The following interrupts are checked and handled by this function -1971 * - Data sent1972 * - Command sent1973 * - Packets received1974 *1975 * Since the firmware does not generate download ready interrupt if the1976 * port updated is command port only, command sent interrupt checking1977 * should be done manually, and for every SDIO interrupt.1978 *1979 * In case of Rx packets received, the packets are uploaded from card to1980 * host and processed accordingly.1981 */1982static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)1983{1984 struct sdio_mmc_card *card = adapter->card;1985 const struct mwifiex_sdio_card_reg *reg = card->reg;1986 int ret = 0;1987 u8 sdio_ireg;1988 struct sk_buff *skb;1989 u8 port = CTRL_PORT;1990 u32 len_reg_l, len_reg_u;1991 u32 rx_blocks;1992 u16 rx_len;1993 unsigned long flags;1994 u32 bitmap;1995 u8 cr;1996 1997 spin_lock_irqsave(&adapter->int_lock, flags);1998 sdio_ireg = adapter->int_status;1999 adapter->int_status = 0;2000 spin_unlock_irqrestore(&adapter->int_lock, flags);2001 2002 if (!sdio_ireg)2003 return ret;2004 2005 /* Following interrupt is only for SDIO new mode */2006 if (sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS && adapter->cmd_sent)2007 adapter->cmd_sent = false;2008 2009 /* Following interrupt is only for SDIO new mode */2010 if (sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) {2011 u32 pkt_type;2012 2013 /* read the len of control packet */2014 rx_len = card->mp_regs[reg->cmd_rd_len_1] << 8;2015 rx_len |= (u16)card->mp_regs[reg->cmd_rd_len_0];2016 rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE);2017 if (rx_len <= adapter->intf_hdr_len ||2018 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >2019 MWIFIEX_RX_DATA_BUF_SIZE)2020 return -1;2021 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);2022 mwifiex_dbg(adapter, INFO, "info: rx_len = %d\n", rx_len);2023 2024 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL);2025 if (!skb)2026 return -1;2027 2028 skb_put(skb, rx_len);2029 2030 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, skb->data,2031 skb->len, adapter->ioport |2032 CMD_PORT_SLCT)) {2033 mwifiex_dbg(adapter, ERROR,2034 "%s: failed to card_to_host", __func__);2035 dev_kfree_skb_any(skb);2036 goto term_cmd;2037 }2038 2039 if ((pkt_type != MWIFIEX_TYPE_CMD) &&2040 (pkt_type != MWIFIEX_TYPE_EVENT))2041 mwifiex_dbg(adapter, ERROR,2042 "%s:Received wrong packet on cmd port",2043 __func__);2044 2045 mwifiex_decode_rx_packet(adapter, skb, pkt_type);2046 }2047 2048 if (sdio_ireg & DN_LD_HOST_INT_STATUS) {2049 bitmap = (u32) card->mp_regs[reg->wr_bitmap_l];2050 bitmap |= ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8;2051 if (card->supports_sdio_new_mode) {2052 bitmap |=2053 ((u32) card->mp_regs[reg->wr_bitmap_1l]) << 16;2054 bitmap |=2055 ((u32) card->mp_regs[reg->wr_bitmap_1u]) << 24;2056 }2057 card->mp_wr_bitmap = bitmap;2058 2059 mwifiex_dbg(adapter, INTR,2060 "int: DNLD: wr_bitmap=0x%x\n",2061 card->mp_wr_bitmap);2062 if (adapter->data_sent &&2063 (card->mp_wr_bitmap & card->mp_data_port_mask)) {2064 mwifiex_dbg(adapter, INTR,2065 "info: <--- Tx DONE Interrupt --->\n");2066 adapter->data_sent = false;2067 }2068 }2069 2070 /* As firmware will not generate download ready interrupt if the port2071 updated is command port only, cmd_sent should be done for any SDIO2072 interrupt. */2073 if (card->has_control_mask && adapter->cmd_sent) {2074 /* Check if firmware has attach buffer at command port and2075 update just that in wr_bit_map. */2076 card->mp_wr_bitmap |=2077 (u32) card->mp_regs[reg->wr_bitmap_l] & CTRL_PORT_MASK;2078 if (card->mp_wr_bitmap & CTRL_PORT_MASK)2079 adapter->cmd_sent = false;2080 }2081 2082 mwifiex_dbg(adapter, INTR, "info: cmd_sent=%d data_sent=%d\n",2083 adapter->cmd_sent, adapter->data_sent);2084 if (sdio_ireg & UP_LD_HOST_INT_STATUS) {2085 bitmap = (u32) card->mp_regs[reg->rd_bitmap_l];2086 bitmap |= ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8;2087 if (card->supports_sdio_new_mode) {2088 bitmap |=2089 ((u32) card->mp_regs[reg->rd_bitmap_1l]) << 16;2090 bitmap |=2091 ((u32) card->mp_regs[reg->rd_bitmap_1u]) << 24;2092 }2093 card->mp_rd_bitmap = bitmap;2094 mwifiex_dbg(adapter, INTR,2095 "int: UPLD: rd_bitmap=0x%x\n",2096 card->mp_rd_bitmap);2097 2098 while (true) {2099 ret = mwifiex_get_rd_port(adapter, &port);2100 if (ret) {2101 mwifiex_dbg(adapter, INFO,2102 "info: no more rd_port available\n");2103 break;2104 }2105 len_reg_l = reg->rd_len_p0_l + (port << 1);2106 len_reg_u = reg->rd_len_p0_u + (port << 1);2107 rx_len = ((u16) card->mp_regs[len_reg_u]) << 8;2108 rx_len |= (u16) card->mp_regs[len_reg_l];2109 mwifiex_dbg(adapter, INFO,2110 "info: RX: port=%d rx_len=%u\n",2111 port, rx_len);2112 rx_blocks =2113 (rx_len + MWIFIEX_SDIO_BLOCK_SIZE -2114 1) / MWIFIEX_SDIO_BLOCK_SIZE;2115 if (rx_len <= adapter->intf_hdr_len ||2116 (card->mpa_rx.enabled &&2117 ((rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >2118 card->mpa_rx.buf_size))) {2119 mwifiex_dbg(adapter, ERROR,2120 "invalid rx_len=%d\n",2121 rx_len);2122 return -1;2123 }2124 2125 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);2126 mwifiex_dbg(adapter, INFO, "info: rx_len = %d\n",2127 rx_len);2128 2129 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, rx_len,2130 port)) {2131 mwifiex_dbg(adapter, ERROR,2132 "card_to_host_mpa failed: int status=%#x\n",2133 sdio_ireg);2134 goto term_cmd;2135 }2136 }2137 }2138 2139 return 0;2140 2141term_cmd:2142 /* terminate cmd */2143 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))2144 mwifiex_dbg(adapter, ERROR, "read CFG reg failed\n");2145 else2146 mwifiex_dbg(adapter, INFO,2147 "info: CFG reg val = %d\n", cr);2148 2149 if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04)))2150 mwifiex_dbg(adapter, ERROR,2151 "write CFG reg failed\n");2152 else2153 mwifiex_dbg(adapter, INFO, "info: write success\n");2154 2155 if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr))2156 mwifiex_dbg(adapter, ERROR,2157 "read CFG reg failed\n");2158 else2159 mwifiex_dbg(adapter, INFO,2160 "info: CFG reg val =%x\n", cr);2161 2162 return -1;2163}2164 2165/*2166 * This function aggregates transmission buffers in driver and downloads2167 * the aggregated packet to card.2168 *2169 * The individual packets are aggregated by copying into an aggregation2170 * buffer and then downloaded to the card. Previous unsent packets in the2171 * aggregation buffer are pre-copied first before new packets are added.2172 * Aggregation is done till there is space left in the aggregation buffer,2173 * or till new packets are available.2174 *2175 * The function will only download the packet to the card when aggregation2176 * stops, otherwise it will just aggregate the packet in aggregation buffer2177 * and return.2178 */2179static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,2180 u8 *payload, u32 pkt_len, u32 port,2181 u32 next_pkt_len)2182{2183 struct sdio_mmc_card *card = adapter->card;2184 int ret = 0;2185 s32 f_send_aggr_buf = 0;2186 s32 f_send_cur_buf = 0;2187 s32 f_precopy_cur_buf = 0;2188 s32 f_postcopy_cur_buf = 0;2189 u32 mport;2190 int index;2191 2192 if (!card->mpa_tx.enabled ||2193 (card->has_control_mask && (port == CTRL_PORT)) ||2194 (card->supports_sdio_new_mode && (port == CMD_PORT_SLCT))) {2195 mwifiex_dbg(adapter, WARN,2196 "info: %s: tx aggregation disabled\n",2197 __func__);2198 2199 f_send_cur_buf = 1;2200 goto tx_curr_single;2201 }2202 2203 if (next_pkt_len) {2204 /* More pkt in TX queue */2205 mwifiex_dbg(adapter, INFO,2206 "info: %s: more packets in queue.\n",2207 __func__);2208 2209 if (MP_TX_AGGR_IN_PROGRESS(card)) {2210 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {2211 f_precopy_cur_buf = 1;2212 2213 if (!(card->mp_wr_bitmap &2214 (1 << card->curr_wr_port)) ||2215 !MP_TX_AGGR_BUF_HAS_ROOM(2216 card, pkt_len + next_pkt_len))2217 f_send_aggr_buf = 1;2218 } else {2219 /* No room in Aggr buf, send it */2220 f_send_aggr_buf = 1;2221 2222 if (!(card->mp_wr_bitmap &2223 (1 << card->curr_wr_port)))2224 f_send_cur_buf = 1;2225 else2226 f_postcopy_cur_buf = 1;2227 }2228 } else {2229 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len) &&2230 (card->mp_wr_bitmap & (1 << card->curr_wr_port)))2231 f_precopy_cur_buf = 1;2232 else2233 f_send_cur_buf = 1;2234 }2235 } else {2236 /* Last pkt in TX queue */2237 mwifiex_dbg(adapter, INFO,2238 "info: %s: Last packet in Tx Queue.\n",2239 __func__);2240 2241 if (MP_TX_AGGR_IN_PROGRESS(card)) {2242 /* some packs in Aggr buf already */2243 f_send_aggr_buf = 1;2244 2245 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len))2246 f_precopy_cur_buf = 1;2247 else2248 /* No room in Aggr buf, send it */2249 f_send_cur_buf = 1;2250 } else {2251 f_send_cur_buf = 1;2252 }2253 }2254 2255 if (f_precopy_cur_buf) {2256 mwifiex_dbg(adapter, DATA,2257 "data: %s: precopy current buffer\n",2258 __func__);2259 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);2260 2261 if (MP_TX_AGGR_PKT_LIMIT_REACHED(card) ||2262 mp_tx_aggr_port_limit_reached(card))2263 /* No more pkts allowed in Aggr buf, send it */2264 f_send_aggr_buf = 1;2265 }2266 2267 if (f_send_aggr_buf) {2268 mwifiex_dbg(adapter, DATA,2269 "data: %s: send aggr buffer: %d %d\n",2270 __func__, card->mpa_tx.start_port,2271 card->mpa_tx.ports);2272 if (card->supports_sdio_new_mode) {2273 u32 port_count;2274 int i;2275 2276 for (i = 0, port_count = 0; i < card->max_ports; i++)2277 if (card->mpa_tx.ports & BIT(i))2278 port_count++;2279 2280 /* Writing data from "start_port + 0" to "start_port +2281 * port_count -1", so decrease the count by 12282 */2283 port_count--;2284 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |2285 (port_count << 8)) + card->mpa_tx.start_port;2286 } else {2287 mport = (adapter->ioport | SDIO_MPA_ADDR_BASE |2288 (card->mpa_tx.ports << 4)) +2289 card->mpa_tx.start_port;2290 }2291 2292 if (card->mpa_tx.pkt_cnt == 1)2293 mport = adapter->ioport + card->mpa_tx.start_port;2294 2295 ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf,2296 card->mpa_tx.buf_len, mport);2297 2298 /* Save the last multi port tx aggregation info to debug log. */2299 index = adapter->dbg.last_sdio_mp_index;2300 index = (index + 1) % MWIFIEX_DBG_SDIO_MP_NUM;2301 adapter->dbg.last_sdio_mp_index = index;2302 adapter->dbg.last_mp_wr_ports[index] = mport;2303 adapter->dbg.last_mp_wr_bitmap[index] = card->mp_wr_bitmap;2304 adapter->dbg.last_mp_wr_len[index] = card->mpa_tx.buf_len;2305 adapter->dbg.last_mp_curr_wr_port[index] = card->curr_wr_port;2306 2307 MP_TX_AGGR_BUF_RESET(card);2308 }2309 2310tx_curr_single:2311 if (f_send_cur_buf) {2312 mwifiex_dbg(adapter, DATA,2313 "data: %s: send current buffer %d\n",2314 __func__, port);2315 ret = mwifiex_write_data_to_card(adapter, payload, pkt_len,2316 adapter->ioport + port);2317 }2318 2319 if (f_postcopy_cur_buf) {2320 mwifiex_dbg(adapter, DATA,2321 "data: %s: postcopy current buffer\n",2322 __func__);2323 MP_TX_AGGR_BUF_PUT(card, payload, pkt_len, port);2324 }2325 2326 return ret;2327}2328 2329/*2330 * This function downloads data from driver to card.2331 *2332 * Both commands and data packets are transferred to the card by this2333 * function.2334 *2335 * This function adds the SDIO specific header to the front of the buffer2336 * before transferring. The header contains the length of the packet and2337 * the type. The firmware handles the packets based upon this set type.2338 */2339static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter,2340 u8 type, struct sk_buff *skb,2341 struct mwifiex_tx_param *tx_param)2342{2343 struct sdio_mmc_card *card = adapter->card;2344 int ret;2345 u32 buf_block_len;2346 u32 blk_size;2347 u32 port = CTRL_PORT;2348 u8 *payload = (u8 *)skb->data;2349 u32 pkt_len = skb->len;2350 2351 /* Allocate buffer and copy payload */2352 blk_size = MWIFIEX_SDIO_BLOCK_SIZE;2353 buf_block_len = (pkt_len + blk_size - 1) / blk_size;2354 put_unaligned_le16((u16)pkt_len, payload + 0);2355 put_unaligned_le16((u32)type, payload + 2);2356 2357 2358 /*2359 * This is SDIO specific header2360 * u16 length,2361 * u16 type (MWIFIEX_TYPE_DATA = 0, MWIFIEX_TYPE_CMD = 1,2362 * MWIFIEX_TYPE_EVENT = 3)2363 */2364 if (type == MWIFIEX_TYPE_DATA) {2365 ret = mwifiex_get_wr_port_data(adapter, &port);2366 if (ret) {2367 mwifiex_dbg(adapter, ERROR,2368 "%s: no wr_port available\n",2369 __func__);2370 return ret;2371 }2372 } else {2373 adapter->cmd_sent = true;2374 /* Type must be MWIFIEX_TYPE_CMD */2375 2376 if (pkt_len <= adapter->intf_hdr_len ||2377 pkt_len > MWIFIEX_UPLD_SIZE)2378 mwifiex_dbg(adapter, ERROR,2379 "%s: payload=%p, nb=%d\n",2380 __func__, payload, pkt_len);2381 2382 if (card->supports_sdio_new_mode)2383 port = CMD_PORT_SLCT;2384 }2385 2386 /* Transfer data to card */2387 pkt_len = buf_block_len * blk_size;2388 2389 if (tx_param)2390 ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,2391 port, tx_param->next_pkt_len2392 );2393 else2394 ret = mwifiex_host_to_card_mp_aggr(adapter, payload, pkt_len,2395 port, 0);2396 2397 if (ret) {2398 if (type == MWIFIEX_TYPE_CMD)2399 adapter->cmd_sent = false;2400 if (type == MWIFIEX_TYPE_DATA) {2401 adapter->data_sent = false;2402 /* restore curr_wr_port in error cases */2403 card->curr_wr_port = port;2404 card->mp_wr_bitmap |= (u32)(1 << card->curr_wr_port);2405 }2406 } else {2407 if (type == MWIFIEX_TYPE_DATA) {2408 if (!(card->mp_wr_bitmap & (1 << card->curr_wr_port)))2409 adapter->data_sent = true;2410 else2411 adapter->data_sent = false;2412 }2413 }2414 2415 return ret;2416}2417 2418/*2419 * This function allocates the MPA Tx and Rx buffers.2420 */2421static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,2422 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)2423{2424 struct sdio_mmc_card *card = adapter->card;2425 u32 rx_buf_size;2426 int ret = 0;2427 2428 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);2429 if (!card->mpa_tx.buf) {2430 ret = -1;2431 goto error;2432 }2433 2434 card->mpa_tx.buf_size = mpa_tx_buf_size;2435 2436 rx_buf_size = max_t(u32, mpa_rx_buf_size,2437 (u32)SDIO_MAX_AGGR_BUF_SIZE);2438 card->mpa_rx.buf = kzalloc(rx_buf_size, GFP_KERNEL);2439 if (!card->mpa_rx.buf) {2440 ret = -1;2441 goto error;2442 }2443 2444 card->mpa_rx.buf_size = rx_buf_size;2445 2446error:2447 if (ret) {2448 kfree(card->mpa_tx.buf);2449 kfree(card->mpa_rx.buf);2450 card->mpa_tx.buf_size = 0;2451 card->mpa_rx.buf_size = 0;2452 card->mpa_tx.buf = NULL;2453 card->mpa_rx.buf = NULL;2454 }2455 2456 return ret;2457}2458 2459/*2460 * This function unregisters the SDIO device.2461 *2462 * The SDIO IRQ is released, the function is disabled and driver2463 * data is set to null.2464 */2465static void2466mwifiex_unregister_dev(struct mwifiex_adapter *adapter)2467{2468 struct sdio_mmc_card *card = adapter->card;2469 2470 if (adapter->card) {2471 card->adapter = NULL;2472 sdio_claim_host(card->func);2473 sdio_disable_func(card->func);2474 sdio_release_host(card->func);2475 }2476}2477 2478/*2479 * This function registers the SDIO device.2480 *2481 * SDIO IRQ is claimed, block size is set and driver data is initialized.2482 */2483static int mwifiex_register_dev(struct mwifiex_adapter *adapter)2484{2485 int ret;2486 struct sdio_mmc_card *card = adapter->card;2487 struct sdio_func *func = card->func;2488 const char *firmware = card->firmware;2489 2490 /* save adapter pointer in card */2491 card->adapter = adapter;2492 adapter->tx_buf_size = card->tx_buf_size;2493 2494 sdio_claim_host(func);2495 2496 /* Set block size */2497 ret = sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);2498 sdio_release_host(func);2499 if (ret) {2500 mwifiex_dbg(adapter, ERROR,2501 "cannot set SDIO block size\n");2502 return ret;2503 }2504 2505 /* Select correct firmware (sdsd or sdiouart) firmware based on the strapping2506 * option2507 */2508 if (card->firmware_sdiouart) {2509 u8 val;2510 2511 mwifiex_read_reg(adapter, card->reg->host_strap_reg, &val);2512 if ((val & card->reg->host_strap_mask) == card->reg->host_strap_value)2513 firmware = card->firmware_sdiouart;2514 }2515 strcpy(adapter->fw_name, firmware);2516 2517 if (card->fw_dump_enh) {2518 adapter->mem_type_mapping_tbl = generic_mem_type_map;2519 adapter->num_mem_types = 1;2520 } else {2521 adapter->mem_type_mapping_tbl = mem_type_mapping_tbl;2522 adapter->num_mem_types = ARRAY_SIZE(mem_type_mapping_tbl);2523 }2524 2525 adapter->host_mlme_enabled = card->host_mlme;2526 2527 return 0;2528}2529 2530/*2531 * This function initializes the SDIO driver.2532 *2533 * The following initializations steps are followed -2534 * - Read the Host interrupt status register to acknowledge2535 * the first interrupt got from bootloader2536 * - Disable host interrupt mask register2537 * - Get SDIO port2538 * - Initialize SDIO variables in card2539 * - Allocate MP registers2540 * - Allocate MPA Tx and Rx buffers2541 */2542static int mwifiex_init_sdio(struct mwifiex_adapter *adapter)2543{2544 struct sdio_mmc_card *card = adapter->card;2545 const struct mwifiex_sdio_card_reg *reg = card->reg;2546 int ret;2547 u8 sdio_ireg;2548 2549 sdio_set_drvdata(card->func, card);2550 2551 /*2552 * Read the host_int_status_reg for ACK the first interrupt got2553 * from the bootloader. If we don't do this we get a interrupt2554 * as soon as we register the irq.2555 */2556 mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);2557 2558 /* Get SDIO ioport */2559 if (mwifiex_init_sdio_ioport(adapter))2560 return -EIO;2561 2562 /* Initialize SDIO variables in card */2563 card->mp_rd_bitmap = 0;2564 card->mp_wr_bitmap = 0;2565 card->curr_rd_port = reg->start_rd_port;2566 card->curr_wr_port = reg->start_wr_port;2567 2568 card->mp_data_port_mask = reg->data_port_mask;2569 2570 card->mpa_tx.buf_len = 0;2571 card->mpa_tx.pkt_cnt = 0;2572 card->mpa_tx.start_port = 0;2573 2574 card->mpa_tx.enabled = 1;2575 card->mpa_tx.pkt_aggr_limit = card->mp_agg_pkt_limit;2576 2577 card->mpa_rx.buf_len = 0;2578 card->mpa_rx.pkt_cnt = 0;2579 card->mpa_rx.start_port = 0;2580 2581 card->mpa_rx.enabled = 1;2582 card->mpa_rx.pkt_aggr_limit = card->mp_agg_pkt_limit;2583 2584 /* Allocate buffers for SDIO MP-A */2585 card->mp_regs = kzalloc(reg->max_mp_regs, GFP_KERNEL);2586 if (!card->mp_regs)2587 return -ENOMEM;2588 2589 card->mpa_rx.len_arr = kcalloc(card->mp_agg_pkt_limit,2590 sizeof(*card->mpa_rx.len_arr),2591 GFP_KERNEL);2592 if (!card->mpa_rx.len_arr) {2593 kfree(card->mp_regs);2594 return -ENOMEM;2595 }2596 2597 ret = mwifiex_alloc_sdio_mpa_buffers(adapter,2598 card->mp_tx_agg_buf_size,2599 card->mp_rx_agg_buf_size);2600 2601 /* Allocate 32k MPA Tx/Rx buffers if 64k memory allocation fails */2602 if (ret && (card->mp_tx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX ||2603 card->mp_rx_agg_buf_size == MWIFIEX_MP_AGGR_BUF_SIZE_MAX)) {2604 /* Disable rx single port aggregation */2605 adapter->host_disable_sdio_rx_aggr = true;2606 2607 ret = mwifiex_alloc_sdio_mpa_buffers2608 (adapter, MWIFIEX_MP_AGGR_BUF_SIZE_32K,2609 MWIFIEX_MP_AGGR_BUF_SIZE_32K);2610 if (ret) {2611 /* Disable multi port aggregation */2612 card->mpa_tx.enabled = 0;2613 card->mpa_rx.enabled = 0;2614 }2615 }2616 2617 adapter->auto_tdls = card->can_auto_tdls;2618 adapter->ext_scan = card->can_ext_scan;2619 return 0;2620}2621 2622/*2623 * This function resets the MPA Tx and Rx buffers.2624 */2625static void mwifiex_cleanup_mpa_buf(struct mwifiex_adapter *adapter)2626{2627 struct sdio_mmc_card *card = adapter->card;2628 2629 MP_TX_AGGR_BUF_RESET(card);2630 MP_RX_AGGR_BUF_RESET(card);2631}2632 2633/*2634 * This function cleans up the allocated card buffers.2635 *2636 * The following are freed by this function -2637 * - MP registers2638 * - MPA Tx buffer2639 * - MPA Rx buffer2640 */2641static void mwifiex_cleanup_sdio(struct mwifiex_adapter *adapter)2642{2643 struct sdio_mmc_card *card = adapter->card;2644 2645 cancel_work_sync(&card->work);2646 2647 kfree(card->mp_regs);2648 kfree(card->mpa_rx.len_arr);2649 kfree(card->mpa_tx.buf);2650 kfree(card->mpa_rx.buf);2651}2652 2653/*2654 * This function updates the MP end port in card.2655 */2656static void2657mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)2658{2659 struct sdio_mmc_card *card = adapter->card;2660 const struct mwifiex_sdio_card_reg *reg = card->reg;2661 int i;2662 2663 card->mp_end_port = port;2664 2665 card->mp_data_port_mask = reg->data_port_mask;2666 2667 if (reg->start_wr_port) {2668 for (i = 1; i <= card->max_ports - card->mp_end_port; i++)2669 card->mp_data_port_mask &=2670 ~(1 << (card->max_ports - i));2671 }2672 2673 card->curr_wr_port = reg->start_wr_port;2674 2675 mwifiex_dbg(adapter, CMD,2676 "cmd: mp_end_port %d, data port mask 0x%x\n",2677 port, card->mp_data_port_mask);2678}2679 2680static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)2681{2682 struct sdio_mmc_card *card = adapter->card;2683 struct sdio_func *func = card->func;2684 int ret;2685 2686 /* Prepare the adapter for the reset. */2687 mwifiex_shutdown_sw(adapter);2688 clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP, &card->work_flags);2689 clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags);2690 2691 /* Run a HW reset of the SDIO interface. */2692 sdio_claim_host(func);2693 ret = mmc_hw_reset(func->card);2694 sdio_release_host(func);2695 2696 switch (ret) {2697 case 1:2698 dev_dbg(&func->dev, "SDIO HW reset asynchronous\n");2699 complete_all(adapter->fw_done);2700 break;2701 case 0:2702 ret = mwifiex_reinit_sw(adapter);2703 if (ret)2704 dev_err(&func->dev, "reinit failed: %d\n", ret);2705 break;2706 default:2707 dev_err(&func->dev, "SDIO HW reset failed: %d\n", ret);2708 break;2709 }2710}2711 2712/* This function read/write firmware */2713static enum2714rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,2715 u8 doneflag)2716{2717 struct sdio_mmc_card *card = adapter->card;2718 int ret, tries;2719 u8 ctrl_data = 0;2720 2721 sdio_writeb(card->func, card->reg->fw_dump_host_ready,2722 card->reg->fw_dump_ctrl, &ret);2723 if (ret) {2724 mwifiex_dbg(adapter, ERROR, "SDIO Write ERR\n");2725 return RDWR_STATUS_FAILURE;2726 }2727 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {2728 ctrl_data = sdio_readb(card->func, card->reg->fw_dump_ctrl,2729 &ret);2730 if (ret) {2731 mwifiex_dbg(adapter, ERROR, "SDIO read err\n");2732 return RDWR_STATUS_FAILURE;2733 }2734 if (ctrl_data == FW_DUMP_DONE)2735 break;2736 if (doneflag && ctrl_data == doneflag)2737 return RDWR_STATUS_DONE;2738 if (ctrl_data != card->reg->fw_dump_host_ready) {2739 mwifiex_dbg(adapter, WARN,2740 "The ctrl reg was changed, re-try again\n");2741 sdio_writeb(card->func, card->reg->fw_dump_host_ready,2742 card->reg->fw_dump_ctrl, &ret);2743 if (ret) {2744 mwifiex_dbg(adapter, ERROR, "SDIO write err\n");2745 return RDWR_STATUS_FAILURE;2746 }2747 }2748 usleep_range(100, 200);2749 }2750 if (ctrl_data == card->reg->fw_dump_host_ready) {2751 mwifiex_dbg(adapter, ERROR,2752 "Fail to pull ctrl_data\n");2753 return RDWR_STATUS_FAILURE;2754 }2755 2756 return RDWR_STATUS_SUCCESS;2757}2758 2759/* This function dump firmware memory to file */2760static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)2761{2762 struct sdio_mmc_card *card = adapter->card;2763 int ret = 0;2764 unsigned int reg, reg_start, reg_end;2765 u8 *dbg_ptr, *end_ptr, dump_num, idx, i, read_reg, doneflag = 0;2766 enum rdwr_status stat;2767 u32 memory_size;2768 2769 if (!card->can_dump_fw)2770 return;2771 2772 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {2773 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];2774 2775 if (entry->mem_ptr) {2776 vfree(entry->mem_ptr);2777 entry->mem_ptr = NULL;2778 }2779 entry->mem_size = 0;2780 }2781 2782 mwifiex_pm_wakeup_card(adapter);2783 sdio_claim_host(card->func);2784 2785 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");2786 2787 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);2788 if (stat == RDWR_STATUS_FAILURE)2789 goto done;2790 2791 reg = card->reg->fw_dump_start;2792 /* Read the number of the memories which will dump */2793 dump_num = sdio_readb(card->func, reg, &ret);2794 if (ret) {2795 mwifiex_dbg(adapter, ERROR, "SDIO read memory length err\n");2796 goto done;2797 }2798 2799 /* Read the length of every memory which will dump */2800 for (idx = 0; idx < dump_num; idx++) {2801 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];2802 2803 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);2804 if (stat == RDWR_STATUS_FAILURE)2805 goto done;2806 2807 memory_size = 0;2808 reg = card->reg->fw_dump_start;2809 for (i = 0; i < 4; i++) {2810 read_reg = sdio_readb(card->func, reg, &ret);2811 if (ret) {2812 mwifiex_dbg(adapter, ERROR, "SDIO read err\n");2813 goto done;2814 }2815 memory_size |= (read_reg << i*8);2816 reg++;2817 }2818 2819 if (memory_size == 0) {2820 mwifiex_dbg(adapter, DUMP, "Firmware dump Finished!\n");2821 ret = mwifiex_write_reg(adapter,2822 card->reg->fw_dump_ctrl,2823 FW_DUMP_READ_DONE);2824 if (ret) {2825 mwifiex_dbg(adapter, ERROR, "SDIO write err\n");2826 return;2827 }2828 break;2829 }2830 2831 mwifiex_dbg(adapter, DUMP,2832 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);2833 entry->mem_ptr = vmalloc(memory_size + 1);2834 entry->mem_size = memory_size;2835 if (!entry->mem_ptr) {2836 mwifiex_dbg(adapter, ERROR, "Vmalloc %s failed\n",2837 entry->mem_name);2838 goto done;2839 }2840 dbg_ptr = entry->mem_ptr;2841 end_ptr = dbg_ptr + memory_size;2842 2843 doneflag = entry->done_flag;2844 mwifiex_dbg(adapter, DUMP,2845 "Start %s output, please wait...\n",2846 entry->mem_name);2847 2848 do {2849 stat = mwifiex_sdio_rdwr_firmware(adapter, doneflag);2850 if (stat == RDWR_STATUS_FAILURE)2851 goto done;2852 2853 reg_start = card->reg->fw_dump_start;2854 reg_end = card->reg->fw_dump_end;2855 for (reg = reg_start; reg <= reg_end; reg++) {2856 *dbg_ptr = sdio_readb(card->func, reg, &ret);2857 if (ret) {2858 mwifiex_dbg(adapter, ERROR,2859 "SDIO read err\n");2860 goto done;2861 }2862 if (dbg_ptr < end_ptr)2863 dbg_ptr++;2864 else2865 mwifiex_dbg(adapter, ERROR,2866 "Allocated buf not enough\n");2867 }2868 2869 if (stat != RDWR_STATUS_DONE)2870 continue;2871 2872 mwifiex_dbg(adapter, DUMP, "%s done: size=0x%tx\n",2873 entry->mem_name, dbg_ptr - entry->mem_ptr);2874 break;2875 } while (1);2876 }2877 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");2878 2879done:2880 sdio_release_host(card->func);2881}2882 2883static void mwifiex_sdio_generic_fw_dump(struct mwifiex_adapter *adapter)2884{2885 struct sdio_mmc_card *card = adapter->card;2886 struct memory_type_mapping *entry = &generic_mem_type_map[0];2887 unsigned int reg, reg_start, reg_end;2888 u8 start_flag = 0, done_flag = 0;2889 u8 *dbg_ptr, *end_ptr;2890 enum rdwr_status stat;2891 int ret = -1, tries;2892 2893 if (!card->fw_dump_enh)2894 return;2895 2896 if (entry->mem_ptr) {2897 vfree(entry->mem_ptr);2898 entry->mem_ptr = NULL;2899 }2900 entry->mem_size = 0;2901 2902 mwifiex_pm_wakeup_card(adapter);2903 sdio_claim_host(card->func);2904 2905 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump start ==\n");2906 2907 stat = mwifiex_sdio_rdwr_firmware(adapter, done_flag);2908 if (stat == RDWR_STATUS_FAILURE)2909 goto done;2910 2911 reg_start = card->reg->fw_dump_start;2912 reg_end = card->reg->fw_dump_end;2913 for (reg = reg_start; reg <= reg_end; reg++) {2914 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {2915 start_flag = sdio_readb(card->func, reg, &ret);2916 if (ret) {2917 mwifiex_dbg(adapter, ERROR,2918 "SDIO read err\n");2919 goto done;2920 }2921 if (start_flag == 0)2922 break;2923 if (tries == MAX_POLL_TRIES) {2924 mwifiex_dbg(adapter, ERROR,2925 "FW not ready to dump\n");2926 ret = -1;2927 goto done;2928 }2929 }2930 usleep_range(100, 200);2931 }2932 2933 entry->mem_ptr = vmalloc(0xf0000 + 1);2934 if (!entry->mem_ptr) {2935 ret = -1;2936 goto done;2937 }2938 dbg_ptr = entry->mem_ptr;2939 entry->mem_size = 0xf0000;2940 end_ptr = dbg_ptr + entry->mem_size;2941 2942 done_flag = entry->done_flag;2943 mwifiex_dbg(adapter, DUMP,2944 "Start %s output, please wait...\n", entry->mem_name);2945 2946 while (true) {2947 stat = mwifiex_sdio_rdwr_firmware(adapter, done_flag);2948 if (stat == RDWR_STATUS_FAILURE)2949 goto done;2950 for (reg = reg_start; reg <= reg_end; reg++) {2951 *dbg_ptr = sdio_readb(card->func, reg, &ret);2952 if (ret) {2953 mwifiex_dbg(adapter, ERROR,2954 "SDIO read err\n");2955 goto done;2956 }2957 dbg_ptr++;2958 if (dbg_ptr >= end_ptr) {2959 u8 *tmp_ptr;2960 2961 tmp_ptr = vmalloc(entry->mem_size + 0x4000 + 1);2962 if (!tmp_ptr)2963 goto done;2964 2965 memcpy(tmp_ptr, entry->mem_ptr,2966 entry->mem_size);2967 vfree(entry->mem_ptr);2968 entry->mem_ptr = tmp_ptr;2969 tmp_ptr = NULL;2970 dbg_ptr = entry->mem_ptr + entry->mem_size;2971 entry->mem_size += 0x4000;2972 end_ptr = entry->mem_ptr + entry->mem_size;2973 }2974 }2975 if (stat == RDWR_STATUS_DONE) {2976 entry->mem_size = dbg_ptr - entry->mem_ptr;2977 mwifiex_dbg(adapter, DUMP, "dump %s done size=0x%x\n",2978 entry->mem_name, entry->mem_size);2979 ret = 0;2980 break;2981 }2982 }2983 mwifiex_dbg(adapter, MSG, "== mwifiex firmware dump end ==\n");2984 2985done:2986 if (ret) {2987 mwifiex_dbg(adapter, ERROR, "firmware dump failed\n");2988 if (entry->mem_ptr) {2989 vfree(entry->mem_ptr);2990 entry->mem_ptr = NULL;2991 }2992 entry->mem_size = 0;2993 }2994 sdio_release_host(card->func);2995}2996 2997static void mwifiex_sdio_device_dump_work(struct mwifiex_adapter *adapter)2998{2999 struct sdio_mmc_card *card = adapter->card;3000 3001 adapter->devdump_data = vzalloc(MWIFIEX_FW_DUMP_SIZE);3002 if (!adapter->devdump_data) {3003 mwifiex_dbg(adapter, ERROR,3004 "vzalloc devdump data failure!\n");3005 return;3006 }3007 3008 mwifiex_drv_info_dump(adapter);3009 if (card->fw_dump_enh)3010 mwifiex_sdio_generic_fw_dump(adapter);3011 else3012 mwifiex_sdio_fw_dump(adapter);3013 mwifiex_prepare_fw_dump_info(adapter);3014 mwifiex_upload_device_dump(adapter);3015}3016 3017static void mwifiex_sdio_work(struct work_struct *work)3018{3019 struct sdio_mmc_card *card =3020 container_of(work, struct sdio_mmc_card, work);3021 3022 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,3023 &card->work_flags))3024 mwifiex_sdio_device_dump_work(card->adapter);3025 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,3026 &card->work_flags))3027 mwifiex_sdio_card_reset_work(card->adapter);3028}3029 3030/* This function resets the card */3031static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)3032{3033 struct sdio_mmc_card *card = adapter->card;3034 3035 if (!test_and_set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &card->work_flags))3036 schedule_work(&card->work);3037}3038 3039/* This function dumps FW information */3040static void mwifiex_sdio_device_dump(struct mwifiex_adapter *adapter)3041{3042 struct sdio_mmc_card *card = adapter->card;3043 3044 if (!test_and_set_bit(MWIFIEX_IFACE_WORK_DEVICE_DUMP,3045 &card->work_flags))3046 schedule_work(&card->work);3047}3048 3049/* Function to dump SDIO function registers and SDIO scratch registers in case3050 * of FW crash3051 */3052static int3053mwifiex_sdio_reg_dump(struct mwifiex_adapter *adapter, char *drv_buf)3054{3055 char *p = drv_buf;3056 struct sdio_mmc_card *cardp = adapter->card;3057 int ret = 0;3058 u8 count, func, data, index = 0, size = 0;3059 u8 reg, reg_start, reg_end;3060 char buf[256], *ptr;3061 3062 if (!p)3063 return 0;3064 3065 mwifiex_dbg(adapter, MSG, "SDIO register dump start\n");3066 3067 mwifiex_pm_wakeup_card(adapter);3068 3069 sdio_claim_host(cardp->func);3070 3071 for (count = 0; count < 5; count++) {3072 memset(buf, 0, sizeof(buf));3073 ptr = buf;3074 3075 switch (count) {3076 case 0:3077 /* Read the registers of SDIO function0 */3078 func = count;3079 reg_start = 0;3080 reg_end = 9;3081 break;3082 case 1:3083 /* Read the registers of SDIO function1 */3084 func = count;3085 reg_start = cardp->reg->func1_dump_reg_start;3086 reg_end = cardp->reg->func1_dump_reg_end;3087 break;3088 case 2:3089 index = 0;3090 func = 1;3091 reg_start = cardp->reg->func1_spec_reg_table[index++];3092 size = cardp->reg->func1_spec_reg_num;3093 reg_end = cardp->reg->func1_spec_reg_table[size-1];3094 break;3095 default:3096 /* Read the scratch registers of SDIO function1 */3097 if (count == 4)3098 mdelay(100);3099 func = 1;3100 reg_start = cardp->reg->func1_scratch_reg;3101 reg_end = reg_start + MWIFIEX_SDIO_SCRATCH_SIZE;3102 }3103 3104 if (count != 2)3105 ptr += sprintf(ptr, "SDIO Func%d (%#x-%#x): ",3106 func, reg_start, reg_end);3107 else3108 ptr += sprintf(ptr, "SDIO Func%d: ", func);3109 3110 for (reg = reg_start; reg <= reg_end;) {3111 if (func == 0)3112 data = sdio_f0_readb(cardp->func, reg, &ret);3113 else3114 data = sdio_readb(cardp->func, reg, &ret);3115 3116 if (count == 2)3117 ptr += sprintf(ptr, "(%#x) ", reg);3118 if (!ret) {3119 ptr += sprintf(ptr, "%02x ", data);3120 } else {3121 ptr += sprintf(ptr, "ERR");3122 break;3123 }3124 3125 if (count == 2 && reg < reg_end)3126 reg = cardp->reg->func1_spec_reg_table[index++];3127 else3128 reg++;3129 }3130 3131 mwifiex_dbg(adapter, MSG, "%s\n", buf);3132 p += sprintf(p, "%s\n", buf);3133 }3134 3135 sdio_release_host(cardp->func);3136 3137 mwifiex_dbg(adapter, MSG, "SDIO register dump end\n");3138 3139 return p - drv_buf;3140}3141 3142/* sdio device/function initialization, code is extracted3143 * from init_if handler and register_dev handler.3144 */3145static void mwifiex_sdio_up_dev(struct mwifiex_adapter *adapter)3146{3147 struct sdio_mmc_card *card = adapter->card;3148 u8 sdio_ireg;3149 3150 sdio_claim_host(card->func);3151 sdio_enable_func(card->func);3152 sdio_set_block_size(card->func, MWIFIEX_SDIO_BLOCK_SIZE);3153 sdio_release_host(card->func);3154 3155 /* tx_buf_size might be changed to 3584 by firmware during3156 * data transfer, we will reset to default size.3157 */3158 adapter->tx_buf_size = card->tx_buf_size;3159 3160 /* Read the host_int_status_reg for ACK the first interrupt got3161 * from the bootloader. If we don't do this we get a interrupt3162 * as soon as we register the irq.3163 */3164 mwifiex_read_reg(adapter, card->reg->host_int_status_reg, &sdio_ireg);3165 3166 if (mwifiex_init_sdio_ioport(adapter))3167 dev_err(&card->func->dev, "error enabling SDIO port\n");3168}3169 3170static struct mwifiex_if_ops sdio_ops = {3171 .init_if = mwifiex_init_sdio,3172 .cleanup_if = mwifiex_cleanup_sdio,3173 .check_fw_status = mwifiex_check_fw_status,3174 .check_winner_status = mwifiex_check_winner_status,3175 .prog_fw = mwifiex_prog_fw_w_helper,3176 .register_dev = mwifiex_register_dev,3177 .unregister_dev = mwifiex_unregister_dev,3178 .enable_int = mwifiex_sdio_enable_host_int,3179 .disable_int = mwifiex_sdio_disable_host_int,3180 .process_int_status = mwifiex_process_int_status,3181 .host_to_card = mwifiex_sdio_host_to_card,3182 .wakeup = mwifiex_pm_wakeup_card,3183 .wakeup_complete = mwifiex_pm_wakeup_card_complete,3184 3185 /* SDIO specific */3186 .update_mp_end_port = mwifiex_update_mp_end_port,3187 .cleanup_mpa_buf = mwifiex_cleanup_mpa_buf,3188 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,3189 .event_complete = mwifiex_sdio_event_complete,3190 .dnld_fw = mwifiex_sdio_dnld_fw,3191 .card_reset = mwifiex_sdio_card_reset,3192 .reg_dump = mwifiex_sdio_reg_dump,3193 .device_dump = mwifiex_sdio_device_dump,3194 .deaggr_pkt = mwifiex_deaggr_sdio_pkt,3195 .up_dev = mwifiex_sdio_up_dev,3196};3197 3198module_sdio_driver(mwifiex_sdio);3199 3200MODULE_AUTHOR("Marvell International Ltd.");3201MODULE_DESCRIPTION("Marvell WiFi-Ex SDIO Driver version " SDIO_VERSION);3202MODULE_VERSION(SDIO_VERSION);3203MODULE_LICENSE("GPL v2");3204MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME);3205MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME);3206MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME);3207MODULE_FIRMWARE(SD8801_DEFAULT_FW_NAME);3208MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME);3209MODULE_FIRMWARE(SD8887_DEFAULT_FW_NAME);3210MODULE_FIRMWARE(SD8977_DEFAULT_FW_NAME);3211MODULE_FIRMWARE(SD8978_SDIOUART_FW_NAME);3212MODULE_FIRMWARE(SD8987_DEFAULT_FW_NAME);3213MODULE_FIRMWARE(SD8997_DEFAULT_FW_NAME);3214MODULE_FIRMWARE(SD8997_SDIOUART_FW_NAME);3215