diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath6kl/wmi.c')
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 148 |
1 files changed, 145 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index ee8ec2394c2c..a6caa673e8ad 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c | |||
@@ -743,7 +743,6 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) | |||
743 | return -ENOMEM; | 743 | return -ENOMEM; |
744 | 744 | ||
745 | cmd = (struct roam_ctrl_cmd *) skb->data; | 745 | cmd = (struct roam_ctrl_cmd *) skb->data; |
746 | memset(cmd, 0, sizeof(*cmd)); | ||
747 | 746 | ||
748 | memcpy(cmd->info.bssid, bssid, ETH_ALEN); | 747 | memcpy(cmd->info.bssid, bssid, ETH_ALEN); |
749 | cmd->roam_ctrl = WMI_FORCE_ROAM; | 748 | cmd->roam_ctrl = WMI_FORCE_ROAM; |
@@ -753,6 +752,22 @@ int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid) | |||
753 | NO_SYNC_WMIFLAG); | 752 | NO_SYNC_WMIFLAG); |
754 | } | 753 | } |
755 | 754 | ||
755 | int ath6kl_wmi_ap_set_dtim_cmd(struct wmi *wmi, u8 if_idx, u32 dtim_period) | ||
756 | { | ||
757 | struct sk_buff *skb; | ||
758 | struct set_dtim_cmd *cmd; | ||
759 | |||
760 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
761 | if (!skb) | ||
762 | return -ENOMEM; | ||
763 | |||
764 | cmd = (struct set_dtim_cmd *) skb->data; | ||
765 | |||
766 | cmd->dtim_period = cpu_to_le32(dtim_period); | ||
767 | return ath6kl_wmi_cmd_send(wmi, if_idx, skb, | ||
768 | WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG); | ||
769 | } | ||
770 | |||
756 | int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) | 771 | int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) |
757 | { | 772 | { |
758 | struct sk_buff *skb; | 773 | struct sk_buff *skb; |
@@ -763,7 +778,6 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode) | |||
763 | return -ENOMEM; | 778 | return -ENOMEM; |
764 | 779 | ||
765 | cmd = (struct roam_ctrl_cmd *) skb->data; | 780 | cmd = (struct roam_ctrl_cmd *) skb->data; |
766 | memset(cmd, 0, sizeof(*cmd)); | ||
767 | 781 | ||
768 | cmd->info.roam_mode = mode; | 782 | cmd->info.roam_mode = mode; |
769 | cmd->roam_ctrl = WMI_SET_ROAM_MODE; | 783 | cmd->roam_ctrl = WMI_SET_ROAM_MODE; |
@@ -1995,7 +2009,7 @@ int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 if_idx, u8 index, u8 flag, | |||
1995 | struct wmi_probed_ssid_cmd *cmd; | 2009 | struct wmi_probed_ssid_cmd *cmd; |
1996 | int ret; | 2010 | int ret; |
1997 | 2011 | ||
1998 | if (index > MAX_PROBED_SSID_INDEX) | 2012 | if (index >= MAX_PROBED_SSIDS) |
1999 | return -EINVAL; | 2013 | return -EINVAL; |
2000 | 2014 | ||
2001 | if (ssid_len > sizeof(cmd->ssid)) | 2015 | if (ssid_len > sizeof(cmd->ssid)) |
@@ -2599,6 +2613,115 @@ static void ath6kl_wmi_relinquish_implicit_pstream_credits(struct wmi *wmi) | |||
2599 | spin_unlock_bh(&wmi->lock); | 2613 | spin_unlock_bh(&wmi->lock); |
2600 | } | 2614 | } |
2601 | 2615 | ||
2616 | static int ath6kl_set_bitrate_mask64(struct wmi *wmi, u8 if_idx, | ||
2617 | const struct cfg80211_bitrate_mask *mask) | ||
2618 | { | ||
2619 | struct sk_buff *skb; | ||
2620 | int ret, mode, band; | ||
2621 | u64 mcsrate, ratemask[IEEE80211_NUM_BANDS]; | ||
2622 | struct wmi_set_tx_select_rates64_cmd *cmd; | ||
2623 | |||
2624 | memset(&ratemask, 0, sizeof(ratemask)); | ||
2625 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
2626 | /* copy legacy rate mask */ | ||
2627 | ratemask[band] = mask->control[band].legacy; | ||
2628 | if (band == IEEE80211_BAND_5GHZ) | ||
2629 | ratemask[band] = | ||
2630 | mask->control[band].legacy << 4; | ||
2631 | |||
2632 | /* copy mcs rate mask */ | ||
2633 | mcsrate = mask->control[band].mcs[1]; | ||
2634 | mcsrate <<= 8; | ||
2635 | mcsrate |= mask->control[band].mcs[0]; | ||
2636 | ratemask[band] |= mcsrate << 12; | ||
2637 | ratemask[band] |= mcsrate << 28; | ||
2638 | } | ||
2639 | |||
2640 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
2641 | "Ratemask 64 bit: 2.4:%llx 5:%llx\n", | ||
2642 | ratemask[0], ratemask[1]); | ||
2643 | |||
2644 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); | ||
2645 | if (!skb) | ||
2646 | return -ENOMEM; | ||
2647 | |||
2648 | cmd = (struct wmi_set_tx_select_rates64_cmd *) skb->data; | ||
2649 | for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { | ||
2650 | /* A mode operate in 5GHZ band */ | ||
2651 | if (mode == WMI_RATES_MODE_11A || | ||
2652 | mode == WMI_RATES_MODE_11A_HT20 || | ||
2653 | mode == WMI_RATES_MODE_11A_HT40) | ||
2654 | band = IEEE80211_BAND_5GHZ; | ||
2655 | else | ||
2656 | band = IEEE80211_BAND_2GHZ; | ||
2657 | cmd->ratemask[mode] = cpu_to_le64(ratemask[band]); | ||
2658 | } | ||
2659 | |||
2660 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, | ||
2661 | WMI_SET_TX_SELECT_RATES_CMDID, | ||
2662 | NO_SYNC_WMIFLAG); | ||
2663 | return ret; | ||
2664 | } | ||
2665 | |||
2666 | static int ath6kl_set_bitrate_mask32(struct wmi *wmi, u8 if_idx, | ||
2667 | const struct cfg80211_bitrate_mask *mask) | ||
2668 | { | ||
2669 | struct sk_buff *skb; | ||
2670 | int ret, mode, band; | ||
2671 | u32 mcsrate, ratemask[IEEE80211_NUM_BANDS]; | ||
2672 | struct wmi_set_tx_select_rates32_cmd *cmd; | ||
2673 | |||
2674 | memset(&ratemask, 0, sizeof(ratemask)); | ||
2675 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | ||
2676 | /* copy legacy rate mask */ | ||
2677 | ratemask[band] = mask->control[band].legacy; | ||
2678 | if (band == IEEE80211_BAND_5GHZ) | ||
2679 | ratemask[band] = | ||
2680 | mask->control[band].legacy << 4; | ||
2681 | |||
2682 | /* copy mcs rate mask */ | ||
2683 | mcsrate = mask->control[band].mcs[0]; | ||
2684 | ratemask[band] |= mcsrate << 12; | ||
2685 | ratemask[band] |= mcsrate << 20; | ||
2686 | } | ||
2687 | |||
2688 | ath6kl_dbg(ATH6KL_DBG_WMI, | ||
2689 | "Ratemask 32 bit: 2.4:%x 5:%x\n", | ||
2690 | ratemask[0], ratemask[1]); | ||
2691 | |||
2692 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd) * WMI_RATES_MODE_MAX); | ||
2693 | if (!skb) | ||
2694 | return -ENOMEM; | ||
2695 | |||
2696 | cmd = (struct wmi_set_tx_select_rates32_cmd *) skb->data; | ||
2697 | for (mode = 0; mode < WMI_RATES_MODE_MAX; mode++) { | ||
2698 | /* A mode operate in 5GHZ band */ | ||
2699 | if (mode == WMI_RATES_MODE_11A || | ||
2700 | mode == WMI_RATES_MODE_11A_HT20 || | ||
2701 | mode == WMI_RATES_MODE_11A_HT40) | ||
2702 | band = IEEE80211_BAND_5GHZ; | ||
2703 | else | ||
2704 | band = IEEE80211_BAND_2GHZ; | ||
2705 | cmd->ratemask[mode] = cpu_to_le32(ratemask[band]); | ||
2706 | } | ||
2707 | |||
2708 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, | ||
2709 | WMI_SET_TX_SELECT_RATES_CMDID, | ||
2710 | NO_SYNC_WMIFLAG); | ||
2711 | return ret; | ||
2712 | } | ||
2713 | |||
2714 | int ath6kl_wmi_set_bitrate_mask(struct wmi *wmi, u8 if_idx, | ||
2715 | const struct cfg80211_bitrate_mask *mask) | ||
2716 | { | ||
2717 | struct ath6kl *ar = wmi->parent_dev; | ||
2718 | |||
2719 | if (ar->hw.flags & ATH6KL_HW_FLAG_64BIT_RATES) | ||
2720 | return ath6kl_set_bitrate_mask64(wmi, if_idx, mask); | ||
2721 | else | ||
2722 | return ath6kl_set_bitrate_mask32(wmi, if_idx, mask); | ||
2723 | } | ||
2724 | |||
2602 | int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, | 2725 | int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, |
2603 | enum ath6kl_host_mode host_mode) | 2726 | enum ath6kl_host_mode host_mode) |
2604 | { | 2727 | { |
@@ -2997,6 +3120,25 @@ int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, | |||
2997 | return ret; | 3120 | return ret; |
2998 | } | 3121 | } |
2999 | 3122 | ||
3123 | int ath6kl_wmi_sta_bmiss_enhance_cmd(struct wmi *wmi, u8 if_idx, bool enhance) | ||
3124 | { | ||
3125 | struct sk_buff *skb; | ||
3126 | struct wmi_sta_bmiss_enhance_cmd *cmd; | ||
3127 | int ret; | ||
3128 | |||
3129 | skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); | ||
3130 | if (!skb) | ||
3131 | return -ENOMEM; | ||
3132 | |||
3133 | cmd = (struct wmi_sta_bmiss_enhance_cmd *) skb->data; | ||
3134 | cmd->enable = enhance ? 1 : 0; | ||
3135 | |||
3136 | ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, | ||
3137 | WMI_STA_BMISS_ENHANCE_CMDID, | ||
3138 | NO_SYNC_WMIFLAG); | ||
3139 | return ret; | ||
3140 | } | ||
3141 | |||
3000 | s32 ath6kl_wmi_get_rate(s8 rate_index) | 3142 | s32 ath6kl_wmi_get_rate(s8 rate_index) |
3001 | { | 3143 | { |
3002 | if (rate_index == RATE_AUTO) | 3144 | if (rate_index == RATE_AUTO) |