.. | .. |
---|
1 | | -/** |
---|
| 1 | +/* |
---|
2 | 2 | * Copyright (c) 2014 Redpine Signals Inc. |
---|
3 | 3 | * |
---|
4 | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
---|
.. | .. |
---|
135 | 135 | } |
---|
136 | 136 | |
---|
137 | 137 | /** |
---|
138 | | - * rsi_handle_interrupt() - This function is called upon the occurence |
---|
| 138 | + * rsi_handle_interrupt() - This function is called upon the occurrence |
---|
139 | 139 | * of an interrupt. |
---|
140 | 140 | * @function: Pointer to the sdio_func structure. |
---|
141 | 141 | * |
---|
.. | .. |
---|
228 | 228 | err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, 0, |
---|
229 | 229 | (MMC_RSP_R4 | MMC_CMD_BCR), &resp); |
---|
230 | 230 | if (err) |
---|
231 | | - rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", __func__, err); |
---|
| 231 | + rsi_dbg(ERR_ZONE, "%s: CMD5 failed : %d\n", |
---|
| 232 | + __func__, err); |
---|
232 | 233 | card->ocr = resp; |
---|
233 | | - |
---|
234 | 234 | /* Issue CMD5, arg = ocr. Wait till card is ready */ |
---|
235 | 235 | for (i = 0; i < 100; i++) { |
---|
236 | 236 | err = rsi_issue_sdiocommand(pfunction, SD_IO_SEND_OP_COND, |
---|
.. | .. |
---|
794 | 794 | |
---|
795 | 795 | /** |
---|
796 | 796 | * rsi_sdio_host_intf_read_pkt() - This function reads the packet |
---|
797 | | - from the device. |
---|
| 797 | + * from the device. |
---|
798 | 798 | * @adapter: Pointer to the adapter data structure. |
---|
799 | 799 | * @pkt: Pointer to the packet data to be read from the the device. |
---|
800 | 800 | * @length: Length of the data to be read from the device. |
---|
.. | .. |
---|
827 | 827 | * rsi_init_sdio_interface() - This function does init specific to SDIO. |
---|
828 | 828 | * |
---|
829 | 829 | * @adapter: Pointer to the adapter data structure. |
---|
830 | | - * @pkt: Pointer to the packet data to be read from the the device. |
---|
| 830 | + * @pfunction: Pointer to the sdio_func structure. |
---|
831 | 831 | * |
---|
832 | 832 | * Return: 0 on success, -1 on failure. |
---|
833 | 833 | */ |
---|
834 | | - |
---|
835 | 834 | static int rsi_init_sdio_interface(struct rsi_hw *adapter, |
---|
836 | 835 | struct sdio_func *pfunction) |
---|
837 | 836 | { |
---|
838 | 837 | struct rsi_91x_sdiodev *rsi_91x_dev; |
---|
839 | | - int status = -ENOMEM; |
---|
| 838 | + int status; |
---|
840 | 839 | |
---|
841 | 840 | rsi_91x_dev = kzalloc(sizeof(*rsi_91x_dev), GFP_KERNEL); |
---|
842 | 841 | if (!rsi_91x_dev) |
---|
843 | | - return status; |
---|
| 842 | + return -ENOMEM; |
---|
844 | 843 | |
---|
845 | 844 | adapter->rsi_dev = rsi_91x_dev; |
---|
846 | 845 | |
---|
.. | .. |
---|
867 | 866 | goto fail; |
---|
868 | 867 | } |
---|
869 | 868 | |
---|
870 | | - rsi_dbg(INIT_ZONE, "%s: Setup card succesfully\n", __func__); |
---|
| 869 | + rsi_dbg(INIT_ZONE, "%s: Setup card successfully\n", __func__); |
---|
871 | 870 | |
---|
872 | 871 | status = rsi_init_sdio_slave_regs(adapter); |
---|
873 | 872 | if (status) { |
---|
.. | .. |
---|
882 | 881 | #ifdef CONFIG_RSI_DEBUGFS |
---|
883 | 882 | adapter->num_debugfs_entries = MAX_DEBUGFS_ENTRIES; |
---|
884 | 883 | #endif |
---|
885 | | - return status; |
---|
| 884 | + return 0; |
---|
886 | 885 | fail: |
---|
887 | 886 | sdio_disable_func(pfunction); |
---|
888 | 887 | sdio_release_host(pfunction); |
---|
.. | .. |
---|
915 | 914 | return 0; |
---|
916 | 915 | } |
---|
917 | 916 | |
---|
| 917 | +static int rsi_sdio_ta_reset(struct rsi_hw *adapter) |
---|
| 918 | +{ |
---|
| 919 | + int status; |
---|
| 920 | + u32 addr; |
---|
| 921 | + u8 *data; |
---|
| 922 | + |
---|
| 923 | + data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL); |
---|
| 924 | + if (!data) |
---|
| 925 | + return -ENOMEM; |
---|
| 926 | + |
---|
| 927 | + status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR); |
---|
| 928 | + if (status < 0) { |
---|
| 929 | + rsi_dbg(ERR_ZONE, |
---|
| 930 | + "Unable to set ms word to common reg\n"); |
---|
| 931 | + goto err; |
---|
| 932 | + } |
---|
| 933 | + |
---|
| 934 | + rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__); |
---|
| 935 | + put_unaligned_le32(TA_HOLD_THREAD_VALUE, data); |
---|
| 936 | + addr = TA_HOLD_THREAD_REG | RSI_SD_REQUEST_MASTER; |
---|
| 937 | + status = rsi_sdio_write_register_multiple(adapter, addr, |
---|
| 938 | + (u8 *)data, |
---|
| 939 | + RSI_9116_REG_SIZE); |
---|
| 940 | + if (status < 0) { |
---|
| 941 | + rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n"); |
---|
| 942 | + goto err; |
---|
| 943 | + } |
---|
| 944 | + |
---|
| 945 | + put_unaligned_le32(TA_SOFT_RST_CLR, data); |
---|
| 946 | + addr = TA_SOFT_RESET_REG | RSI_SD_REQUEST_MASTER; |
---|
| 947 | + status = rsi_sdio_write_register_multiple(adapter, addr, |
---|
| 948 | + (u8 *)data, |
---|
| 949 | + RSI_9116_REG_SIZE); |
---|
| 950 | + if (status < 0) { |
---|
| 951 | + rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n"); |
---|
| 952 | + goto err; |
---|
| 953 | + } |
---|
| 954 | + |
---|
| 955 | + put_unaligned_le32(TA_PC_ZERO, data); |
---|
| 956 | + addr = TA_TH0_PC_REG | RSI_SD_REQUEST_MASTER; |
---|
| 957 | + status = rsi_sdio_write_register_multiple(adapter, addr, |
---|
| 958 | + (u8 *)data, |
---|
| 959 | + RSI_9116_REG_SIZE); |
---|
| 960 | + if (status < 0) { |
---|
| 961 | + rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n"); |
---|
| 962 | + status = -EINVAL; |
---|
| 963 | + goto err; |
---|
| 964 | + } |
---|
| 965 | + |
---|
| 966 | + put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data); |
---|
| 967 | + addr = TA_RELEASE_THREAD_REG | RSI_SD_REQUEST_MASTER; |
---|
| 968 | + status = rsi_sdio_write_register_multiple(adapter, addr, |
---|
| 969 | + (u8 *)data, |
---|
| 970 | + RSI_9116_REG_SIZE); |
---|
| 971 | + if (status < 0) { |
---|
| 972 | + rsi_dbg(ERR_ZONE, "Unable to release TA threads\n"); |
---|
| 973 | + goto err; |
---|
| 974 | + } |
---|
| 975 | + |
---|
| 976 | + status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR); |
---|
| 977 | + if (status < 0) { |
---|
| 978 | + rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n"); |
---|
| 979 | + goto err; |
---|
| 980 | + } |
---|
| 981 | + rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n"); |
---|
| 982 | + |
---|
| 983 | +err: |
---|
| 984 | + kfree(data); |
---|
| 985 | + return status; |
---|
| 986 | +} |
---|
| 987 | + |
---|
918 | 988 | static struct rsi_host_intf_ops sdio_host_intf_ops = { |
---|
919 | 989 | .write_pkt = rsi_sdio_host_intf_write_pkt, |
---|
920 | 990 | .read_pkt = rsi_sdio_host_intf_read_pkt, |
---|
.. | .. |
---|
925 | 995 | .master_reg_write = rsi_sdio_master_reg_write, |
---|
926 | 996 | .load_data_master_write = rsi_sdio_load_data_master_write, |
---|
927 | 997 | .reinit_device = rsi_sdio_reinit_device, |
---|
| 998 | + .ta_reset = rsi_sdio_ta_reset, |
---|
928 | 999 | }; |
---|
929 | 1000 | |
---|
930 | 1001 | /** |
---|
.. | .. |
---|
941 | 1012 | { |
---|
942 | 1013 | struct rsi_hw *adapter; |
---|
943 | 1014 | struct rsi_91x_sdiodev *sdev; |
---|
944 | | - int status; |
---|
| 1015 | + int status = -EINVAL; |
---|
945 | 1016 | |
---|
946 | 1017 | rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); |
---|
947 | 1018 | |
---|
.. | .. |
---|
960 | 1031 | status = -EIO; |
---|
961 | 1032 | goto fail_free_adapter; |
---|
962 | 1033 | } |
---|
| 1034 | + |
---|
| 1035 | + if (pfunction->device == SDIO_DEVICE_ID_RSI_9113) { |
---|
| 1036 | + rsi_dbg(ERR_ZONE, "%s: 9113 module detected\n", __func__); |
---|
| 1037 | + adapter->device_model = RSI_DEV_9113; |
---|
| 1038 | + } else if (pfunction->device == SDIO_DEVICE_ID_RSI_9116) { |
---|
| 1039 | + rsi_dbg(ERR_ZONE, "%s: 9116 module detected\n", __func__); |
---|
| 1040 | + adapter->device_model = RSI_DEV_9116; |
---|
| 1041 | + } else { |
---|
| 1042 | + rsi_dbg(ERR_ZONE, |
---|
| 1043 | + "%s: Unsupported RSI device id 0x%x\n", __func__, |
---|
| 1044 | + pfunction->device); |
---|
| 1045 | + goto fail_free_adapter; |
---|
| 1046 | + } |
---|
| 1047 | + |
---|
963 | 1048 | sdev = (struct rsi_91x_sdiodev *)adapter->rsi_dev; |
---|
964 | 1049 | rsi_init_event(&sdev->rx_thread.event); |
---|
965 | 1050 | status = rsi_create_kthread(adapter->priv, &sdev->rx_thread, |
---|
.. | .. |
---|
1078 | 1163 | * and any pending dma transfers to rf spi in device to finish. |
---|
1079 | 1164 | */ |
---|
1080 | 1165 | msleep(100); |
---|
1081 | | - |
---|
1082 | | - ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32); |
---|
1083 | | - ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32); |
---|
1084 | | - ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0, 32); |
---|
1085 | | - ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1, RSI_ULP_WRITE_50, |
---|
1086 | | - 32); |
---|
1087 | | - ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2, RSI_ULP_WRITE_0, |
---|
1088 | | - 32); |
---|
1089 | | - ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE, |
---|
1090 | | - RSI_ULP_TIMER_ENABLE, 32); |
---|
| 1166 | + if (adapter->device_model != RSI_DEV_9116) { |
---|
| 1167 | + ulp_read_write(adapter, RSI_ULP_RESET_REG, RSI_ULP_WRITE_0, 32); |
---|
| 1168 | + ulp_read_write(adapter, |
---|
| 1169 | + RSI_WATCH_DOG_TIMER_1, RSI_ULP_WRITE_2, 32); |
---|
| 1170 | + ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_2, RSI_ULP_WRITE_0, |
---|
| 1171 | + 32); |
---|
| 1172 | + ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_1, |
---|
| 1173 | + RSI_ULP_WRITE_50, 32); |
---|
| 1174 | + ulp_read_write(adapter, RSI_WATCH_DOG_DELAY_TIMER_2, |
---|
| 1175 | + RSI_ULP_WRITE_0, 32); |
---|
| 1176 | + ulp_read_write(adapter, RSI_WATCH_DOG_TIMER_ENABLE, |
---|
| 1177 | + RSI_ULP_TIMER_ENABLE, 32); |
---|
| 1178 | + } else { |
---|
| 1179 | + if ((rsi_sdio_master_reg_write(adapter, |
---|
| 1180 | + NWP_WWD_INTERRUPT_TIMER, |
---|
| 1181 | + NWP_WWD_INT_TIMER_CLKS, |
---|
| 1182 | + RSI_9116_REG_SIZE)) < 0) { |
---|
| 1183 | + rsi_dbg(ERR_ZONE, "Failed to write to intr timer\n"); |
---|
| 1184 | + } |
---|
| 1185 | + if ((rsi_sdio_master_reg_write(adapter, |
---|
| 1186 | + NWP_WWD_SYSTEM_RESET_TIMER, |
---|
| 1187 | + NWP_WWD_SYS_RESET_TIMER_CLKS, |
---|
| 1188 | + RSI_9116_REG_SIZE)) < 0) { |
---|
| 1189 | + rsi_dbg(ERR_ZONE, |
---|
| 1190 | + "Failed to write to system reset timer\n"); |
---|
| 1191 | + } |
---|
| 1192 | + if ((rsi_sdio_master_reg_write(adapter, |
---|
| 1193 | + NWP_WWD_MODE_AND_RSTART, |
---|
| 1194 | + NWP_WWD_TIMER_DISABLE, |
---|
| 1195 | + RSI_9116_REG_SIZE)) < 0) { |
---|
| 1196 | + rsi_dbg(ERR_ZONE, |
---|
| 1197 | + "Failed to write to mode and restart\n"); |
---|
| 1198 | + } |
---|
| 1199 | + rsi_dbg(ERR_ZONE, "***** Watch Dog Reset Successful *****\n"); |
---|
| 1200 | + } |
---|
1091 | 1201 | /* This msleep will be sufficient for the ulp |
---|
1092 | 1202 | * read write operations to complete for chip reset. |
---|
1093 | 1203 | */ |
---|
.. | .. |
---|
1350 | 1460 | struct rsi_91x_sdiodev *sdev = |
---|
1351 | 1461 | (struct rsi_91x_sdiodev *)adapter->rsi_dev; |
---|
1352 | 1462 | struct ieee80211_hw *hw = adapter->hw; |
---|
1353 | | - struct cfg80211_wowlan *wowlan = hw->wiphy->wowlan_config; |
---|
1354 | 1463 | |
---|
1355 | 1464 | rsi_dbg(ERR_ZONE, "SDIO Bus shutdown =====>\n"); |
---|
1356 | 1465 | |
---|
1357 | | - if (rsi_config_wowlan(adapter, wowlan)) |
---|
1358 | | - rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); |
---|
| 1466 | + if (hw && hw->wiphy && hw->wiphy->wowlan_config) { |
---|
| 1467 | + if (rsi_config_wowlan(adapter, hw->wiphy->wowlan_config)) |
---|
| 1468 | + rsi_dbg(ERR_ZONE, "Failed to configure WoWLAN\n"); |
---|
| 1469 | + } |
---|
1359 | 1470 | |
---|
1360 | 1471 | if (IS_ENABLED(CONFIG_RSI_COEX) && adapter->priv->coex_mode > 1 && |
---|
1361 | 1472 | adapter->priv->bt_adapter) { |
---|
.. | .. |
---|
1367 | 1478 | |
---|
1368 | 1479 | if (sdev->write_fail) |
---|
1369 | 1480 | rsi_dbg(INFO_ZONE, "###### Device is not ready #######\n"); |
---|
1370 | | - |
---|
1371 | | - if (rsi_set_sdio_pm_caps(adapter)) |
---|
1372 | | - rsi_dbg(INFO_ZONE, "Setting power management caps failed\n"); |
---|
1373 | 1481 | |
---|
1374 | 1482 | rsi_dbg(INFO_ZONE, "***** RSI module shut down *****\n"); |
---|
1375 | 1483 | } |
---|
.. | .. |
---|
1386 | 1494 | common->iface_down = true; |
---|
1387 | 1495 | |
---|
1388 | 1496 | adapter->sc_nvifs = 0; |
---|
1389 | | - ieee80211_restart_hw(adapter->hw); |
---|
| 1497 | + adapter->ps_state = PS_NONE; |
---|
1390 | 1498 | |
---|
1391 | 1499 | common->wow_flags = 0; |
---|
1392 | 1500 | common->iface_down = false; |
---|
.. | .. |
---|
1405 | 1513 | #endif |
---|
1406 | 1514 | |
---|
1407 | 1515 | static const struct sdio_device_id rsi_dev_table[] = { |
---|
1408 | | - { SDIO_DEVICE(RSI_SDIO_VID_9113, RSI_SDIO_PID_9113) }, |
---|
| 1516 | + { SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9113) }, |
---|
| 1517 | + { SDIO_DEVICE(SDIO_VENDOR_ID_RSI, SDIO_DEVICE_ID_RSI_9116) }, |
---|
1409 | 1518 | { /* Blank */}, |
---|
1410 | 1519 | }; |
---|
1411 | 1520 | |
---|