diff options
author | Yogesh Ashok Powar <yogeshp@marvell.com> | 2013-05-17 20:54:58 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-05-22 15:09:14 -0400 |
commit | b60186f824330cd85859f5944b9559b0f7df0b4f (patch) | |
tree | 34401cc99e50a9a2e75078ee3cc6b23cd028a046 /drivers/net/wireless/mwifiex/sdio.c | |
parent | c23b7c8f719317983c59b01873b51394fde26907 (diff) |
mwifiex: add support for Marvell SD8897 chipset
Some of the key differences between SD8897 and older chipsets
are as follows:
a) sdio mpa_rx and mpa_tx ports have been increased from 16 to 32
b) Same is the case with read/write bitmap that one receives from
mpa_reg read
c) aggregation packet count doubled from 8 to 16
d) Most of key reg addresses are changed
e) There is a separate command or control port
f) Now command rx/tx_done have new interrupts
1. 'supports_sdio_new_mode' flag is added to handle (a) and (b).
2. (c) and (d) are taken care of by filling chip specific
information in global structurei (mwifiex_sdio_sd8897).
3. For older chipsets, port 0 was cmd port and port 1->15 were
data port. Therefore we had CTRL_PORT_MASK to differentiate
port type. Now these changes are under 'has_control_mask' flag.
Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: Nishant Sarmukadam <nishants@marvell.com>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: Frank Huang <frankh@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/sdio.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/sdio.c | 267 |
1 files changed, 215 insertions, 52 deletions
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index 4b196dc97463..5ee5ed02eccd 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c | |||
@@ -84,6 +84,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) | |||
84 | card->reg = data->reg; | 84 | card->reg = data->reg; |
85 | card->max_ports = data->max_ports; | 85 | card->max_ports = data->max_ports; |
86 | card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; | 86 | card->mp_agg_pkt_limit = data->mp_agg_pkt_limit; |
87 | card->supports_sdio_new_mode = data->supports_sdio_new_mode; | ||
88 | card->has_control_mask = data->has_control_mask; | ||
87 | } | 89 | } |
88 | 90 | ||
89 | sdio_claim_host(func); | 91 | sdio_claim_host(func); |
@@ -260,6 +262,8 @@ static int mwifiex_sdio_resume(struct device *dev) | |||
260 | #define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) | 262 | #define SDIO_DEVICE_ID_MARVELL_8787 (0x9119) |
261 | /* Device ID for SD8797 */ | 263 | /* Device ID for SD8797 */ |
262 | #define SDIO_DEVICE_ID_MARVELL_8797 (0x9129) | 264 | #define SDIO_DEVICE_ID_MARVELL_8797 (0x9129) |
265 | /* Device ID for SD8897 */ | ||
266 | #define SDIO_DEVICE_ID_MARVELL_8897 (0x912d) | ||
263 | 267 | ||
264 | /* WLAN IDs */ | 268 | /* WLAN IDs */ |
265 | static const struct sdio_device_id mwifiex_ids[] = { | 269 | static const struct sdio_device_id mwifiex_ids[] = { |
@@ -269,6 +273,8 @@ static const struct sdio_device_id mwifiex_ids[] = { | |||
269 | .driver_data = (unsigned long) &mwifiex_sdio_sd8787}, | 273 | .driver_data = (unsigned long) &mwifiex_sdio_sd8787}, |
270 | {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797), | 274 | {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797), |
271 | .driver_data = (unsigned long) &mwifiex_sdio_sd8797}, | 275 | .driver_data = (unsigned long) &mwifiex_sdio_sd8797}, |
276 | {SDIO_DEVICE(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8897), | ||
277 | .driver_data = (unsigned long) &mwifiex_sdio_sd8897}, | ||
272 | {}, | 278 | {}, |
273 | }; | 279 | }; |
274 | 280 | ||
@@ -412,7 +418,40 @@ static int mwifiex_pm_wakeup_card_complete(struct mwifiex_adapter *adapter) | |||
412 | } | 418 | } |
413 | 419 | ||
414 | /* | 420 | /* |
415 | * This function initializes the IO ports. | 421 | * This function is used to initialize IO ports for the |
422 | * chipsets supporting SDIO new mode eg SD8897. | ||
423 | */ | ||
424 | static int mwifiex_init_sdio_new_mode(struct mwifiex_adapter *adapter) | ||
425 | { | ||
426 | u8 reg; | ||
427 | |||
428 | adapter->ioport = MEM_PORT; | ||
429 | |||
430 | /* enable sdio new mode */ | ||
431 | if (mwifiex_read_reg(adapter, CARD_CONFIG_2_1_REG, ®)) | ||
432 | return -1; | ||
433 | if (mwifiex_write_reg(adapter, CARD_CONFIG_2_1_REG, | ||
434 | reg | CMD53_NEW_MODE)) | ||
435 | return -1; | ||
436 | |||
437 | /* Configure cmd port and enable reading rx length from the register */ | ||
438 | if (mwifiex_read_reg(adapter, CMD_CONFIG_0, ®)) | ||
439 | return -1; | ||
440 | if (mwifiex_write_reg(adapter, CMD_CONFIG_0, reg | CMD_PORT_RD_LEN_EN)) | ||
441 | return -1; | ||
442 | |||
443 | /* Enable Dnld/Upld ready auto reset for cmd port after cmd53 is | ||
444 | * completed | ||
445 | */ | ||
446 | if (mwifiex_read_reg(adapter, CMD_CONFIG_1, ®)) | ||
447 | return -1; | ||
448 | if (mwifiex_write_reg(adapter, CMD_CONFIG_1, reg | CMD_PORT_AUTO_EN)) | ||
449 | return -1; | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | /* This function initializes the IO ports. | ||
416 | * | 455 | * |
417 | * The following operations are performed - | 456 | * The following operations are performed - |
418 | * - Read the IO ports (0, 1 and 2) | 457 | * - Read the IO ports (0, 1 and 2) |
@@ -426,6 +465,12 @@ static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter) | |||
426 | 465 | ||
427 | adapter->ioport = 0; | 466 | adapter->ioport = 0; |
428 | 467 | ||
468 | if (card->supports_sdio_new_mode) { | ||
469 | if (mwifiex_init_sdio_new_mode(adapter)) | ||
470 | return -1; | ||
471 | goto cont; | ||
472 | } | ||
473 | |||
429 | /* Read the IO port */ | 474 | /* Read the IO port */ |
430 | if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, ®)) | 475 | if (!mwifiex_read_reg(adapter, IO_PORT_0_REG, ®)) |
431 | adapter->ioport |= (reg & 0xff); | 476 | adapter->ioport |= (reg & 0xff); |
@@ -441,7 +486,7 @@ static int mwifiex_init_sdio_ioport(struct mwifiex_adapter *adapter) | |||
441 | adapter->ioport |= ((reg & 0xff) << 16); | 486 | adapter->ioport |= ((reg & 0xff) << 16); |
442 | else | 487 | else |
443 | return -1; | 488 | return -1; |
444 | 489 | cont: | |
445 | pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport); | 490 | pr_debug("info: SDIO FUNC1 IO port: %#x\n", adapter->ioport); |
446 | 491 | ||
447 | /* Set Host interrupt reset to read to clear */ | 492 | /* Set Host interrupt reset to read to clear */ |
@@ -504,10 +549,16 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
504 | 549 | ||
505 | dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap); | 550 | dev_dbg(adapter->dev, "data: mp_rd_bitmap=0x%08x\n", rd_bitmap); |
506 | 551 | ||
507 | if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask))) | 552 | if (card->supports_sdio_new_mode) { |
508 | return -1; | 553 | if (!(rd_bitmap & reg->data_port_mask)) |
554 | return -1; | ||
555 | } else { | ||
556 | if (!(rd_bitmap & (CTRL_PORT_MASK | reg->data_port_mask))) | ||
557 | return -1; | ||
558 | } | ||
509 | 559 | ||
510 | if (card->mp_rd_bitmap & CTRL_PORT_MASK) { | 560 | if ((card->has_control_mask) && |
561 | (card->mp_rd_bitmap & CTRL_PORT_MASK)) { | ||
511 | card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK); | 562 | card->mp_rd_bitmap &= (u32) (~CTRL_PORT_MASK); |
512 | *port = CTRL_PORT; | 563 | *port = CTRL_PORT; |
513 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n", | 564 | dev_dbg(adapter->dev, "data: port=%d mp_rd_bitmap=0x%08x\n", |
@@ -542,24 +593,34 @@ static int mwifiex_get_rd_port(struct mwifiex_adapter *adapter, u8 *port) | |||
542 | static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port) | 593 | static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port) |
543 | { | 594 | { |
544 | struct sdio_mmc_card *card = adapter->card; | 595 | struct sdio_mmc_card *card = adapter->card; |
596 | const struct mwifiex_sdio_card_reg *reg = card->reg; | ||
545 | u32 wr_bitmap = card->mp_wr_bitmap; | 597 | u32 wr_bitmap = card->mp_wr_bitmap; |
546 | 598 | ||
547 | dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap); | 599 | dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap); |
548 | 600 | ||
549 | if (!(wr_bitmap & card->mp_data_port_mask)) | 601 | if (card->supports_sdio_new_mode && |
602 | !(wr_bitmap & reg->data_port_mask)) { | ||
603 | adapter->data_sent = true; | ||
604 | return -EBUSY; | ||
605 | } else if (!card->supports_sdio_new_mode && | ||
606 | !(wr_bitmap & card->mp_data_port_mask)) { | ||
550 | return -1; | 607 | return -1; |
608 | } | ||
551 | 609 | ||
552 | if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { | 610 | if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { |
553 | card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port)); | 611 | card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port)); |
554 | *port = card->curr_wr_port; | 612 | *port = card->curr_wr_port; |
555 | if (++card->curr_wr_port == card->mp_end_port) | 613 | if (((card->supports_sdio_new_mode) && |
556 | card->curr_wr_port = card->reg->start_wr_port; | 614 | (++card->curr_wr_port == card->max_ports)) || |
615 | ((!card->supports_sdio_new_mode) && | ||
616 | (++card->curr_wr_port == card->mp_end_port))) | ||
617 | card->curr_wr_port = reg->start_wr_port; | ||
557 | } else { | 618 | } else { |
558 | adapter->data_sent = true; | 619 | adapter->data_sent = true; |
559 | return -EBUSY; | 620 | return -EBUSY; |
560 | } | 621 | } |
561 | 622 | ||
562 | if (*port == CTRL_PORT) { | 623 | if ((card->has_control_mask) && (*port == CTRL_PORT)) { |
563 | dev_err(adapter->dev, | 624 | dev_err(adapter->dev, |
564 | "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n", | 625 | "invalid data port=%d cur port=%d mp_wr_bitmap=0x%08x -> 0x%08x\n", |
565 | *port, card->curr_wr_port, wr_bitmap, | 626 | *port, card->curr_wr_port, wr_bitmap, |
@@ -904,6 +965,9 @@ static void mwifiex_interrupt_status(struct mwifiex_adapter *adapter) | |||
904 | if (sdio_ireg) { | 965 | if (sdio_ireg) { |
905 | /* | 966 | /* |
906 | * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS | 967 | * DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS |
968 | * For SDIO new mode CMD port interrupts | ||
969 | * DN_LD_CMD_PORT_HOST_INT_STATUS and/or | ||
970 | * UP_LD_CMD_PORT_HOST_INT_STATUS | ||
907 | * Clear the interrupt status register | 971 | * Clear the interrupt status register |
908 | */ | 972 | */ |
909 | dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg); | 973 | dev_dbg(adapter->dev, "int: sdio_ireg = %#x\n", sdio_ireg); |
@@ -1031,7 +1095,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1031 | u8 *curr_ptr; | 1095 | u8 *curr_ptr; |
1032 | u32 rx_len = skb->len; | 1096 | u32 rx_len = skb->len; |
1033 | 1097 | ||
1034 | if (port == CTRL_PORT) { | 1098 | if ((card->has_control_mask) && (port == CTRL_PORT)) { |
1035 | /* Read the command Resp without aggr */ | 1099 | /* Read the command Resp without aggr */ |
1036 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " | 1100 | dev_dbg(adapter->dev, "info: %s: no aggregation for cmd " |
1037 | "response\n", __func__); | 1101 | "response\n", __func__); |
@@ -1048,7 +1112,10 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1048 | goto rx_curr_single; | 1112 | goto rx_curr_single; |
1049 | } | 1113 | } |
1050 | 1114 | ||
1051 | if (card->mp_rd_bitmap & (~((u32) CTRL_PORT_MASK))) { | 1115 | if ((!card->has_control_mask && (card->mp_rd_bitmap & |
1116 | card->reg->data_port_mask)) || | ||
1117 | (card->has_control_mask && (card->mp_rd_bitmap & | ||
1118 | (~((u32) CTRL_PORT_MASK))))) { | ||
1052 | /* Some more data RX pending */ | 1119 | /* Some more data RX pending */ |
1053 | dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); | 1120 | dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); |
1054 | 1121 | ||
@@ -1100,8 +1167,25 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, | |||
1100 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", | 1167 | dev_dbg(adapter->dev, "info: do_rx_aggr: num of packets: %d\n", |
1101 | card->mpa_rx.pkt_cnt); | 1168 | card->mpa_rx.pkt_cnt); |
1102 | 1169 | ||
1103 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | 1170 | if (card->supports_sdio_new_mode) { |
1104 | (card->mpa_rx.ports << 4)) + card->mpa_rx.start_port; | 1171 | int i; |
1172 | u32 port_count; | ||
1173 | |||
1174 | for (i = 0, port_count = 0; i < card->max_ports; i++) | ||
1175 | if (card->mpa_rx.ports & BIT(i)) | ||
1176 | port_count++; | ||
1177 | |||
1178 | /* Reading data from "start_port + 0" to "start_port + | ||
1179 | * port_count -1", so decrease the count by 1 | ||
1180 | */ | ||
1181 | port_count--; | ||
1182 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | ||
1183 | (port_count << 8)) + card->mpa_rx.start_port; | ||
1184 | } else { | ||
1185 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | ||
1186 | (card->mpa_rx.ports << 4)) + | ||
1187 | card->mpa_rx.start_port; | ||
1188 | } | ||
1105 | 1189 | ||
1106 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, | 1190 | if (mwifiex_read_data_sync(adapter, card->mpa_rx.buf, |
1107 | card->mpa_rx.buf_len, mport, 1)) | 1191 | card->mpa_rx.buf_len, mport, 1)) |
@@ -1200,6 +1284,8 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1200 | u32 rx_blocks; | 1284 | u32 rx_blocks; |
1201 | u16 rx_len; | 1285 | u16 rx_len; |
1202 | unsigned long flags; | 1286 | unsigned long flags; |
1287 | u32 bitmap; | ||
1288 | u8 cr; | ||
1203 | 1289 | ||
1204 | spin_lock_irqsave(&adapter->int_lock, flags); | 1290 | spin_lock_irqsave(&adapter->int_lock, flags); |
1205 | sdio_ireg = adapter->int_status; | 1291 | sdio_ireg = adapter->int_status; |
@@ -1209,12 +1295,60 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1209 | if (!sdio_ireg) | 1295 | if (!sdio_ireg) |
1210 | return ret; | 1296 | return ret; |
1211 | 1297 | ||
1298 | /* Following interrupt is only for SDIO new mode */ | ||
1299 | if (sdio_ireg & DN_LD_CMD_PORT_HOST_INT_STATUS && adapter->cmd_sent) | ||
1300 | adapter->cmd_sent = false; | ||
1301 | |||
1302 | /* Following interrupt is only for SDIO new mode */ | ||
1303 | if (sdio_ireg & UP_LD_CMD_PORT_HOST_INT_STATUS) { | ||
1304 | u32 pkt_type; | ||
1305 | |||
1306 | /* read the len of control packet */ | ||
1307 | rx_len = card->mp_regs[CMD_RD_LEN_1] << 8; | ||
1308 | rx_len |= (u16) card->mp_regs[CMD_RD_LEN_0]; | ||
1309 | rx_blocks = DIV_ROUND_UP(rx_len, MWIFIEX_SDIO_BLOCK_SIZE); | ||
1310 | if (rx_len <= INTF_HEADER_LEN || | ||
1311 | (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > | ||
1312 | MWIFIEX_RX_DATA_BUF_SIZE) | ||
1313 | return -1; | ||
1314 | rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); | ||
1315 | |||
1316 | skb = dev_alloc_skb(rx_len); | ||
1317 | if (!skb) | ||
1318 | return -1; | ||
1319 | |||
1320 | skb_put(skb, rx_len); | ||
1321 | |||
1322 | if (mwifiex_sdio_card_to_host(adapter, &pkt_type, skb->data, | ||
1323 | skb->len, adapter->ioport | | ||
1324 | CMD_PORT_SLCT)) { | ||
1325 | dev_err(adapter->dev, | ||
1326 | "%s: failed to card_to_host", __func__); | ||
1327 | dev_kfree_skb_any(skb); | ||
1328 | goto term_cmd; | ||
1329 | } | ||
1330 | |||
1331 | if ((pkt_type != MWIFIEX_TYPE_CMD) && | ||
1332 | (pkt_type != MWIFIEX_TYPE_EVENT)) | ||
1333 | dev_err(adapter->dev, | ||
1334 | "%s:Received wrong packet on cmd port", | ||
1335 | __func__); | ||
1336 | |||
1337 | mwifiex_decode_rx_packet(adapter, skb, pkt_type); | ||
1338 | } | ||
1339 | |||
1212 | if (sdio_ireg & DN_LD_HOST_INT_STATUS) { | 1340 | if (sdio_ireg & DN_LD_HOST_INT_STATUS) { |
1213 | card->mp_wr_bitmap = | 1341 | bitmap = (u32) card->mp_regs[reg->wr_bitmap_l]; |
1214 | ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8; | 1342 | bitmap |= ((u32) card->mp_regs[reg->wr_bitmap_u]) << 8; |
1215 | card->mp_wr_bitmap |= | 1343 | if (card->supports_sdio_new_mode) { |
1216 | (u32) card->mp_regs[reg->wr_bitmap_l]; | 1344 | bitmap |= |
1217 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%08x\n", | 1345 | ((u32) card->mp_regs[reg->wr_bitmap_1l]) << 16; |
1346 | bitmap |= | ||
1347 | ((u32) card->mp_regs[reg->wr_bitmap_1u]) << 24; | ||
1348 | } | ||
1349 | card->mp_wr_bitmap = bitmap; | ||
1350 | |||
1351 | dev_dbg(adapter->dev, "int: DNLD: wr_bitmap=0x%x\n", | ||
1218 | card->mp_wr_bitmap); | 1352 | card->mp_wr_bitmap); |
1219 | if (adapter->data_sent && | 1353 | if (adapter->data_sent && |
1220 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { | 1354 | (card->mp_wr_bitmap & card->mp_data_port_mask)) { |
@@ -1227,7 +1361,7 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1227 | /* As firmware will not generate download ready interrupt if the port | 1361 | /* As firmware will not generate download ready interrupt if the port |
1228 | updated is command port only, cmd_sent should be done for any SDIO | 1362 | updated is command port only, cmd_sent should be done for any SDIO |
1229 | interrupt. */ | 1363 | interrupt. */ |
1230 | if (adapter->cmd_sent) { | 1364 | if (card->has_control_mask && adapter->cmd_sent) { |
1231 | /* Check if firmware has attach buffer at command port and | 1365 | /* Check if firmware has attach buffer at command port and |
1232 | update just that in wr_bit_map. */ | 1366 | update just that in wr_bit_map. */ |
1233 | card->mp_wr_bitmap |= | 1367 | card->mp_wr_bitmap |= |
@@ -1239,10 +1373,16 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1239 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", | 1373 | dev_dbg(adapter->dev, "info: cmd_sent=%d data_sent=%d\n", |
1240 | adapter->cmd_sent, adapter->data_sent); | 1374 | adapter->cmd_sent, adapter->data_sent); |
1241 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { | 1375 | if (sdio_ireg & UP_LD_HOST_INT_STATUS) { |
1242 | card->mp_rd_bitmap = | 1376 | bitmap = (u32) card->mp_regs[reg->rd_bitmap_l]; |
1243 | ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8; | 1377 | bitmap |= ((u32) card->mp_regs[reg->rd_bitmap_u]) << 8; |
1244 | card->mp_rd_bitmap |= (u32) card->mp_regs[reg->rd_bitmap_l]; | 1378 | if (card->supports_sdio_new_mode) { |
1245 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%08x\n", | 1379 | bitmap |= |
1380 | ((u32) card->mp_regs[reg->rd_bitmap_1l]) << 16; | ||
1381 | bitmap |= | ||
1382 | ((u32) card->mp_regs[reg->rd_bitmap_1u]) << 24; | ||
1383 | } | ||
1384 | card->mp_rd_bitmap = bitmap; | ||
1385 | dev_dbg(adapter->dev, "int: UPLD: rd_bitmap=0x%x\n", | ||
1246 | card->mp_rd_bitmap); | 1386 | card->mp_rd_bitmap); |
1247 | 1387 | ||
1248 | while (true) { | 1388 | while (true) { |
@@ -1285,37 +1425,33 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter) | |||
1285 | 1425 | ||
1286 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, | 1426 | if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, |
1287 | port)) { | 1427 | port)) { |
1288 | u8 cr = 0; | ||
1289 | |||
1290 | dev_err(adapter->dev, "card_to_host_mpa failed:" | 1428 | dev_err(adapter->dev, "card_to_host_mpa failed:" |
1291 | " int status=%#x\n", sdio_ireg); | 1429 | " int status=%#x\n", sdio_ireg); |
1292 | if (mwifiex_read_reg(adapter, | 1430 | goto term_cmd; |
1293 | CONFIGURATION_REG, &cr)) | ||
1294 | dev_err(adapter->dev, | ||
1295 | "read CFG reg failed\n"); | ||
1296 | |||
1297 | dev_dbg(adapter->dev, | ||
1298 | "info: CFG reg val = %d\n", cr); | ||
1299 | if (mwifiex_write_reg(adapter, | ||
1300 | CONFIGURATION_REG, | ||
1301 | (cr | 0x04))) | ||
1302 | dev_err(adapter->dev, | ||
1303 | "write CFG reg failed\n"); | ||
1304 | |||
1305 | dev_dbg(adapter->dev, "info: write success\n"); | ||
1306 | if (mwifiex_read_reg(adapter, | ||
1307 | CONFIGURATION_REG, &cr)) | ||
1308 | dev_err(adapter->dev, | ||
1309 | "read CFG reg failed\n"); | ||
1310 | |||
1311 | dev_dbg(adapter->dev, | ||
1312 | "info: CFG reg val =%x\n", cr); | ||
1313 | return -1; | ||
1314 | } | 1431 | } |
1315 | } | 1432 | } |
1316 | } | 1433 | } |
1317 | 1434 | ||
1318 | return 0; | 1435 | return 0; |
1436 | |||
1437 | term_cmd: | ||
1438 | /* terminate cmd */ | ||
1439 | if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) | ||
1440 | dev_err(adapter->dev, "read CFG reg failed\n"); | ||
1441 | else | ||
1442 | dev_dbg(adapter->dev, "info: CFG reg val = %d\n", cr); | ||
1443 | |||
1444 | if (mwifiex_write_reg(adapter, CONFIGURATION_REG, (cr | 0x04))) | ||
1445 | dev_err(adapter->dev, "write CFG reg failed\n"); | ||
1446 | else | ||
1447 | dev_dbg(adapter->dev, "info: write success\n"); | ||
1448 | |||
1449 | if (mwifiex_read_reg(adapter, CONFIGURATION_REG, &cr)) | ||
1450 | dev_err(adapter->dev, "read CFG reg failed\n"); | ||
1451 | else | ||
1452 | dev_dbg(adapter->dev, "info: CFG reg val =%x\n", cr); | ||
1453 | |||
1454 | return -1; | ||
1319 | } | 1455 | } |
1320 | 1456 | ||
1321 | /* | 1457 | /* |
@@ -1344,7 +1480,9 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1344 | s32 f_postcopy_cur_buf = 0; | 1480 | s32 f_postcopy_cur_buf = 0; |
1345 | u32 mport; | 1481 | u32 mport; |
1346 | 1482 | ||
1347 | if ((!card->mpa_tx.enabled) || (port == CTRL_PORT)) { | 1483 | if (!card->mpa_tx.enabled || |
1484 | (card->has_control_mask && (port == CTRL_PORT)) || | ||
1485 | (card->supports_sdio_new_mode && (port == CMD_PORT_SLCT))) { | ||
1348 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", | 1486 | dev_dbg(adapter->dev, "info: %s: tx aggregation disabled\n", |
1349 | __func__); | 1487 | __func__); |
1350 | 1488 | ||
@@ -1419,8 +1557,26 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter, | |||
1419 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", | 1557 | dev_dbg(adapter->dev, "data: %s: send aggr buffer: %d %d\n", |
1420 | __func__, | 1558 | __func__, |
1421 | card->mpa_tx.start_port, card->mpa_tx.ports); | 1559 | card->mpa_tx.start_port, card->mpa_tx.ports); |
1422 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | 1560 | if (card->supports_sdio_new_mode) { |
1423 | (card->mpa_tx.ports << 4)) + card->mpa_tx.start_port; | 1561 | u32 port_count; |
1562 | int i; | ||
1563 | |||
1564 | for (i = 0, port_count = 0; i < card->max_ports; i++) | ||
1565 | if (card->mpa_tx.ports & BIT(i)) | ||
1566 | port_count++; | ||
1567 | |||
1568 | /* Writing data from "start_port + 0" to "start_port + | ||
1569 | * port_count -1", so decrease the count by 1 | ||
1570 | */ | ||
1571 | port_count--; | ||
1572 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | ||
1573 | (port_count << 8)) + card->mpa_tx.start_port; | ||
1574 | } else { | ||
1575 | mport = (adapter->ioport | SDIO_MPA_ADDR_BASE | | ||
1576 | (card->mpa_tx.ports << 4)) + | ||
1577 | card->mpa_tx.start_port; | ||
1578 | } | ||
1579 | |||
1424 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, | 1580 | ret = mwifiex_write_data_to_card(adapter, card->mpa_tx.buf, |
1425 | card->mpa_tx.buf_len, mport); | 1581 | card->mpa_tx.buf_len, mport); |
1426 | 1582 | ||
@@ -1493,6 +1649,9 @@ static int mwifiex_sdio_host_to_card(struct mwifiex_adapter *adapter, | |||
1493 | pkt_len > MWIFIEX_UPLD_SIZE) | 1649 | pkt_len > MWIFIEX_UPLD_SIZE) |
1494 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", | 1650 | dev_err(adapter->dev, "%s: payload=%p, nb=%d\n", |
1495 | __func__, payload, pkt_len); | 1651 | __func__, payload, pkt_len); |
1652 | |||
1653 | if (card->supports_sdio_new_mode) | ||
1654 | port = CMD_PORT_SLCT; | ||
1496 | } | 1655 | } |
1497 | 1656 | ||
1498 | /* Transfer data to card */ | 1657 | /* Transfer data to card */ |
@@ -1748,8 +1907,11 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port) | |||
1748 | 1907 | ||
1749 | card->mp_data_port_mask = reg->data_port_mask; | 1908 | card->mp_data_port_mask = reg->data_port_mask; |
1750 | 1909 | ||
1751 | for (i = 1; i <= card->max_ports - card->mp_end_port; i++) | 1910 | if (reg->start_wr_port) { |
1752 | card->mp_data_port_mask &= ~(1 << (card->max_ports - i)); | 1911 | for (i = 1; i <= card->max_ports - card->mp_end_port; i++) |
1912 | card->mp_data_port_mask &= | ||
1913 | ~(1 << (card->max_ports - i)); | ||
1914 | } | ||
1753 | 1915 | ||
1754 | card->curr_wr_port = reg->start_wr_port; | 1916 | card->curr_wr_port = reg->start_wr_port; |
1755 | 1917 | ||
@@ -1857,3 +2019,4 @@ MODULE_LICENSE("GPL v2"); | |||
1857 | MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME); | 2019 | MODULE_FIRMWARE(SD8786_DEFAULT_FW_NAME); |
1858 | MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); | 2020 | MODULE_FIRMWARE(SD8787_DEFAULT_FW_NAME); |
1859 | MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); | 2021 | MODULE_FIRMWARE(SD8797_DEFAULT_FW_NAME); |
2022 | MODULE_FIRMWARE(SD8897_DEFAULT_FW_NAME); | ||