diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/init.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath6kl/init.c | 57 | 
1 files changed, 36 insertions, 21 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index eb7cc2f5b96f..29ef50ea07d5 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -23,12 +23,14 @@  #include <linux/export.h>  #include <linux/of.h>  #include <linux/mmc/sdio_func.h> +#include <linux/vmalloc.h>  #include "core.h"  #include "cfg80211.h"  #include "target.h"  #include "debug.h"  #include "hif-ops.h" +#include "htc-ops.h"  static const struct ath6kl_hw hw_list[] = {  	{ @@ -258,6 +260,7 @@ static int ath6kl_init_service_ep(struct ath6kl *ar)  	memset(&connect, 0, sizeof(connect));  	/* these fields are the same for all service endpoints */ +	connect.ep_cb.tx_comp_multi = ath6kl_tx_complete;  	connect.ep_cb.rx = ath6kl_rx;  	connect.ep_cb.rx_refill = ath6kl_rx_refill;  	connect.ep_cb.tx_full = ath6kl_tx_queue_full; @@ -487,22 +490,31 @@ int ath6kl_configure_target(struct ath6kl *ar)  		fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);  	/* -	 * By default, submodes : +	 * Submodes when fw does not support dynamic interface +	 * switching:  	 *		vif[0] - AP/STA/IBSS  	 *		vif[1] - "P2P dev"/"P2P GO"/"P2P Client"  	 *		vif[2] - "P2P dev"/"P2P GO"/"P2P Client" +	 * Otherwise, All the interface are initialized to p2p dev.  	 */ -	for (i = 0; i < ar->max_norm_iface; i++) -		fw_submode |= HI_OPTION_FW_SUBMODE_NONE << -			      (i * HI_OPTION_FW_SUBMODE_BITS); +	if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX, +		     ar->fw_capabilities)) { +		for (i = 0; i < ar->vif_max; i++) +			fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << +				(i * HI_OPTION_FW_SUBMODE_BITS); +	} else { +		for (i = 0; i < ar->max_norm_iface; i++) +			fw_submode |= HI_OPTION_FW_SUBMODE_NONE << +				(i * HI_OPTION_FW_SUBMODE_BITS); -	for (i = ar->max_norm_iface; i < ar->vif_max; i++) -		fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << -			      (i * HI_OPTION_FW_SUBMODE_BITS); +		for (i = ar->max_norm_iface; i < ar->vif_max; i++) +			fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << +				(i * HI_OPTION_FW_SUBMODE_BITS); -	if (ar->p2p && ar->vif_max == 1) -		fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; +		if (ar->p2p && ar->vif_max == 1) +			fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; +	}  	if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,  				  HTC_PROTOCOL_VERSION) != 0) { @@ -541,18 +553,20 @@ int ath6kl_configure_target(struct ath6kl *ar)  	 * but possible in theory.  	 */ -	param = ar->hw.board_ext_data_addr; -	ram_reserved_size = ar->hw.reserved_ram_size; +	if (ar->target_type == TARGET_TYPE_AR6003) { +		param = ar->hw.board_ext_data_addr; +		ram_reserved_size = ar->hw.reserved_ram_size; -	if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { -		ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); -		return -EIO; -	} +		if (ath6kl_bmi_write_hi32(ar, hi_board_ext_data, param) != 0) { +			ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n"); +			return -EIO; +		} -	if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, -				  ram_reserved_size) != 0) { -		ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); -		return -EIO; +		if (ath6kl_bmi_write_hi32(ar, hi_end_ram_reserve_sz, +					  ram_reserved_size) != 0) { +			ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n"); +			return -EIO; +		}  	}  	/* set the block size for the target */ @@ -926,13 +940,14 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name)  			if (ar->fw != NULL)  				break; -			ar->fw = kmemdup(data, ie_len, GFP_KERNEL); +			ar->fw = vmalloc(ie_len);  			if (ar->fw == NULL) {  				ret = -ENOMEM;  				goto out;  			} +			memcpy(ar->fw, data, ie_len);  			ar->fw_len = ie_len;  			break;  		case ATH6KL_FW_IE_PATCH_IMAGE: @@ -1509,7 +1524,7 @@ int ath6kl_init_hw_start(struct ath6kl *ar)  	}  	/* setup credit distribution */ -	ath6kl_credit_setup(ar->htc_target, &ar->credit_state_info); +	ath6kl_htc_credit_setup(ar->htc_target, &ar->credit_state_info);  	/* start HTC */  	ret = ath6kl_htc_start(ar->htc_target);  |