diff options
| author | Pontus Fuchs <pontus.fuchs@gmail.com> | 2014-02-12 14:04:45 -0500 |
|---|---|---|
| committer | John W. Linville <linville@tuxdriver.com> | 2014-02-13 15:20:17 -0500 |
| commit | f2ed5d2499b550917c7f5e50476e39548de68092 (patch) | |
| tree | 725122899f2a0e45720640b0c00beb7dd6445b5d | |
| parent | 2be6636a9610ca3924ac3ee1f4a49eced912297b (diff) | |
wcn36xx: Add support for 3680
3680 has a few registers on other addresses.
Signed-off-by: Pontus Fuchs <pontus.fuchs@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/ath/wcn36xx/dxe.c | 10 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wcn36xx/dxe.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wcn36xx/main.c | 28 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 4 |
4 files changed, 36 insertions, 10 deletions
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c index ee25786b4447..73f12f196f14 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.c +++ b/drivers/net/wireless/ath/wcn36xx/dxe.c | |||
| @@ -44,6 +44,14 @@ static void wcn36xx_dxe_write_register(struct wcn36xx *wcn, int addr, int data) | |||
| 44 | writel(data, wcn->mmio + addr); | 44 | writel(data, wcn->mmio + addr); |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | #define wcn36xx_dxe_write_register_x(wcn, reg, reg_data) \ | ||
| 48 | do { \ | ||
| 49 | if (wcn->chip_version == WCN36XX_CHIP_3680) \ | ||
| 50 | wcn36xx_dxe_write_register(wcn, reg ## _3680, reg_data); \ | ||
| 51 | else \ | ||
| 52 | wcn36xx_dxe_write_register(wcn, reg ## _3660, reg_data); \ | ||
| 53 | } while (0) \ | ||
| 54 | |||
| 47 | static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) | 55 | static void wcn36xx_dxe_read_register(struct wcn36xx *wcn, int addr, int *data) |
| 48 | { | 56 | { |
| 49 | *data = readl(wcn->mmio + addr); | 57 | *data = readl(wcn->mmio + addr); |
| @@ -680,7 +688,7 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) | |||
| 680 | 688 | ||
| 681 | /* Setting interrupt path */ | 689 | /* Setting interrupt path */ |
| 682 | reg_data = WCN36XX_DXE_CCU_INT; | 690 | reg_data = WCN36XX_DXE_CCU_INT; |
| 683 | wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); | 691 | wcn36xx_dxe_write_register_x(wcn, WCN36XX_DXE_REG_CCU_INT, reg_data); |
| 684 | 692 | ||
| 685 | /***************************************/ | 693 | /***************************************/ |
| 686 | /* Init descriptors for TX LOW channel */ | 694 | /* Init descriptors for TX LOW channel */ |
diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.h b/drivers/net/wireless/ath/wcn36xx/dxe.h index c88562f85de1..35ee7e966bd2 100644 --- a/drivers/net/wireless/ath/wcn36xx/dxe.h +++ b/drivers/net/wireless/ath/wcn36xx/dxe.h | |||
| @@ -28,11 +28,11 @@ H2H_TEST_RX_TX = DMA2 | |||
| 28 | */ | 28 | */ |
| 29 | 29 | ||
| 30 | /* DXE registers */ | 30 | /* DXE registers */ |
| 31 | #define WCN36XX_DXE_MEM_BASE 0x03000000 | ||
| 32 | #define WCN36XX_DXE_MEM_REG 0x202000 | 31 | #define WCN36XX_DXE_MEM_REG 0x202000 |
| 33 | 32 | ||
| 34 | #define WCN36XX_DXE_CCU_INT 0xA0011 | 33 | #define WCN36XX_DXE_CCU_INT 0xA0011 |
| 35 | #define WCN36XX_DXE_REG_CCU_INT 0x200b10 | 34 | #define WCN36XX_DXE_REG_CCU_INT_3660 0x200b10 |
| 35 | #define WCN36XX_DXE_REG_CCU_INT_3680 0x2050dc | ||
| 36 | 36 | ||
| 37 | /* TODO This must calculated properly but not hardcoded */ | 37 | /* TODO This must calculated properly but not hardcoded */ |
| 38 | #define WCN36XX_DXE_CTRL_TX_L 0x328a44 | 38 | #define WCN36XX_DXE_CTRL_TX_L 0x328a44 |
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c index 95fd5c6614b0..dca21ee69a62 100644 --- a/drivers/net/wireless/ath/wcn36xx/main.c +++ b/drivers/net/wireless/ath/wcn36xx/main.c | |||
| @@ -221,6 +221,17 @@ static void wcn36xx_feat_caps_info(struct wcn36xx *wcn) | |||
| 221 | } | 221 | } |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | static void wcn36xx_detect_chip_version(struct wcn36xx *wcn) | ||
| 225 | { | ||
| 226 | if (get_feat_caps(wcn->fw_feat_caps, DOT11AC)) { | ||
| 227 | wcn36xx_info("Chip is 3680\n"); | ||
| 228 | wcn->chip_version = WCN36XX_CHIP_3680; | ||
| 229 | } else { | ||
| 230 | wcn36xx_info("Chip is 3660\n"); | ||
| 231 | wcn->chip_version = WCN36XX_CHIP_3660; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 224 | static int wcn36xx_start(struct ieee80211_hw *hw) | 235 | static int wcn36xx_start(struct ieee80211_hw *hw) |
| 225 | { | 236 | { |
| 226 | struct wcn36xx *wcn = hw->priv; | 237 | struct wcn36xx *wcn = hw->priv; |
| @@ -267,6 +278,16 @@ static int wcn36xx_start(struct ieee80211_hw *hw) | |||
| 267 | goto out_free_smd_buf; | 278 | goto out_free_smd_buf; |
| 268 | } | 279 | } |
| 269 | 280 | ||
| 281 | if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { | ||
| 282 | ret = wcn36xx_smd_feature_caps_exchange(wcn); | ||
| 283 | if (ret) | ||
| 284 | wcn36xx_warn("Exchange feature caps failed\n"); | ||
| 285 | else | ||
| 286 | wcn36xx_feat_caps_info(wcn); | ||
| 287 | } | ||
| 288 | |||
| 289 | wcn36xx_detect_chip_version(wcn); | ||
| 290 | |||
| 270 | /* DMA channel initialization */ | 291 | /* DMA channel initialization */ |
| 271 | ret = wcn36xx_dxe_init(wcn); | 292 | ret = wcn36xx_dxe_init(wcn); |
| 272 | if (ret) { | 293 | if (ret) { |
| @@ -276,13 +297,6 @@ static int wcn36xx_start(struct ieee80211_hw *hw) | |||
| 276 | 297 | ||
| 277 | wcn36xx_debugfs_init(wcn); | 298 | wcn36xx_debugfs_init(wcn); |
| 278 | 299 | ||
| 279 | if (!wcn36xx_is_fw_version(wcn, 1, 2, 2, 24)) { | ||
| 280 | ret = wcn36xx_smd_feature_caps_exchange(wcn); | ||
| 281 | if (ret) | ||
| 282 | wcn36xx_warn("Exchange feature caps failed\n"); | ||
| 283 | else | ||
| 284 | wcn36xx_feat_caps_info(wcn); | ||
| 285 | } | ||
| 286 | INIT_LIST_HEAD(&wcn->vif_list); | 300 | INIT_LIST_HEAD(&wcn->vif_list); |
| 287 | return 0; | 301 | return 0; |
| 288 | 302 | ||
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h index 0c5413f2c2e0..b4dc85b45910 100644 --- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h +++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h | |||
| @@ -178,6 +178,7 @@ struct wcn36xx { | |||
| 178 | u8 fw_minor; | 178 | u8 fw_minor; |
| 179 | u8 fw_major; | 179 | u8 fw_major; |
| 180 | u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; | 180 | u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; |
| 181 | u32 chip_version; | ||
| 181 | 182 | ||
| 182 | /* extra byte for the NULL termination */ | 183 | /* extra byte for the NULL termination */ |
| 183 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | 184 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; |
| @@ -225,6 +226,9 @@ struct wcn36xx { | |||
| 225 | 226 | ||
| 226 | }; | 227 | }; |
| 227 | 228 | ||
| 229 | #define WCN36XX_CHIP_3660 0 | ||
| 230 | #define WCN36XX_CHIP_3680 1 | ||
| 231 | |||
| 228 | static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, | 232 | static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, |
| 229 | u8 major, | 233 | u8 major, |
| 230 | u8 minor, | 234 | u8 minor, |
