rsi: add/remove interface enhancements for p2p

STA_OPMODE and AP_OPMODE macros are renamed to RSI_OPMODE_STA
and RSI_OPMODE_AP. New opmodes are added to this list for P2P
support. Mapping of mac80211 interface types to rsi interface
types are added.
Add and remove interface callbacks are handled for P2P mode.

Signed-off-by: Prameela Rani Garnepudi <prameela.j04cs@gmail.com>
Signed-off-by: Amitkumar Karwar <amit.karwar@redpinesignals.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
This commit is contained in:
Prameela Rani Garnepudi 2017-08-30 15:08:22 +05:30 committed by Kalle Valo
parent 421eedff11
commit b8bd3a439f
4 changed files with 89 additions and 55 deletions

View File

@ -355,6 +355,24 @@ static void rsi_mac80211_stop(struct ieee80211_hw *hw)
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
} }
static int rsi_map_intf_mode(enum nl80211_iftype vif_type)
{
switch (vif_type) {
case NL80211_IFTYPE_STATION:
return RSI_OPMODE_STA;
case NL80211_IFTYPE_AP:
return RSI_OPMODE_AP;
case NL80211_IFTYPE_P2P_DEVICE:
return RSI_OPMODE_P2P_CLIENT;
case NL80211_IFTYPE_P2P_CLIENT:
return RSI_OPMODE_P2P_CLIENT;
case NL80211_IFTYPE_P2P_GO:
return RSI_OPMODE_P2P_GO;
default:
return RSI_OPMODE_UNSUPPORTED;
}
}
/** /**
* rsi_mac80211_add_interface() - This function is called when a netdevice * rsi_mac80211_add_interface() - This function is called when a netdevice
* attached to the hardware is enabled. * attached to the hardware is enabled.
@ -368,54 +386,62 @@ static int rsi_mac80211_add_interface(struct ieee80211_hw *hw,
{ {
struct rsi_hw *adapter = hw->priv; struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv; struct rsi_common *common = adapter->priv;
struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv;
enum opmode intf_mode; enum opmode intf_mode;
int ret = -EOPNOTSUPP; enum vap_status vap_status;
int vap_idx = -1, i;
vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD; vif->driver_flags |= IEEE80211_VIF_SUPPORTS_UAPSD;
mutex_lock(&common->mutex); mutex_lock(&common->mutex);
if (adapter->sc_nvifs > 1) { intf_mode = rsi_map_intf_mode(vif->type);
mutex_unlock(&common->mutex); if (intf_mode == RSI_OPMODE_UNSUPPORTED) {
return -EOPNOTSUPP;
}
switch (vif->type) {
case NL80211_IFTYPE_STATION:
rsi_dbg(INFO_ZONE, "Station Mode");
intf_mode = STA_OPMODE;
break;
case NL80211_IFTYPE_AP:
rsi_dbg(INFO_ZONE, "AP Mode");
intf_mode = AP_OPMODE;
break;
default:
rsi_dbg(ERR_ZONE, rsi_dbg(ERR_ZONE,
"%s: Interface type %d not supported\n", __func__, "%s: Interface type %d not supported\n", __func__,
vif->type); vif->type);
goto out; mutex_unlock(&common->mutex);
return -EOPNOTSUPP;
} }
if ((vif->type == NL80211_IFTYPE_P2P_DEVICE) ||
(vif->type == NL80211_IFTYPE_P2P_CLIENT) ||
(vif->type == NL80211_IFTYPE_P2P_GO))
common->p2p_enabled = true;
adapter->vifs[adapter->sc_nvifs++] = vif; /* Get free vap index */
ret = rsi_set_vap_capabilities(common, intf_mode, common->mac_addr, for (i = 0; i < RSI_MAX_VIFS; i++) {
0, VAP_ADD); if (!adapter->vifs[i]) {
if (ret) { vap_idx = i;
break;
}
}
if (vap_idx < 0) {
rsi_dbg(ERR_ZONE, "Reject: Max VAPs reached\n");
mutex_unlock(&common->mutex);
return -EOPNOTSUPP;
}
vif_info->vap_id = vap_idx;
adapter->vifs[vap_idx] = vif;
adapter->sc_nvifs++;
vap_status = VAP_ADD;
if (rsi_set_vap_capabilities(common, intf_mode, vif->addr,
vif_info->vap_id, vap_status)) {
rsi_dbg(ERR_ZONE, "Failed to set VAP capabilities\n"); rsi_dbg(ERR_ZONE, "Failed to set VAP capabilities\n");
goto out; mutex_unlock(&common->mutex);
return -EINVAL;
} }
if (vif->type == NL80211_IFTYPE_AP) { if ((vif->type == NL80211_IFTYPE_AP) ||
int i; (vif->type == NL80211_IFTYPE_P2P_GO)) {
rsi_send_rx_filter_frame(common, DISALLOW_BEACONS); rsi_send_rx_filter_frame(common, DISALLOW_BEACONS);
common->min_rate = RSI_RATE_AUTO; common->min_rate = RSI_RATE_AUTO;
for (i = 0; i < common->max_stations; i++) for (i = 0; i < common->max_stations; i++)
common->stations[i].sta = NULL; common->stations[i].sta = NULL;
} }
out:
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
return ret; return 0;
} }
/** /**
@ -432,6 +458,7 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
struct rsi_hw *adapter = hw->priv; struct rsi_hw *adapter = hw->priv;
struct rsi_common *common = adapter->priv; struct rsi_common *common = adapter->priv;
enum opmode opmode; enum opmode opmode;
int i;
rsi_dbg(INFO_ZONE, "Remove Interface Called\n"); rsi_dbg(INFO_ZONE, "Remove Interface Called\n");
@ -442,23 +469,22 @@ static void rsi_mac80211_remove_interface(struct ieee80211_hw *hw,
return; return;
} }
switch (vif->type) { opmode = rsi_map_intf_mode(vif->type);
case NL80211_IFTYPE_STATION: if (opmode == RSI_OPMODE_UNSUPPORTED) {
opmode = STA_OPMODE; rsi_dbg(ERR_ZONE, "Opmode error : %d\n", opmode);
break;
case NL80211_IFTYPE_AP:
opmode = AP_OPMODE;
break;
default:
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
return; return;
} }
rsi_set_vap_capabilities(common, opmode, vif->addr, for (i = 0; i < RSI_MAX_VIFS; i++) {
0, VAP_DELETE); if (!adapter->vifs[i])
adapter->sc_nvifs--; continue;
if (vif == adapter->vifs[i]) {
if (!memcmp(adapter->vifs[0], vif, sizeof(struct ieee80211_vif))) rsi_set_vap_capabilities(common, opmode, vif->addr,
adapter->vifs[0] = NULL; i, VAP_DELETE);
adapter->sc_nvifs--;
adapter->vifs[i] = NULL;
}
}
mutex_unlock(&common->mutex); mutex_unlock(&common->mutex);
} }
@ -652,7 +678,7 @@ static void rsi_mac80211_bss_info_changed(struct ieee80211_hw *hw,
rsi_send_rx_filter_frame(common, rx_filter_word); rsi_send_rx_filter_frame(common, rx_filter_word);
} }
rsi_inform_bss_status(common, rsi_inform_bss_status(common,
STA_OPMODE, RSI_OPMODE_STA,
bss_conf->assoc, bss_conf->assoc,
bss_conf->bssid, bss_conf->bssid,
bss_conf->qos, bss_conf->qos,
@ -1285,8 +1311,9 @@ static int rsi_mac80211_sta_add(struct ieee80211_hw *hw,
/* Send peer notify to device */ /* Send peer notify to device */
rsi_dbg(INFO_ZONE, "Indicate bss status to device\n"); rsi_dbg(INFO_ZONE, "Indicate bss status to device\n");
rsi_inform_bss_status(common, AP_OPMODE, 1, sta->addr, rsi_inform_bss_status(common, RSI_OPMODE_AP, 1,
sta->wme, sta->aid, sta, sta_idx); sta->addr, sta->wme, sta->aid,
sta, sta_idx);
if (common->key) { if (common->key) {
struct ieee80211_key_conf *key = common->key; struct ieee80211_key_conf *key = common->key;
@ -1358,7 +1385,7 @@ static int rsi_mac80211_sta_remove(struct ieee80211_hw *hw,
if (!rsta->sta) if (!rsta->sta)
continue; continue;
if (!memcmp(rsta->sta->addr, sta->addr, ETH_ALEN)) { if (!memcmp(rsta->sta->addr, sta->addr, ETH_ALEN)) {
rsi_inform_bss_status(common, AP_OPMODE, 0, rsi_inform_bss_status(common, RSI_OPMODE_AP, 0,
sta->addr, sta->wme, sta->addr, sta->wme,
sta->aid, sta, sta_idx); sta->aid, sta, sta_idx);
rsta->sta = NULL; rsta->sta = NULL;

View File

@ -482,9 +482,9 @@ static int rsi_hal_send_sta_notify_frame(struct rsi_common *common,
memset(skb->data, 0, frame_len); memset(skb->data, 0, frame_len);
peer_notify = (struct rsi_peer_notify *)skb->data; peer_notify = (struct rsi_peer_notify *)skb->data;
if (opmode == STA_OPMODE) if (opmode == RSI_OPMODE_STA)
peer_notify->command = cpu_to_le16(PEER_TYPE_AP << 1); peer_notify->command = cpu_to_le16(PEER_TYPE_AP << 1);
else if (opmode == AP_OPMODE) else if (opmode == RSI_OPMODE_AP)
peer_notify->command = cpu_to_le16(PEER_TYPE_STA << 1); peer_notify->command = cpu_to_le16(PEER_TYPE_STA << 1);
switch (notify_event) { switch (notify_event) {
@ -1321,7 +1321,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
u16 sta_id) u16 sta_id)
{ {
if (status) { if (status) {
if (opmode == STA_OPMODE) if (opmode == RSI_OPMODE_STA)
common->hw_data_qs_blocked = true; common->hw_data_qs_blocked = true;
rsi_hal_send_sta_notify_frame(common, rsi_hal_send_sta_notify_frame(common,
opmode, opmode,
@ -1331,12 +1331,12 @@ void rsi_inform_bss_status(struct rsi_common *common,
aid, sta_id); aid, sta_id);
if (common->min_rate == 0xffff) if (common->min_rate == 0xffff)
rsi_send_auto_rate_request(common, sta, sta_id); rsi_send_auto_rate_request(common, sta, sta_id);
if (opmode == STA_OPMODE) { if (opmode == RSI_OPMODE_STA) {
if (!rsi_send_block_unblock_frame(common, false)) if (!rsi_send_block_unblock_frame(common, false))
common->hw_data_qs_blocked = false; common->hw_data_qs_blocked = false;
} }
} else { } else {
if (opmode == STA_OPMODE) if (opmode == RSI_OPMODE_STA)
common->hw_data_qs_blocked = true; common->hw_data_qs_blocked = true;
rsi_hal_send_sta_notify_frame(common, rsi_hal_send_sta_notify_frame(common,
opmode, opmode,
@ -1344,7 +1344,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
addr, addr,
qos_enable, qos_enable,
aid, sta_id); aid, sta_id);
if (opmode == STA_OPMODE) if (opmode == RSI_OPMODE_STA)
rsi_send_block_unblock_frame(common, true); rsi_send_block_unblock_frame(common, true);
} }
} }

View File

@ -60,7 +60,7 @@ enum RSI_FSM_STATES {
extern u32 rsi_zone_enabled; extern u32 rsi_zone_enabled;
extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...); extern __printf(2, 3) void rsi_dbg(u32 zone, const char *fmt, ...);
#define RSI_MAX_VIFS 1 #define RSI_MAX_VIFS 3
#define NUM_EDCA_QUEUES 4 #define NUM_EDCA_QUEUES 4
#define IEEE80211_ADDR_LEN 6 #define IEEE80211_ADDR_LEN 6
#define FRAME_DESC_SZ 16 #define FRAME_DESC_SZ 16
@ -157,6 +157,7 @@ struct vif_priv {
bool is_ht; bool is_ht;
bool sgi; bool sgi;
u16 seq_start; u16 seq_start;
int vap_id;
}; };
struct rsi_event { struct rsi_event {
@ -270,6 +271,9 @@ struct rsi_common {
int num_stations; int num_stations;
int max_stations; int max_stations;
struct ieee80211_key_conf *key; struct ieee80211_key_conf *key;
/* Wi-Fi direct mode related */
bool p2p_enabled;
}; };
enum host_intf { enum host_intf {

View File

@ -200,8 +200,11 @@
#define RSI_DATA_DESC_INSERT_SEQ_NO BIT(2) #define RSI_DATA_DESC_INSERT_SEQ_NO BIT(2)
enum opmode { enum opmode {
AP_OPMODE = 0, RSI_OPMODE_UNSUPPORTED = -1,
STA_OPMODE, RSI_OPMODE_AP = 0,
RSI_OPMODE_STA,
RSI_OPMODE_P2P_GO,
RSI_OPMODE_P2P_CLIENT
}; };
enum vap_status { enum vap_status {
@ -363,9 +366,9 @@ struct rsi_vap_caps {
u8 vif_type; u8 vif_type;
u8 channel_bw; u8 channel_bw;
__le16 antenna_info; __le16 antenna_info;
__le16 token;
u8 radioid_macid; u8 radioid_macid;
u8 vap_id; u8 vap_id;
__le16 reserved3;
u8 mac_addr[6]; u8 mac_addr[6];
__le16 keep_alive_period; __le16 keep_alive_period;
u8 bssid[6]; u8 bssid[6];