Commit 5faa1aff authored by Nishant Sarmukadam's avatar Nishant Sarmukadam Committed by John W. Linville

mwl8k: add support for block ack commands

Signed-off-by: default avatarPradeep Nemavat <pnemavat@marvell.com>
Signed-off-by: default avatarBrian Cavagnolo <brian@cozybit.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 8a7a578c
...@@ -135,6 +135,14 @@ struct mwl8k_tx_queue { ...@@ -135,6 +135,14 @@ struct mwl8k_tx_queue {
struct sk_buff **skb; struct sk_buff **skb;
}; };
struct mwl8k_ampdu_stream {
struct ieee80211_sta *sta;
u8 tid;
u8 state;
u8 idx;
u8 txq_idx; /* index of this stream in priv->txq */
};
struct mwl8k_priv { struct mwl8k_priv {
struct ieee80211_hw *hw; struct ieee80211_hw *hw;
struct pci_dev *pdev; struct pci_dev *pdev;
...@@ -360,6 +368,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = { ...@@ -360,6 +368,7 @@ static const struct ieee80211_rate mwl8k_rates_50[] = {
#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */ #define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
#define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */ #define MWL8K_CMD_UPDATE_ENCRYPTION 0x1122 /* per-vif */
#define MWL8K_CMD_UPDATE_STADB 0x1123 #define MWL8K_CMD_UPDATE_STADB 0x1123
#define MWL8K_CMD_BASTREAM 0x1125
static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
{ {
...@@ -399,6 +408,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) ...@@ -399,6 +408,7 @@ static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize)
MWL8K_CMDNAME(SET_NEW_STN); MWL8K_CMDNAME(SET_NEW_STN);
MWL8K_CMDNAME(UPDATE_ENCRYPTION); MWL8K_CMDNAME(UPDATE_ENCRYPTION);
MWL8K_CMDNAME(UPDATE_STADB); MWL8K_CMDNAME(UPDATE_STADB);
MWL8K_CMDNAME(BASTREAM);
default: default:
snprintf(buf, bufsize, "0x%x", cmd); snprintf(buf, bufsize, "0x%x", cmd);
} }
...@@ -3175,6 +3185,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw, ...@@ -3175,6 +3185,152 @@ static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
return rc; return rc;
} }
/*
* CMD_BASTREAM.
*/
/*
* UPSTREAM is tx direction
*/
#define BASTREAM_FLAG_DIRECTION_UPSTREAM 0x00
#define BASTREAM_FLAG_IMMEDIATE_TYPE 0x01
enum {
MWL8K_BA_CREATE,
MWL8K_BA_UPDATE,
MWL8K_BA_DESTROY,
MWL8K_BA_FLUSH,
MWL8K_BA_CHECK,
} ba_stream_action_type;
struct mwl8k_create_ba_stream {
__le32 flags;
__le32 idle_thrs;
__le32 bar_thrs;
__le32 window_size;
u8 peer_mac_addr[6];
u8 dialog_token;
u8 tid;
u8 queue_id;
u8 param_info;
__le32 ba_context;
u8 reset_seq_no_flag;
__le16 curr_seq_no;
u8 sta_src_mac_addr[6];
} __packed;
struct mwl8k_destroy_ba_stream {
__le32 flags;
__le32 ba_context;
} __packed;
struct mwl8k_cmd_bastream {
struct mwl8k_cmd_pkt header;
__le32 action;
union {
struct mwl8k_create_ba_stream create_params;
struct mwl8k_destroy_ba_stream destroy_params;
};
} __packed;
static int
mwl8k_check_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream)
{
struct mwl8k_cmd_bastream *cmd;
int rc;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL)
return -ENOMEM;
cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
cmd->header.length = cpu_to_le16(sizeof(*cmd));
cmd->action = cpu_to_le32(MWL8K_BA_CHECK);
cmd->create_params.queue_id = stream->idx;
memcpy(&cmd->create_params.peer_mac_addr[0], stream->sta->addr,
ETH_ALEN);
cmd->create_params.tid = stream->tid;
cmd->create_params.flags =
cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE) |
cpu_to_le32(BASTREAM_FLAG_DIRECTION_UPSTREAM);
rc = mwl8k_post_cmd(hw, &cmd->header);
kfree(cmd);
return rc;
}
static int
mwl8k_create_ba(struct ieee80211_hw *hw, struct mwl8k_ampdu_stream *stream,
u8 buf_size)
{
struct mwl8k_cmd_bastream *cmd;
int rc;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL)
return -ENOMEM;
cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
cmd->header.length = cpu_to_le16(sizeof(*cmd));
cmd->action = cpu_to_le32(MWL8K_BA_CREATE);
cmd->create_params.bar_thrs = cpu_to_le32((u32)buf_size);
cmd->create_params.window_size = cpu_to_le32((u32)buf_size);
cmd->create_params.queue_id = stream->idx;
memcpy(cmd->create_params.peer_mac_addr, stream->sta->addr, ETH_ALEN);
cmd->create_params.tid = stream->tid;
cmd->create_params.curr_seq_no = cpu_to_le16(0);
cmd->create_params.reset_seq_no_flag = 1;
cmd->create_params.param_info =
(stream->sta->ht_cap.ampdu_factor &
IEEE80211_HT_AMPDU_PARM_FACTOR) |
((stream->sta->ht_cap.ampdu_density << 2) &
IEEE80211_HT_AMPDU_PARM_DENSITY);
cmd->create_params.flags =
cpu_to_le32(BASTREAM_FLAG_IMMEDIATE_TYPE |
BASTREAM_FLAG_DIRECTION_UPSTREAM);
rc = mwl8k_post_cmd(hw, &cmd->header);
wiphy_debug(hw->wiphy, "Created a BA stream for %pM : tid %d\n",
stream->sta->addr, stream->tid);
kfree(cmd);
return rc;
}
static void mwl8k_destroy_ba(struct ieee80211_hw *hw,
struct mwl8k_ampdu_stream *stream)
{
struct mwl8k_cmd_bastream *cmd;
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (cmd == NULL)
return;
cmd->header.code = cpu_to_le16(MWL8K_CMD_BASTREAM);
cmd->header.length = cpu_to_le16(sizeof(*cmd));
cmd->action = cpu_to_le32(MWL8K_BA_DESTROY);
cmd->destroy_params.ba_context = cpu_to_le32(stream->idx);
mwl8k_post_cmd(hw, &cmd->header);
wiphy_debug(hw->wiphy, "Deleted BA stream index %d\n", stream->idx);
kfree(cmd);
}
/* /*
* CMD_SET_NEW_STN. * CMD_SET_NEW_STN.
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment