summaryrefslogtreecommitdiff
path: root/drivers/staging/cw1200/ap.c
diff options
context:
space:
mode:
authorAmit Shakya <amit.shakya@stericsson.com>2011-09-21 14:41:58 +0530
committerPhilippe LANGLAIS <philippe.langlais@stericsson.com>2011-10-13 10:18:33 +0200
commitafa3d7b12a74b0583e5c46f8a4d889a2086691ff (patch)
treef55225b1c4766938e15962684b760fa5fa0a5cb4 /drivers/staging/cw1200/ap.c
parentb4fc8cc9749880779001b76c43fc8b90ca71a6b1 (diff)
cw1200: Add BT Coexistence support
BT Coexistence support required setting priority to frames for PTA arbitration FW, parsing SDD file for getting the listen interval and using the same in assoc request, modifying Tx rate for PSPOLL and NULL templates (plumbing them) ST-Ericsson ID: 357776 ST-Ericsson FOSS-OUT ID: STETL-FOSS-OUT-10091 Change-Id: I14f05cbcc2f02b85f72dbe820893cef9c3775df7 Signed-off-by: Amit Shakya <amit.shakya@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/31602 Reviewed-by: Bartosz MARKOWSKI <bartosz.markowski@tieto.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/33528 Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com> Tested-by: Dmitry TARNYAGIN <dmitry.tarnyagin@stericsson.com>
Diffstat (limited to 'drivers/staging/cw1200/ap.c')
-rwxr-xr-xdrivers/staging/cw1200/ap.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/drivers/staging/cw1200/ap.c b/drivers/staging/cw1200/ap.c
index 494403dd28d..aabca5ca06e 100755
--- a/drivers/staging/cw1200/ap.c
+++ b/drivers/staging/cw1200/ap.c
@@ -23,6 +23,8 @@
#define CW1200_LINK_ID_GC_TIMEOUT ((unsigned long)(10 * HZ))
static int cw1200_upload_beacon(struct cw1200_common *priv);
+static int cw1200_upload_pspoll(struct cw1200_common *priv);
+static int cw1200_upload_null(struct cw1200_common *priv);
static int cw1200_start_ap(struct cw1200_common *priv);
static int cw1200_update_beaconing(struct cw1200_common *priv);
static int cw1200_enable_beaconing(struct cw1200_common *priv,
@@ -195,6 +197,56 @@ int cw1200_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
return 0;
}
+static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
+{
+ struct wsm_override_internal_txrate arg;
+ int ret = 0;
+
+ if (priv->mode == NL80211_IFTYPE_STATION) {
+ /* Plumb PSPOLL and NULL template */
+ WARN_ON(cw1200_upload_pspoll(priv));
+ WARN_ON(cw1200_upload_null(priv));
+ } else {
+ return 0;
+ }
+
+ memset(&arg, 0, sizeof(struct wsm_override_internal_txrate));
+
+ if (!priv->vif->p2p) {
+ /* STATION mode */
+ if (priv->bss_params.operationalRateSet & ~0xF) {
+ ap_printk(KERN_DEBUG "[STA] STA has ERP rates\n");
+ /* G or BG mode */
+ arg.internalTxRate = (__ffs(
+ priv->bss_params.operationalRateSet & ~0xF));
+ } else {
+ ap_printk(KERN_DEBUG "[STA] STA has non ERP rates\n");
+ /* B only mode */
+ arg.internalTxRate = (__ffs(
+ priv->association_mode.basicRateSet));
+ }
+ arg.nonErpInternalTxRate = (__ffs(
+ priv->association_mode.basicRateSet));
+ } else {
+ /* P2P mode */
+ arg.internalTxRate = (__ffs(
+ priv->bss_params.operationalRateSet & ~0xF));
+ arg.nonErpInternalTxRate = (__ffs(
+ priv->bss_params.operationalRateSet & ~0xF));
+ }
+
+ ap_printk(KERN_DEBUG "[STA] BTCOEX_INFO"
+ "MODE %d, internalTxRate : %x, nonErpInternalTxRate: %x\n",
+ priv->mode,
+ arg.internalTxRate,
+ arg.nonErpInternalTxRate);
+
+ ret = WARN_ON(wsm_write_mib(priv, WSM_MIB_ID_OVERRIDE_INTERNAL_TX_RATE,
+ &arg, sizeof(arg)));
+
+ return ret;
+}
+
void cw1200_bss_info_changed(struct ieee80211_hw *dev,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *info,
@@ -389,6 +441,9 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
WARN_ON(wsm_set_beacon_wakeup_period(priv,
dtim_interval, listen_interval));
cw1200_set_pm(priv, &priv->powersave_mode);
+
+ if (priv->is_BT_Present)
+ WARN_ON(cw1200_set_btcoexinfo(priv));
#if 0
/* It's better to override internal TX rete; otherwise
* device sends RTS at too high rate. However device
@@ -683,6 +738,46 @@ static int cw1200_upload_beacon(struct cw1200_common *priv)
return ret;
}
+static int cw1200_upload_pspoll(struct cw1200_common *priv)
+{
+ int ret = 0;
+ struct wsm_template_frame frame = {
+ .frame_type = WSM_FRAME_TYPE_PS_POLL,
+ .rate = 0xFF,
+ };
+
+
+ frame.skb = ieee80211_pspoll_get(priv->hw, priv->vif);
+ if (WARN_ON(!frame.skb))
+ return -ENOMEM;
+
+ ret = wsm_set_template_frame(priv, &frame);
+
+ dev_kfree_skb(frame.skb);
+
+ return ret;
+}
+
+static int cw1200_upload_null(struct cw1200_common *priv)
+{
+ int ret = 0;
+ struct wsm_template_frame frame = {
+ .frame_type = WSM_FRAME_TYPE_NULL,
+ .rate = 0xFF,
+ };
+
+
+ frame.skb = ieee80211_nullfunc_get(priv->hw, priv->vif);
+ if (WARN_ON(!frame.skb))
+ return -ENOMEM;
+
+ ret = wsm_set_template_frame(priv, &frame);
+
+ dev_kfree_skb(frame.skb);
+
+ return ret;
+}
+
static int cw1200_enable_beaconing(struct cw1200_common *priv,
bool enable)
{