aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorVasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>2012-04-06 10:54:30 -0400
committerKalle Valo <kvalo@qca.qualcomm.com>2012-04-09 10:49:43 -0400
commit1e8d13b0aca8414a1ab581e24ae1851b9820a3b1 (patch)
tree230b6fb9ab7a6011be75da56e469199021cbc78d /drivers/net/wireless/ath
parentb514fab5a17464adcb31852c6bd6fd775b5dcb4d (diff)
ath6kl: Fix target assert in p2p bringup with multi vif
Using interface 0 for p2p causes target assert. This is because interface 0 is always initialized to non-p2p operations. Fix this issue by initializing all the interfaces for p2p when fw is capable of dynamic interface switching. When fw is not capable of dynamic switching, make sure p2p is not brought up on interface which is not initialized for this purpose. Reported-by: Naveen Singh navesing@qca.qualcomm.com Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c29
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c27
2 files changed, 47 insertions, 9 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 1272508513f7..06f12da554e1 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -1451,9 +1451,38 @@ static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1451 struct vif_params *params) 1451 struct vif_params *params)
1452{ 1452{
1453 struct ath6kl_vif *vif = netdev_priv(ndev); 1453 struct ath6kl_vif *vif = netdev_priv(ndev);
1454 int i;
1454 1455
1455 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type); 1456 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1456 1457
1458 /*
1459 * Don't bring up p2p on an interface which is not initialized
1460 * for p2p operation where fw does not have capability to switch
1461 * dynamically between non-p2p and p2p type interface.
1462 */
1463 if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1464 vif->ar->fw_capabilities) &&
1465 (type == NL80211_IFTYPE_P2P_CLIENT ||
1466 type == NL80211_IFTYPE_P2P_GO)) {
1467 if (vif->ar->vif_max == 1) {
1468 if (vif->fw_vif_idx != 0)
1469 return -EINVAL;
1470 else
1471 goto set_iface_type;
1472 }
1473
1474 for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1475 if (i == vif->fw_vif_idx)
1476 break;
1477 }
1478
1479 if (i == vif->ar->vif_max) {
1480 ath6kl_err("Invalid interface to bring up P2P\n");
1481 return -EINVAL;
1482 }
1483 }
1484
1485set_iface_type:
1457 switch (type) { 1486 switch (type) {
1458 case NL80211_IFTYPE_STATION: 1487 case NL80211_IFTYPE_STATION:
1459 vif->next_mode = INFRA_NETWORK; 1488 vif->next_mode = INFRA_NETWORK;
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 5949ab5357fd..edd778888aa0 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -488,22 +488,31 @@ int ath6kl_configure_target(struct ath6kl *ar)
488 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS); 488 fw_mode |= fw_iftype << (i * HI_OPTION_FW_MODE_BITS);
489 489
490 /* 490 /*
491 * By default, submodes : 491 * Submodes when fw does not support dynamic interface
492 * switching:
492 * vif[0] - AP/STA/IBSS 493 * vif[0] - AP/STA/IBSS
493 * vif[1] - "P2P dev"/"P2P GO"/"P2P Client" 494 * vif[1] - "P2P dev"/"P2P GO"/"P2P Client"
494 * vif[2] - "P2P dev"/"P2P GO"/"P2P Client" 495 * vif[2] - "P2P dev"/"P2P GO"/"P2P Client"
496 * Otherwise, All the interface are initialized to p2p dev.
495 */ 497 */
496 498
497 for (i = 0; i < ar->max_norm_iface; i++) 499 if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
498 fw_submode |= HI_OPTION_FW_SUBMODE_NONE << 500 ar->fw_capabilities)) {
499 (i * HI_OPTION_FW_SUBMODE_BITS); 501 for (i = 0; i < ar->vif_max; i++)
502 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
503 (i * HI_OPTION_FW_SUBMODE_BITS);
504 } else {
505 for (i = 0; i < ar->max_norm_iface; i++)
506 fw_submode |= HI_OPTION_FW_SUBMODE_NONE <<
507 (i * HI_OPTION_FW_SUBMODE_BITS);
500 508
501 for (i = ar->max_norm_iface; i < ar->vif_max; i++) 509 for (i = ar->max_norm_iface; i < ar->vif_max; i++)
502 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV << 510 fw_submode |= HI_OPTION_FW_SUBMODE_P2PDEV <<
503 (i * HI_OPTION_FW_SUBMODE_BITS); 511 (i * HI_OPTION_FW_SUBMODE_BITS);
504 512
505 if (ar->p2p && ar->vif_max == 1) 513 if (ar->p2p && ar->vif_max == 1)
506 fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV; 514 fw_submode = HI_OPTION_FW_SUBMODE_P2PDEV;
515 }
507 516
508 if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest, 517 if (ath6kl_bmi_write_hi32(ar, hi_app_host_interest,
509 HTC_PROTOCOL_VERSION) != 0) { 518 HTC_PROTOCOL_VERSION) != 0) {