BigW Consortium Gitlab

Commit f297cd05 by David Clark

Updates after getting ifup/ifdown working

parent d30c8150
......@@ -57,7 +57,7 @@ static __inline size_t mt7697q_get_free_words(const struct mt7697q_spec *qs)
return mt7697q_get_capacity(qs) - mt7697q_get_num_words(qs);
}
static int mt7697q_send_init(u8 tx_ch, u8 rx_ch, struct mt7697q_spec *qs)
static int mt7697q_wr_init(u8 tx_ch, u8 rx_ch, struct mt7697q_spec *qs)
{
struct mt7697_queue_init_req req;
int ret;
......@@ -279,11 +279,6 @@ static int mt7697q_proc_queue_rsp(struct mt7697q_spec *qs)
__func__);
break;
case MT7697_CMD_QUEUE_UNUSED_RSP:
dev_dbg(qs->qinfo->dev, "%s(): --> QUEUE UNUSED RSP\n",
__func__);
break;
case MT7697_CMD_QUEUE_RESET_RSP:
dev_dbg(qs->qinfo->dev, "%s(): --> QUEUE RESET RSP\n",
__func__);
......@@ -445,7 +440,45 @@ cleanup:
return ret;
}
int mt7697q_send_reset(void *tx_hndl, void* rx_hndl)
int mt7697q_wr_unused(void *tx_hndl, void* rx_hndl)
{
struct mt7697q_spec *qsM2S = (struct mt7697q_spec*)tx_hndl;
struct mt7697q_spec *qsS2M = (struct mt7697q_spec*)rx_hndl;
struct mt7697_queue_reset_req req;
int ret;
req.cmd.len = sizeof(struct mt7697_queue_reset_req);
req.cmd.grp = MT7697_CMD_GRP_QUEUE;
req.cmd.type = MT7697_CMD_QUEUE_UNUSED;
req.m2s_ch = qsM2S->ch;
req.s2m_ch = qsS2M->ch;
qsM2S->data.flags &= ~BF_GET(qsM2S->data.flags, MT7697_QUEUE_FLAGS_IN_USE_OFFSET,
MT7697_QUEUE_FLAGS_IN_USE_WIDTH);
qsS2M->data.flags &= ~BF_GET(qsS2M->data.flags, MT7697_QUEUE_FLAGS_IN_USE_OFFSET,
MT7697_QUEUE_FLAGS_IN_USE_WIDTH);
dev_dbg(qsM2S->qinfo->dev, "%s(): <-- QUEUE UNUSED(%u/%u)\n",
__func__, req.m2s_ch, req.s2m_ch);
ret = mt7697q_write(qsM2S, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
dev_err(qsM2S->qinfo->dev,
"%s(): mt7697q_write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.cmd.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
EXPORT_SYMBOL(mt7697q_wr_unused);
int mt7697q_wr_reset(void *tx_hndl, void* rx_hndl)
{
struct mt7697q_spec *qsM2S = (struct mt7697q_spec*)tx_hndl;
struct mt7697q_spec *qsS2M = (struct mt7697q_spec*)rx_hndl;
......@@ -476,7 +509,7 @@ cleanup:
return ret;
}
EXPORT_SYMBOL(mt7697q_send_reset);
EXPORT_SYMBOL(mt7697q_wr_reset);
int mt7697q_init(u8 tx_ch, u8 rx_ch, void *priv, rx_hndlr rx_fcn,
void** tx_hndl, void** rx_hndl)
......@@ -573,9 +606,9 @@ int mt7697q_init(u8 tx_ch, u8 rx_ch, void *priv, rx_hndlr rx_fcn,
qsRx->data.flags |= BF_DEFINE(1, MT7697_QUEUE_FLAGS_IN_USE_OFFSET,
MT7697_QUEUE_FLAGS_IN_USE_WIDTH);
ret = mt7697q_send_init(tx_ch, rx_ch, qsTx);
ret = mt7697q_wr_init(tx_ch, rx_ch, qsTx);
if (ret < 0) {
dev_err(qinfo->dev, "%s(): mt7697q_send_init() failed(%d)\n",
dev_err(qinfo->dev, "%s(): mt7697q_wr_init() failed(%d)\n",
__func__, ret);
goto cleanup;
}
......
......@@ -23,7 +23,6 @@
((x) % sizeof(u32) ? 1:0))
#define mt7697_queue_init_rsp mt7697q_rsp_hdr
#define mt7697_queue_unused_rsp mt7697q_rsp_hdr
#define mt7697_queue_reset_rsp mt7697q_rsp_hdr
enum mt7697q_dir
......@@ -42,7 +41,6 @@ enum mt7697q_cmd_types {
MT7697_CMD_QUEUE_INIT = 0,
MT7697_CMD_QUEUE_INIT_RSP,
MT7697_CMD_QUEUE_UNUSED,
MT7697_CMD_QUEUE_UNUSED_RSP,
MT7697_CMD_QUEUE_RESET,
MT7697_CMD_QUEUE_RESET_RSP,
};
......@@ -91,9 +89,9 @@ u32 mt7697q_flags_get_in_use(u32);
u32 mt7697q_flags_get_dir(u32);
int mt7697q_init(u8, u8, void*, rx_hndlr, void**, void**);
int mt7697q_wr_reset(void*, void*);
int mt7697q_wr_unused(void*, void*);
size_t mt7697q_read(void*, u32*, size_t);
size_t mt7697q_write(void*, const u32*, size_t);
int mt7697q_send_reset(void*, void*);
#endif
......@@ -152,59 +152,101 @@ static const u32 mt7697_cipher_suites[] = {
WLAN_CIPHER_SUITE_AES_CMAC,
};
static int mt7697_cfg80211_vif_stop(struct mt7697_vif *vif, bool wmi_ready)
static int mt7697_set_key_mgmt(struct mt7697_vif *vif, u32 key_mgmt)
{
int ret = 0;
netif_stop_queue(vif->ndev);
dev_dbg(vif->cfg->dev, "%s: key mgmt(0x%08x)\n", __func__, key_mgmt);
if (key_mgmt == WLAN_AKM_SUITE_PSK) {
if (vif->auth_mode == MT7697_WIFI_AUTH_MODE_WPA)
vif->auth_mode = MT7697_WIFI_AUTH_MODE_WPA_PSK;
else if (vif->auth_mode == MT7697_WIFI_AUTH_MODE_WPA2)
vif->auth_mode = MT7697_WIFI_AUTH_MODE_WPA2_PSK;
} else if (key_mgmt == 0x00409600) {
dev_err(vif->cfg->dev, "%s: key mgmt(0x%08x) not supported\n",
__func__, key_mgmt);
ret = -ENOTSUPP;
goto cleanup;
} else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
vif->auth_mode = MT7697_WIFI_AUTH_MODE_OPEN;
}
clear_bit(WLAN_ENABLED, &vif->flags);
dev_dbg(vif->cfg->dev, "%s: auth mode(%u)\n",
__func__, vif->auth_mode);
if (wmi_ready) {
ret = mt7697_disconnect(vif);
if (ret < 0) {
dev_err(vif->cfg->dev,
"mt7697_disconnect() failed(%d)\n", ret);
goto cleanup;
}
cleanup:
return ret;
}
del_timer(&vif->disconnect_timer);
static int mt7697_set_cipher(struct mt7697_vif *vif, u32 cipher, bool ucast)
{
enum mt7697_wifi_encrypt_type_t *_cipher = ucast ?
&vif->prwise_crypto : &vif->grp_crypto;
u8 *_cipher_len = ucast ? &vif->prwise_crypto_len :
&vif->grp_crypto_len;
int ret = 0;
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = 0;
}
dev_dbg(vif->cfg->dev, "%s: cipher(0x%08x), ucast(%u)\n",
__func__, cipher, ucast);
if (vif->scan_req) {
cfg80211_scan_done(vif->scan_req, true);
vif->scan_req = NULL;
switch (cipher) {
case 0:
*_cipher = MT7697_WIFI_ENCRYPT_TYPE_ENCRYPT_DISABLED;
*_cipher_len = 0;
break;
case WLAN_CIPHER_SUITE_TKIP:
*_cipher = MT7697_WIFI_ENCRYPT_TYPE_TKIP_ENABLED;
*_cipher_len = 0;
break;
case WLAN_CIPHER_SUITE_CCMP:
*_cipher = MT7697_WIFI_ENCRYPT_TYPE_AES_ENABLED;
*_cipher_len = 0;
break;
case WLAN_CIPHER_SUITE_WEP104:
case WLAN_CIPHER_SUITE_WEP40:
case WLAN_CIPHER_SUITE_SMS4:
default:
dev_err(vif->cfg->dev, "cipher(0x%08x) not supported\n", cipher);
ret = -ENOTSUPP;
goto cleanup;
}
dev_dbg(vif->cfg->dev, "%s: set cipher(%u)\n", __func__, *_cipher);
cleanup:
return ret;
}
static inline bool mt7697_is_wpa_ie(const u8 *pos)
static int mt7697_set_wpa_version(struct mt7697_vif *vif,
enum nl80211_wpa_versions wpa_version)
{
return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
pos[2] == 0x00 && pos[3] == 0x50 &&
pos[4] == 0xf2 && pos[5] == 0x01;
}
int ret = 0;
static inline bool mt7697_is_rsn_ie(const u8 *pos)
{
return pos[0] == WLAN_EID_RSN;
}
dev_dbg(vif->cfg->dev, "%s: WPA version(%u)\n", __func__, wpa_version);
if (!wpa_version) {
vif->auth_mode = MT7697_WIFI_AUTH_MODE_OPEN;
} else if (wpa_version & NL80211_WPA_VERSION_2) {
vif->auth_mode = MT7697_WIFI_AUTH_MODE_WPA2;
} else if (wpa_version & NL80211_WPA_VERSION_1) {
vif->auth_mode = MT7697_WIFI_AUTH_MODE_WPA;
} else {
dev_err(vif->cfg->dev, "%s: WPA version(%u) not supported\n",
__func__, wpa_version);
ret = -ENOTSUPP;
goto cleanup;
}
static inline bool mt7697_is_wps_ie(const u8 *pos)
{
return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
pos[1] >= 4 &&
pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
pos[5] == 0x04);
dev_dbg(vif->cfg->dev, "%s: auth mode(%u)\n", __func__, vif->auth_mode);
cleanup:
return ret;
}
static bool mt7697_is_valid_iftype(struct mt7697_cfg80211_info *cfg,
enum nl80211_iftype type, u8 *if_idx)
static bool mt7697_is_valid_iftype(const struct mt7697_cfg80211_info *cfg,
enum nl80211_iftype type, u8 *if_idx)
{
int i;
......@@ -212,19 +254,8 @@ static bool mt7697_is_valid_iftype(struct mt7697_cfg80211_info *cfg,
((type == NL80211_IFTYPE_ADHOC) && cfg->num_vif))
return false;
if (type == NL80211_IFTYPE_STATION ||
type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
for (i = 0; i < cfg->vif_max; i++) {
if ((cfg->avail_idx_map) & BIT(i)) {
*if_idx = i;
return true;
}
}
}
if (type == NL80211_IFTYPE_P2P_CLIENT ||
type == NL80211_IFTYPE_P2P_GO) {
for (i = cfg->max_norm_iface; i < cfg->vif_max; i++) {
if (type == NL80211_IFTYPE_STATION || type == NL80211_IFTYPE_AP) {
for (i = cfg->vif_start; i < cfg->vif_max; i++) {
if ((cfg->avail_idx_map) & BIT(i)) {
*if_idx = i;
return true;
......@@ -244,6 +275,11 @@ static struct cfg80211_bss* mt7697_add_bss_if_needed(struct mt7697_vif *vif,
struct cfg80211_bss *bss = NULL;
u8 *ie = NULL;
dev_dbg(cfg->dev, "%s(): SSID('%s')\n", __func__, vif->ssid);
print_hex_dump(KERN_DEBUG, DRVNAME" BSSID ", DUMP_PREFIX_OFFSET,
16, 1, bssid, ETH_ALEN, 0);
dev_dbg(cfg->dev, "%s(): freq(%u)\n", __func__, freq);
chan = ieee80211_get_channel(cfg->wiphy, freq);
if (!chan) {
dev_err(cfg->dev, "%s(): ieee80211_get_channel(%u) failed\n",
......@@ -251,7 +287,10 @@ static struct cfg80211_bss* mt7697_add_bss_if_needed(struct mt7697_vif *vif,
goto cleanup;
}
bss = cfg80211_get_bss(cfg->wiphy, chan, vif->req_bssid,
dev_dbg(cfg->dev, "%s(): band(%u) chan(%u)\n",
__func__, chan->band, chan->center_freq);
bss = cfg80211_get_bss(cfg->wiphy, chan, bssid,
vif->ssid, vif->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!bss) {
......@@ -288,18 +327,17 @@ static struct cfg80211_bss* mt7697_add_bss_if_needed(struct mt7697_vif *vif,
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): added bss %pM to cfg80211\n",
dev_dbg(cfg->dev, "%s(): added bss(%p) to cfg80211\n",
__func__, bssid);
} else
dev_dbg(cfg->dev, "%s(): cfg80211 already has a bss\n",
__func__);
dev_dbg(cfg->dev, "%s(): cfg80211 has bss\n", __func__);
cleanup:
if (ie) kfree(ie);
return bss;
}
static struct wireless_dev *mt7697_cfg80211_add_iface(struct wiphy *wiphy,
static struct wireless_dev* mt7697_cfg80211_add_iface(struct wiphy *wiphy,
const char *name,
enum nl80211_iftype type,
u32 *flags,
......@@ -312,13 +350,12 @@ static struct wireless_dev *mt7697_cfg80211_add_iface(struct wiphy *wiphy,
dev_dbg(cfg->dev, "%s(): iface('%s') type(%u)\n",
__func__, name, type);
if (cfg->num_vif == cfg->vif_max) {
dev_err(cfg->dev, "max # of supported vif(%u)\n",
cfg->num_vif);
dev_err(cfg->dev, "max # supported vif(%u)\n", cfg->num_vif);
goto cleanup;
}
if (!mt7697_is_valid_iftype(cfg, type, &if_idx)) {
dev_err(cfg->dev, "%s(): unsupported interface type(%d)\n",
dev_err(cfg->dev, "%s(): unsupported interface(%d)\n",
__func__, type);
goto cleanup;
}
......@@ -346,17 +383,19 @@ static int mt7697_cfg80211_del_iface(struct wiphy *wiphy,
dev_dbg(cfg->dev, "%s(): DEL IFACE\n", __func__);
spin_lock_bh(&cfg->vif_list_lock);
list_del(&vif->list);
list_del(&vif->next);
spin_unlock_bh(&cfg->vif_list_lock);
ret = mt7697_cfg80211_vif_stop(vif, test_bit(WMI_READY, &cfg->flag));
ret = mt7697_cfg80211_stop(vif);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_cfg80211_vif_stop() failed(%d)\n",
"%s(): mt7697_cfg80211_stop() failed(%d)\n",
__func__, ret);
goto cleanup;
}
unregister_netdev(vif->ndev);
cleanup:
return ret;
}
......@@ -372,15 +411,48 @@ static int mt7697_cfg80211_change_iface(struct wiphy *wiphy,
dev_dbg(cfg->dev, "%s(): iface type(%u)\n", __func__, type);
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, params->macaddr, ETH_ALEN, 0);
switch (type) {
case NL80211_IFTYPE_AP:
case NL80211_IFTYPE_STATION:
if (cfg->wifi_cfg.opmode != MT7697_WIFI_MODE_STA_ONLY) {
cfg->wifi_cfg.opmode = MT7697_WIFI_MODE_STA_ONLY;
cfg->port_type = MT7697_PORT_STA;
vif->wdev.iftype = NL80211_IFTYPE_STATION;
ret = mt7697_wr_set_op_mode_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
break;
case NL80211_IFTYPE_AP:
if (cfg->wifi_cfg.opmode != MT7697_WIFI_MODE_AP_ONLY) {
cfg->wifi_cfg.opmode = MT7697_WIFI_MODE_AP_ONLY;
cfg->port_type = MT7697_PORT_AP;
vif->wdev.iftype = NL80211_IFTYPE_AP;
ret = mt7697_wr_set_op_mode_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
break;
case NL80211_IFTYPE_P2P_GO:
case NL80211_IFTYPE_P2P_CLIENT:
default:
dev_err(cfg->dev, "%s(): invalid interface type %u\n",
dev_err(cfg->dev, "%s(): unsupported interface(%u)\n",
__func__, type);
ret = -EOPNOTSUPP;
goto cleanup;
......@@ -392,8 +464,20 @@ cleanup:
return ret;
}
static int mt7697_cfg80211_set_txq_params(struct wiphy *wiphy,
struct net_device *ndev,
struct ieee80211_txq_params *params)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev,
"%s(): SET TXQ PARAMS ac(%u) txop(%u) cwmin/cwmax(%u/%u) aifs(%u)\n",
__func__, params->ac, params->txop, params->cwmin,
params->cwmax, params->aifs);
return 0;
}
static int mt7697_cfg80211_scan(struct wiphy *wiphy,
struct cfg80211_scan_request *request)
struct cfg80211_scan_request *request)
{
struct mt7697_vif *vif = mt7697_vif_from_wdev(request->wdev);
struct mt7697_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
......@@ -403,7 +487,7 @@ static int mt7697_cfg80211_scan(struct wiphy *wiphy,
if (test_bit(CONNECTED, &vif->flags)) {
dev_warn(cfg->dev,
"%s(): connected scan not allowed\n", __func__);
"%s(): CONNECTED - scan not allowed\n", __func__);
ret = -EINVAL;
goto out;
}
......@@ -420,16 +504,6 @@ static int mt7697_cfg80211_scan(struct wiphy *wiphy,
GFP_KERNEL);
}
if (cfg->reg_rx_hndlr) {
ret = mt7697_wr_unreg_rx_hndlr_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_unreg_rx_hndlr_req() failed(%d)\n",
__func__, ret);
goto out;
}
}
vif->scan_req = request;
ret = mt7697_wr_scan_req(cfg, vif->fw_vif_idx, request);
if (ret < 0) {
......@@ -443,6 +517,15 @@ out:
return ret;
}
static int mt7697_cfg80211_connect(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_connect_params *sme)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): CONNECT\n", __func__);
return 0;
}
static int mt7697_cfg80211_disconnect(struct wiphy *wiphy,
struct net_device *ndev, u16 reason_code)
{
......@@ -491,7 +574,22 @@ static int mt7697_cfg80211_add_key(struct wiphy *wiphy,
struct key_params *params)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): ADD KEY\n", __func__);
dev_dbg(cfg->dev, "%s(): ADD KEY index(%u) cipher(0x%08x)\n",
__func__, key_index, params->cipher);
if (mac_addr) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac_addr, ETH_ALEN, 0);
}
dev_dbg(cfg->dev, "%s(): key(%u)\n", __func__, params->key_len);
print_hex_dump(KERN_DEBUG, DRVNAME" KEY ",
DUMP_PREFIX_OFFSET, 16, 1, params->key, params->key_len, 0);
dev_dbg(cfg->dev, "%s(): seq(%u)\n", __func__, params->key_len);
print_hex_dump(KERN_DEBUG, DRVNAME" SEQ ",
DUMP_PREFIX_OFFSET, 16, 1, params->key, params->key_len, 0);
return 0;
}
......@@ -503,7 +601,13 @@ static int mt7697_cfg80211_get_key(struct wiphy *wiphy,
struct key_params *))
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): GET KEY\n", __func__);
dev_dbg(cfg->dev, "%s(): GET KEY(%u)\n", __func__, key_index);
if (mac_addr) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac_addr, ETH_ALEN, 0);
}
return 0;
}
......@@ -513,7 +617,7 @@ static int mt7697_cfg80211_del_key(struct wiphy *wiphy,
const u8 *mac_addr)
{
struct mt7697_vif *vif = netdev_priv(ndev);
dev_dbg(vif->cfg->dev, "%s(): DEL KEY\n", __func__);
dev_dbg(vif->cfg->dev, "%s(): DEL KEY(%u)\n", __func__, key_index);
return 0;
}
......@@ -523,7 +627,9 @@ static int mt7697_cfg80211_set_default_key(struct wiphy *wiphy,
bool multicast)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): SET DEFAULT KEY\n", __func__);
dev_dbg(cfg->dev,
"%s(): SET DEFAULT KEY(%u) unicast(%u) multicast(%u)\n",
__func__, key_index, unicast, multicast);
return 0;
}
......@@ -560,12 +666,169 @@ static int mt7697_cfg80211_leave_ibss(struct wiphy *wiphy,
return ret;
}
static int mt7697_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
{
struct mt7697_cfg80211_info *cfg = (struct mt7697_cfg80211_info*)wiphy_priv(wiphy);
dev_dbg(cfg->dev, "%s(): SET WIPHY PARAMS changed(0x%08x)\n",
__func__, changed);
return 0;
}
static int mt7697_cfg80211_start_ap(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_ap_settings *settings)
{
struct mt7697_cfg80211_info *cfg = (struct mt7697_cfg80211_info*)wiphy_priv(wiphy);
struct mt7697_vif *vif = netdev_priv(ndev);
int ret;
dev_dbg(cfg->dev, "%s(): START AP ssid('%s') band(%u) freq(%u)\n",
__func__, settings->ssid, settings->chandef.chan->band,
settings->chandef.chan->center_freq);
ret = mt7697_wr_set_ssid_req(cfg, settings->ssid_len, settings->ssid);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_ssid_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cfg->wifi_cfg.ap.ssid_len = settings->ssid_len;
memcpy(cfg->wifi_cfg.ap.ssid, settings->ssid, settings->ssid_len);
vif->ch_hint = ieee80211_frequency_to_channel(settings->chandef.chan->center_freq);
if (!vif->ch_hint) {
dev_err(cfg->dev,
"%s(): ieee80211_frequency_to_channel() failed\n",
__func__);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): channel(%u)\n", __func__, vif->ch_hint);
ret = mt7697_wr_set_channel_req(cfg, vif->ch_hint);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_channel_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cfg->wifi_cfg.ap.ch = vif->ch_hint;
ret = mt7697_set_wpa_version(vif, settings->crypto.wpa_versions);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_set_wpa_version() failed(%d)\n",
__func__, ret);
goto cleanup;
}
if (settings->crypto.n_ciphers_pairwise)
ret = mt7697_set_cipher(vif, settings->crypto.ciphers_pairwise[0], true);
else
ret = mt7697_set_cipher(vif, 0, true);
if (ret < 0) {
dev_err(cfg->dev, "mt7697_set_cipher() failed(%d)\n", ret);
goto cleanup;
}
ret = mt7697_set_cipher(vif, settings->crypto.cipher_group, false);
if (ret < 0) {
dev_err(cfg->dev, "%s: mt7697_set_cipher() failed(%d)\n",
__func__, ret);
goto cleanup;
}
if (settings->crypto.n_akm_suites) {
ret = mt7697_set_key_mgmt(vif, settings->crypto.akm_suites[0]);
if (ret < 0) {
dev_err(cfg->dev, "%s: mt7697_set_key_mgmt() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
ret = mt7697_wr_set_security_mode_req(cfg, vif->auth_mode, vif->prwise_crypto);
if (ret < 0) {
dev_err(cfg->dev, "%s: mt7697_wr_set_security_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697_wr_reload_settings_req(cfg, vif->fw_vif_idx);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_reload_settings_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cleanup:
return ret;
}
static int mt7697_cfg80211_stop_ap(struct wiphy *wiphy,
struct net_device *ndev)
{
struct mt7697_cfg80211_info *cfg = (struct mt7697_cfg80211_info*)wiphy_priv(wiphy);
dev_dbg(cfg->dev, "%s(): STOP AP\n", __func__);
return 0;
}
static int mt7697_cfg80211_change_beacon(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_beacon_data *info)
{
struct mt7697_cfg80211_info *cfg = (struct mt7697_cfg80211_info*)wiphy_priv(wiphy);
dev_dbg(cfg->dev, "%s(): CHANGE BEACON\n", __func__);
return 0;
}
static int mt7697_cfg80211_add_station(struct wiphy *wiphy,
struct net_device *ndev,
u8 *mac,
struct station_parameters *params)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): ADD STATION\n", __func__);
if (mac) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac, ETH_ALEN, 0);
}
return 0;
}
static int mt7697_cfg80211_get_station(struct wiphy *wiphy,
struct net_device *ndev,
u8 *mac,
struct station_info *sinfo)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): CHANGE STATION\n", __func__);
if (mac) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac, ETH_ALEN, 0);
}
return 0;
}
static int mt7697_cfg80211_del_station(struct wiphy *wiphy,
struct net_device *ndev,
u8 *mac)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): DEL STATION\n", __func__);
if (mac) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac, ETH_ALEN, 0);
}
return 0;
}
......@@ -581,10 +844,13 @@ static int mt7697_cfg80211_change_station(struct wiphy *wiphy,
dev_dbg(cfg->dev, "%s(): CHANGE STATION flags(0x%08x)\n",
__func__, params->sta_flags_set);
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac, ETH_ALEN, 0);
if (mac) {
print_hex_dump(KERN_DEBUG, DRVNAME" MAC ",
DUMP_PREFIX_OFFSET, 16, 1, mac, ETH_ALEN, 0);
}
if ((vif->wdev.iftype != NL80211_IFTYPE_STATION)) {
if ((vif->wdev.iftype != NL80211_IFTYPE_STATION) &&
(vif->wdev.iftype != NL80211_IFTYPE_AP)) {
dev_err(cfg->dev, "%s(): iftype(%u) not supported\n",
__func__, vif->wdev.iftype);
err = -EOPNOTSUPP;
......@@ -600,24 +866,36 @@ static int mt7697_cfg80211_change_station(struct wiphy *wiphy,
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): set mlme('%s')\n",
__func__,
params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED) ?
"AUTHORIZED":"UNAUTHORIZE");
/*
err = mt7697_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
(params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED)) ?
WMI_AP_MLME_AUTHORIZE:WMI_AP_MLME_UNAUTHORIZE, mac, 0);
if (err) {
dev_err(cfg->dev,
"mt7697_wmi_ap_set_mlme() failed(%d)\n", err);
goto cleanup;
}
*/
cleanup:
return err;
}
static int mt7697_cfg80211_set_pmksa(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_pmksa *pmksa)
{
struct mt7697_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
dev_dbg(cfg->dev, "%s(): SET PMKSA\n", __func__);
return 0;
}
static int mt7697_cfg80211_del_pmksa(struct wiphy *wiphy,
struct net_device *ndev,
struct cfg80211_pmksa *pmksa)
{
struct mt7697_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
dev_dbg(cfg->dev, "%s(): DEL PMKSA\n", __func__);
return 0;
}
static int mt7697_cfg80211_flush_pmksa(struct wiphy *wiphy,
struct net_device *ndev)
{
struct mt7697_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
dev_dbg(cfg->dev, "%s(): FLUSH PMKSA\n", __func__);
return 0;
}
static int mt7697_cfg80211_remain_on_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct ieee80211_channel *chan,
......@@ -676,8 +954,9 @@ static const struct cfg80211_ops mt7697_cfg80211_ops =
.add_virtual_intf = mt7697_cfg80211_add_iface,
.del_virtual_intf = mt7697_cfg80211_del_iface,
.change_virtual_intf = mt7697_cfg80211_change_iface,
.set_txq_params = mt7697_cfg80211_set_txq_params,
.scan = mt7697_cfg80211_scan,
// .connect = mt7697_cfg80211_connect,
.connect = mt7697_cfg80211_connect,
.disconnect = mt7697_cfg80211_disconnect,
.add_key = mt7697_cfg80211_add_key,
.get_key = mt7697_cfg80211_get_key,
......@@ -685,31 +964,63 @@ static const struct cfg80211_ops mt7697_cfg80211_ops =
.set_default_key = mt7697_cfg80211_set_default_key,
.join_ibss = mt7697_cfg80211_join_ibss,
.leave_ibss = mt7697_cfg80211_leave_ibss,
// .set_pmksa = mt7697_cfg80211_set_pmksa,
// .del_pmksa = mt7697_cfg80211_del_pmksa,
// .flush_pmksa = mt7697_cfg80211_flush_pmksa,
.set_wiphy_params = mt7697_cfg80211_set_wiphy_params,
.start_ap = mt7697_cfg80211_start_ap,
.stop_ap = mt7697_cfg80211_stop_ap,
.change_beacon = mt7697_cfg80211_change_beacon,
.add_station = mt7697_cfg80211_add_station,
.get_station = mt7697_cfg80211_get_station,
.del_station = mt7697_cfg80211_del_station,
.change_station = mt7697_cfg80211_change_station,
.set_pmksa = mt7697_cfg80211_set_pmksa,
.del_pmksa = mt7697_cfg80211_del_pmksa,
.flush_pmksa = mt7697_cfg80211_flush_pmksa,
.remain_on_channel = mt7697_cfg80211_remain_on_channel,
.cancel_remain_on_channel = mt7697_cfg80211_cancel_remain_on_channel,
.mgmt_tx = mt7697_cfg80211_mgmt_tx,
.mgmt_frame_register = mt7697_cfg80211_mgmt_frame_register,
};
void mt7697_cfg80211_stop(struct mt7697_vif *vif)
int mt7697_cfg80211_stop(struct mt7697_vif *vif)
{
switch (vif->sme_state) {
case SME_DISCONNECTED:
break;
case SME_CONNECTING:
cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
break;
case SME_CONNECTED:
cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
break;
struct mt7697_sta *sta, *sta_next;
int ret = 0;
if (vif->wdev.iftype == NL80211_IFTYPE_STATION) {
switch (vif->sme_state) {
case SME_DISCONNECTED:
break;
case SME_CONNECTING:
cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
break;
case SME_CONNECTED:
cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
break;
}
}
else if (vif->wdev.iftype == NL80211_IFTYPE_AP) {
spin_lock_bh(&vif->sta_list_lock);
list_for_each_entry_safe(sta, sta_next, &vif->sta_list, next) {
print_hex_dump(KERN_DEBUG, DRVNAME" DISCONNECT STA BSSID ",
DUMP_PREFIX_OFFSET, 16, 1, sta->bssid, ETH_ALEN, 0);
ret = mt7697_wr_disconnect_req(vif->cfg, vif->fw_vif_idx, sta->bssid);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_disconnect_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
list_del(&sta->next);
kfree(sta);
}
vif->sta_count = 0;
spin_lock_bh(&vif->sta_list_lock);
}
vif->sme_state = SME_DISCONNECTED;
......@@ -724,6 +1035,9 @@ void mt7697_cfg80211_stop(struct mt7697_vif *vif)
cfg80211_scan_done(vif->scan_req, true);
vif->scan_req = NULL;
}
cleanup:
return ret;
}
static const struct ieee80211_txrx_stypes
......@@ -755,8 +1069,8 @@ static int mt7697_cfg80211_vif_init(struct mt7697_vif *vif)
static void mt7697_cfg80211_disconnect_work(struct work_struct *work)
{
struct mt7697_vif *vif = container_of(work,
struct mt7697_vif, disconnect_work);
struct mt7697_vif *vif = container_of(work, struct mt7697_vif,
disconnect_work);
struct mt7697_cfg80211_info *cfg = vif->cfg;
int ret;
......@@ -774,19 +1088,48 @@ cleanup:
return;
}
static void mt7697_cleanup_vif(struct mt7697_cfg80211_info *cfg)
{
struct mt7697_vif *vif, *vif_next = NULL;
int ret;
spin_lock_bh(&cfg->vif_list_lock);
list_for_each_entry_safe(vif, vif_next, &cfg->vif_list, next) {
dev_dbg(cfg->dev, "%s(): remove vif(%u)\n",
__func__, vif->fw_vif_idx);
list_del(&vif->next);
WARN_ON(vif->sta_count > 0);
spin_unlock_bh(&cfg->vif_list_lock);
ret = mt7697_cfg80211_stop(vif);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_cfg80211_stop() failed(%d)\n",
__func__, ret);
}
unregister_netdev(vif->ndev);
spin_lock_bh(&cfg->vif_list_lock);
}
spin_unlock_bh(&cfg->vif_list_lock);
}
struct mt7697_vif* mt7697_get_vif_by_idx(struct mt7697_cfg80211_info *cfg,
u8 if_idx)
u32 if_idx)
{
struct mt7697_vif *vif, *found = NULL;
if (WARN_ON(if_idx > (cfg->vif_max - 1))) {
if (if_idx > cfg->vif_max - 1) {
dev_err(cfg->dev, "%s(): invalid if idx(%u > %u)\n",
__func__, if_idx, cfg->vif_max - 1);
return NULL;
}
spin_lock_bh(&cfg->vif_list_lock);
list_for_each_entry(vif, &cfg->vif_list, list) {
list_for_each_entry(vif, &cfg->vif_list, next) {
if (vif->fw_vif_idx == if_idx) {
found = vif;
break;
......@@ -797,78 +1140,158 @@ struct mt7697_vif* mt7697_get_vif_by_idx(struct mt7697_cfg80211_info *cfg,
return found;
}
struct wireless_dev *mt7697_interface_add(
struct mt7697_cfg80211_info *cfg, const char *name,
enum nl80211_iftype type, u8 fw_vif_idx)
struct wireless_dev* mt7697_interface_add(struct mt7697_cfg80211_info *cfg,
const char *name,
enum nl80211_iftype type,
u8 fw_vif_idx)
{
struct net_device *ndev;
struct mt7697_vif *vif;
int err;
dev_err(cfg->dev, "%s(): interface('%s') type(%u)\n",
dev_dbg(cfg->dev, "%s(): interface('%s') type(%u)\n",
__func__, name, type);
ndev = alloc_etherdev(sizeof(struct mt7697_vif));
if (!ndev) {
dev_err(cfg->dev, "%s(): alloc_etherdev() failed\n", __func__);
goto err;
}
if (dev_alloc_name(ndev, name) < 0) {
dev_err(cfg->dev, "%s(): dev_alloc_name() failed\n", __func__);
goto err;
}
vif = netdev_priv(ndev);
ndev->ieee80211_ptr = &vif->wdev;
vif->wdev.wiphy = cfg->wiphy;
vif->cfg = cfg;
vif->ndev = ndev;
INIT_WORK(&vif->disconnect_work, mt7697_cfg80211_disconnect_work);
INIT_LIST_HEAD(&vif->list);
SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
vif->wdev.netdev = ndev;
vif->wdev.iftype = type;
vif->fw_vif_idx = fw_vif_idx;
if (list_empty(&cfg->vif_list)) {
ndev = alloc_etherdev(sizeof(struct mt7697_vif));
if (!ndev) {
dev_err(cfg->dev, "%s(): alloc_etherdev() failed\n",
__func__);
goto err;
}
err = dev_alloc_name(ndev, name);
if (err < 0) {
dev_err(cfg->dev, "%s(): dev_alloc_name() failed(%d)\n",
__func__, err);
goto err;
}
vif = netdev_priv(ndev);
ndev->ieee80211_ptr = &vif->wdev;
vif->wdev.wiphy = cfg->wiphy;
vif->cfg = cfg;
vif->ndev = ndev;
INIT_WORK(&vif->disconnect_work, mt7697_cfg80211_disconnect_work);
INIT_LIST_HEAD(&vif->next);
SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
vif->wdev.netdev = ndev;
vif->wdev.iftype = type;
vif->fw_vif_idx = fw_vif_idx;
spin_lock_init(&vif->sta_list_lock);
INIT_LIST_HEAD(&vif->sta_list);
vif->sta_max = MT7697_MAX_STA;
ndev->addr_assign_type = NET_ADDR_PERM;
ndev->addr_len = ETH_ALEN;
ndev->dev_addr = cfg->mac_addr.addr;
ndev->wireless_data = &vif->wireless_data;
mt7697_init_netdev(ndev);
if (mt7697_cfg80211_vif_init(vif)) {
dev_err(cfg->dev, "%s(): mt7697_cfg80211_vif_init() failed\n",
__func__);
goto err;
}
ndev->addr_assign_type = NET_ADDR_PERM;
ndev->addr_len = ETH_ALEN;
ndev->dev_addr = cfg->mac_addr.addr;
ndev->wireless_data = &vif->wireless_data;
dev_dbg(cfg->dev, "%s(): register('%s') type(%u)\n",
__func__, ndev->name, type);
mt7697_init_netdev(ndev);
if (register_netdevice(ndev)) {
dev_err(cfg->dev, "%s(): register_netdevice() failed\n",
__func__);
goto err;
}
if (mt7697_cfg80211_vif_init(vif)) {
dev_err(cfg->dev, "%s(): mt7697_cfg80211_vif_init() failed\n",
__func__);
goto err;
netif_carrier_off(ndev);
vif->sme_state = SME_DISCONNECTED;
set_bit(WLAN_ENABLED, &vif->flags);
spin_lock_bh(&cfg->vif_list_lock);
list_add_tail(&vif->next, &cfg->vif_list);
spin_unlock_bh(&cfg->vif_list_lock);
dev_err(cfg->dev, "%s(): added('%s') type(%u)\n",
__func__, ndev->name, type);
}
else {
dev_dbg(cfg->dev, "%s(): interface exists\n", __func__);
vif = mt7697_get_vif_by_idx(cfg, 0);
}
dev_err(cfg->dev, "%s(): register('%s') type(%u)\n",
__func__, ndev->name, type);
return &vif->wdev;
if (register_netdevice(ndev)) {
dev_err(cfg->dev, "%s(): register_netdevice() failed\n",
__func__);
goto err;
err:
if (ndev) free_netdev(ndev);
return NULL;
}
int mt7697_cfg80211_del_sta(struct mt7697_vif *vif, const u8* bssid)
{
struct mt7697_sta *sta, *sta_next;
int ret = -EINVAL;
spin_lock_bh(&vif->sta_list_lock);
list_for_each_entry_safe(sta, sta_next, &vif->sta_list, next) {
if (!memcmp(bssid, sta->bssid, ETH_ALEN)) {
print_hex_dump(KERN_DEBUG, DRVNAME" DISCONNECT STA BSSID ",
DUMP_PREFIX_OFFSET, 16, 1, sta->bssid, ETH_ALEN, 0);
ret = mt7697_wr_disconnect_req(vif->cfg, vif->fw_vif_idx, sta->bssid);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_disconnect_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
list_del(&sta->next);
kfree(sta);
vif->sta_count--;
ret = 0;
break;
}
}
netif_carrier_off(ndev);
cleanup:
spin_unlock_bh(&vif->sta_list_lock);
return ret;
}
vif->sme_state = SME_DISCONNECTED;
set_bit(WLAN_ENABLED, &vif->flags);
int mt7697_cfg80211_new_sta(struct mt7697_vif *vif, const u8* bssid)
{
struct mt7697_sta *sta;
int ret = 0;
spin_lock_bh(&cfg->vif_list_lock);
list_add_tail(&vif->list, &cfg->vif_list);
spin_unlock_bh(&cfg->vif_list_lock);
if (vif->sta_count < vif->sta_max) {
dev_err(vif->cfg->dev, "%s(): max stations reached(%u)\n",
__func__, vif->sta_max);
ret = -EINVAL;
goto cleanup;
}
sta = kmalloc(sizeof(struct mt7697_sta), GFP_KERNEL);
if (!sta) {
dev_err(vif->cfg->dev, "%s(): kmalloc() failed\n", __func__);
ret = -ENOMEM;
goto cleanup;
}
dev_err(cfg->dev, "%s(): added('%s') type(%u)\n",
__func__, ndev->name, type);
print_hex_dump(KERN_DEBUG, DRVNAME" ADD STA BSSID ",
DUMP_PREFIX_OFFSET, 16, 1, bssid, ETH_ALEN, 0);
return &vif->wdev;
memcpy(sta->bssid, bssid, ETH_ALEN);
INIT_LIST_HEAD(&sta->next);
spin_lock_bh(&vif->sta_list_lock);
list_add_tail(&sta->next, &vif->sta_list);
vif->sta_count++;
spin_unlock_bh(&vif->sta_list_lock);
err:
if (ndev) free_netdev(ndev);
return NULL;
cleanup:
return ret;
}
int mt7697_cfg80211_connect_event(struct mt7697_vif *vif, const u8* bssid,
......@@ -926,6 +1349,7 @@ int mt7697_cfg80211_connect_event(struct mt7697_vif *vif, const u8* bssid,
(vif->sme_state == SME_DISCONNECTED)) {
vif->sme_state = SME_CONNECTED;
memcpy(vif->bssid, bssid, ETH_ALEN);
cfg80211_connect_result(vif->ndev, bssid,
NULL, 0,
NULL, 0,
......@@ -965,6 +1389,44 @@ static const struct wiphy_wowlan_support mt7697_wowlan_support = {
};
#endif
int mt7697_cfg80211_get_params(struct mt7697_cfg80211_info *cfg)
{
int err = mt7697_wr_get_listen_interval_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_listen_interval_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_radio_state_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_radio_state_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_wireless_mode_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_wireless_mode_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_mac_addr_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_mac_addr_req() failed(%d)\n",
__func__, err);
goto failed;
}
failed:
return err;
}
int mt7697_cfg80211_init(struct mt7697_cfg80211_info *cfg)
{
struct wiphy *wiphy = cfg->wiphy;
......@@ -1043,7 +1505,6 @@ int mt7697_cfg80211_init(struct mt7697_cfg80211_info *cfg)
#ifdef CONFIG_PM
wiphy->wowlan = &mt7697_wowlan_support;
#endif
wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
WIPHY_FLAG_HAVE_AP_SME |
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
......@@ -1070,8 +1531,15 @@ cleanup:
void mt7697_cfg80211_cleanup(struct mt7697_cfg80211_info *cfg)
{
wiphy_unregister(cfg->wiphy);
cfg->wiphy_registered = false;
mt7697_cleanup_vif(cfg);
flush_workqueue(cfg->tx_workq);
destroy_workqueue(cfg->tx_workq);
if (cfg->wiphy_registered) {
wiphy_unregister(cfg->wiphy);
cfg->wiphy_registered = false;
}
}
struct mt7697_cfg80211_info *mt7697_cfg80211_create(void)
......
......@@ -22,9 +22,12 @@
struct mt7697_cfg80211_info;
struct mt7697_vif;
int mt7697_cfg80211_new_sta(struct mt7697_vif*, const u8*);
int mt7697_cfg80211_del_sta(struct mt7697_vif*, const u8*);
int mt7697_cfg80211_connect_event(struct mt7697_vif*, const u8*, u32);
struct mt7697_cfg80211_info *mt7697_cfg80211_create(void);
void mt7697_cfg80211_stop(struct mt7697_vif *vif);
int mt7697_cfg80211_stop(struct mt7697_vif*);
int mt7697_cfg80211_get_params(struct mt7697_cfg80211_info*);
int mt7697_cfg80211_init(struct mt7697_cfg80211_info*);
void mt7697_cfg80211_cleanup(struct mt7697_cfg80211_info*);
void mt7697_cfg80211_destroy(struct mt7697_cfg80211_info*);
......
......@@ -32,7 +32,9 @@
#define MT7697_CH_MAX_5G_CHANNEL 216
#define MT7697_SCAN_MAX_ITEMS 16
#define MT7697_IFACE_MAX_CNT 2
#define MT7697_IFACE_MAX_CNT 4
#define MT7697_IFACE_NAME_LEN 32
#define MT7697_MAX_STA 10
#define MT7697_MAX_MC_FILTERS_PER_LIST 7
#define MT7697_MAX_COOKIE_NUM 180
#define MT7697_TX_TIMEOUT 10
......@@ -98,24 +100,24 @@ struct mt7697_cfg80211_info {
u32 cookie_count;
struct mt7697_cookie cookie_mem[MT7697_MAX_COOKIE_NUM];
struct workqueue_struct *tx_workq;
struct work_struct tx_work;
struct mt7697_tx_raw_packet tx_req;
u8 rx_data[LEN32_ALIGNED(IEEE80211_MAX_FRAME_LEN)];
u8 probe_data[LEN32_ALIGNED(IEEE80211_MAX_DATA_LEN)];
enum mt7697_port_type port_type;
enum mt7697_radio_state radio_state;
enum mt7697_wifi_phy_mode_t wireless_mode;
enum mt7697_wifi_phy_mode_t hw_wireless_mode;
struct mac_address mac_addr;
struct mt7697_wifi_config_t wifi_cfg;
int listen_interval;
enum mt7697_wifi_rx_filter_t rx_filter;
u8 smart_conn_filter;
u8 reg_rx_hndlr;
struct list_head vif_list;
spinlock_t vif_list_lock;
u8 num_vif;
unsigned int vif_start;
unsigned int vif_max;
u8 max_norm_iface;
u8 avail_idx_map;
......@@ -134,8 +136,13 @@ struct mt7697_key {
u32 cipher;
};
struct mt7697_sta {
struct list_head next;
u8 bssid[ETH_ALEN];
};
struct mt7697_vif {
struct list_head list;
struct list_head next;
struct wireless_dev wdev;
struct net_device *ndev;
struct mt7697_cfg80211_info *cfg;
......@@ -163,6 +170,11 @@ struct mt7697_vif {
enum mt7697_wifi_encrypt_type_t grp_crypto;
u8 grp_crypto_len;
spinlock_t sta_list_lock;
struct list_head sta_list;
u8 sta_count;
u8 sta_max;
u8 def_txkey_index;
struct mt7697_key keys[MT7697_MAX_KEY_INDEX + 1];
......@@ -197,9 +209,9 @@ static inline struct mt7697_vif *mt7697_vif_from_wdev(struct wireless_dev *wdev)
void mt7697_init_netdev(struct net_device*);
struct mt7697_vif *mt7697_get_vif_by_idx(struct mt7697_cfg80211_info*, u8);
struct mt7697_vif *mt7697_get_vif_by_idx(struct mt7697_cfg80211_info*, u32);
struct wireless_dev *mt7697_interface_add(struct mt7697_cfg80211_info*,
const char*, enum nl80211_iftype, u8 fw_vif_idx);
const char*, enum nl80211_iftype, u8);
void mt7697_tx_work(struct work_struct *);
int mt7697_data_tx(struct sk_buff*, struct net_device*);
int mt7697_rx_data(struct mt7697_cfg80211_info*, u32, u32);
......
......@@ -67,6 +67,60 @@ static int mt7697_wext_giwfreq(struct net_device *ndev,
return 0;
}
static int mt7697_wext_siwmode(struct net_device *ndev,
struct iw_request_info *info,
u32 *mode, char *extra)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
struct wireless_dev *wdev = ndev->ieee80211_ptr;
struct mt7697_vif *vif = mt7697_vif_from_wdev(wdev);
int ret = 0;
dev_dbg(cfg->dev, "%s(): mode(%u)\n", __func__, *mode);
switch (*mode) {
case IW_MODE_MASTER:
if (cfg->wifi_cfg.opmode != MT7697_WIFI_MODE_AP_ONLY) {
cfg->wifi_cfg.opmode = MT7697_WIFI_MODE_AP_ONLY;
cfg->port_type = MT7697_PORT_AP;
vif->wdev.iftype = NL80211_IFTYPE_AP;
ret = mt7697_wr_set_op_mode_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
break;
case IW_MODE_INFRA:
if (cfg->wifi_cfg.opmode != MT7697_WIFI_MODE_STA_ONLY) {
cfg->wifi_cfg.opmode = MT7697_WIFI_MODE_STA_ONLY;
cfg->port_type = MT7697_PORT_STA;
vif->wdev.iftype = NL80211_IFTYPE_STATION;
ret = mt7697_wr_set_op_mode_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
break;
default:
dev_err(cfg->dev, "%s(): unsupported mode(%u)\n",
__func__, *mode);
ret = -EINVAL;
goto cleanup;
}
cleanup:
return ret;
}
static int mt7697_wext_giwrange(struct net_device *ndev,
struct iw_request_info *info,
struct iw_point *dwrq, char *extra)
......@@ -213,9 +267,10 @@ static int mt7697_wext_siwessid(struct net_device *ndev,
__func__, wdev->iftype, ssid);
/* call only for station! */
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION)) {
dev_warn(cfg->dev, "%s(): iftype(%u != %u)\n",
__func__, wdev->iftype, NL80211_IFTYPE_STATION);
if (WARN_ON((wdev->iftype != NL80211_IFTYPE_STATION) &&
(wdev->iftype != NL80211_IFTYPE_AP))) {
dev_warn(cfg->dev, "%s(): unsupported iftype(%u)\n",
__func__, wdev->iftype);
ret = -EINVAL;
goto cleanup;
}
......@@ -230,30 +285,39 @@ static int mt7697_wext_siwessid(struct net_device *ndev,
memset(vif->ssid, 0, sizeof(vif->ssid));
vif->ssid_len = len;
memcpy(vif->ssid, ssid, len);
ret = mt7697_wr_set_ssid_req(cfg, MT7697_PORT_STA, len, ssid);
memcpy(wdev->ssid, ssid, len);
wdev->ssid_len = len;
ret = mt7697_wr_set_ssid_req(cfg, len, ssid);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_set_ssid_req() failed(%d)\n",
dev_err(cfg->dev,
"%s(): mt7697_wr_set_ssid_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697_wr_set_bssid_req(cfg, vif->req_bssid);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_set_channel_req() failed(%d)\n",
__func__, ret);
goto cleanup;
if (cfg->wifi_cfg.opmode == MT7697_WIFI_MODE_STA_ONLY) {
ret = mt7697_wr_set_bssid_req(cfg, vif->req_bssid);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_channel_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
if (vif->ch_hint > 0) {
ret = mt7697_wr_set_channel_req(cfg, MT7697_PORT_STA, vif->ch_hint);
ret = mt7697_wr_set_channel_req(cfg, vif->ch_hint);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_set_channel_req() failed(%d)\n",
dev_err(cfg->dev,
"%s(): mt7697_wr_set_channel_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
ret = mt7697_wr_set_pmk_req(cfg, MT7697_PORT_STA, vif->pmk);
ret = mt7697_wr_set_pmk_req(cfg, vif->pmk);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_set_pmk_req() failed(%d)\n",
__func__, ret);
......@@ -262,7 +326,8 @@ static int mt7697_wext_siwessid(struct net_device *ndev,
if (len > 0) {
if (test_bit(CONNECTED, &vif->flags)) {
dev_dbg(cfg->dev, "%s(): already connected\n", __func__);
dev_dbg(cfg->dev, "%s(): already connected\n",
__func__);
goto cleanup;
}
......@@ -275,9 +340,10 @@ static int mt7697_wext_siwessid(struct net_device *ndev,
goto cleanup;
}
ret = mt7697_wr_reload_settings_req(cfg);
ret = mt7697_wr_reload_settings_req(cfg, vif->fw_vif_idx);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_reload_settings_req() failed(%d)\n",
dev_err(cfg->dev,
"%s(): mt7697_wr_reload_settings_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
......@@ -406,7 +472,7 @@ static int mt7697_wext_siwencodeext(struct net_device *ndev,
dev_dbg(cfg->dev, "%s(): iftype(%u)\n", __func__, wdev->iftype);
if (wdev->iftype != NL80211_IFTYPE_STATION &&
wdev->iftype != NL80211_IFTYPE_ADHOC) {
wdev->iftype != NL80211_IFTYPE_AP) {
dev_err(cfg->dev, "%s(): iftype(%d) not supported\n",
__func__, wdev->iftype);
ret = -EOPNOTSUPP;
......@@ -419,12 +485,18 @@ static int mt7697_wext_siwencodeext(struct net_device *ndev,
DUMP_PREFIX_OFFSET, 16, 1, ext->key, ext->key_len, 0);
memcpy(vif->pmk, ext->key, ext->key_len);
}
else {
dev_err(cfg->dev, "%s(): alg(%d) not supported\n",
__func__, ext->alg);
ret = -EOPNOTSUPP;
goto cleanup;
if (wdev->iftype == NL80211_IFTYPE_AP) {
ret = mt7697_wr_set_security_mode_req(cfg,
MT7697_WIFI_AUTH_MODE_WPA2_PSK,
MT7697_WIFI_ENCRYPT_TYPE_AES_ENABLED);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_security_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
}
cleanup:
......@@ -445,7 +517,7 @@ static const iw_handler mt7697_wireless_handler[] = {
[IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
[IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) mt7697_wext_siwfreq,
[IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) mt7697_wext_giwfreq,
[IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode,
[IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) mt7697_wext_siwmode,
[IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode,
[IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) mt7697_wext_giwrange,
[IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) mt7697_wext_siwap,
......@@ -461,9 +533,6 @@ static const iw_handler mt7697_wireless_handler[] = {
[IW_IOCTL_IDX(SIOCGIWRTS)] = (iw_handler) cfg80211_wext_giwrts,
[IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag,
[IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag,
// [IW_IOCTL_IDX(SIOCSIWTXPOW)] = (iw_handler) cfg80211_wext_siwtxpower,
// [IW_IOCTL_IDX(SIOCGIWTXPOW)] = (iw_handler) cfg80211_wext_giwtxpower,
// [IW_IOCTL_IDX(SIOCSIWRETRY)] = (iw_handler) cfg80211_wext_siwretry,
[IW_IOCTL_IDX(SIOCGIWRETRY)] = (iw_handler) cfg80211_wext_giwretry,
[IW_IOCTL_IDX(SIOCSIWENCODE)] = (iw_handler) mt7697_wext_siwencode,
[IW_IOCTL_IDX(SIOCGIWENCODE)] = (iw_handler) mt7697_wext_giwencode,
......@@ -475,7 +544,6 @@ static const iw_handler mt7697_wireless_handler[] = {
[IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) mt7697_wext_giwauth,
[IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) mt7697_wext_siwencodeext,
[IW_IOCTL_IDX(SIOCGIWENCODEEXT)]= (iw_handler) mt7697_wext_giwencodeext,
// [IW_IOCTL_IDX(SIOCSIWPMKSA)] = (iw_handler) cfg80211_wext_siwpmksa,
};
const struct iw_handler_def mt7697_wireless_hndlrs = {
......
......@@ -24,6 +24,10 @@
#include "core.h"
#include "cfg80211.h"
static int itf_idx_start = 1;
module_param(itf_idx_start, int, S_IRUGO);
MODULE_PARM_DESC(itf_idx_start, "MT7697 interface start index");
static struct platform_device *pdev = NULL;
static int mt7697_open(struct net_device *ndev)
......@@ -51,10 +55,8 @@ static int mt7697_stop(struct net_device *ndev)
dev_dbg(cfg->dev, "%s(): stop net device\n", __func__);
netif_stop_queue(ndev);
mt7697_cfg80211_stop(vif);
clear_bit(WLAN_ENABLED, &vif->flags);
return 0;
}
......@@ -64,14 +66,6 @@ static struct net_device_stats *mt7697_get_stats(struct net_device *dev)
return &vif->net_stats;
}
static int mt7697_set_features(struct net_device *ndev,
netdev_features_t features)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
dev_dbg(cfg->dev, "%s(): net device set features\n", __func__);
return 0;
}
static void mt7697_set_multicast_list(struct net_device *ndev)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
......@@ -112,8 +106,9 @@ static void mt7697_init_hw_start(struct work_struct *work)
dev_dbg(cfg->dev, "%s(): init mt7697 queue(%u/%u)\n",
__func__, MT7697_MAC80211_QUEUE_TX, MT7697_MAC80211_QUEUE_RX);
err = cfg->hif_ops->init(MT7697_MAC80211_QUEUE_TX,
MT7697_MAC80211_QUEUE_RX, cfg, mt7697_proc_80211cmd,
&cfg->txq_hdl, &cfg->rxq_hdl);
MT7697_MAC80211_QUEUE_RX, cfg,
mt7697_proc_80211cmd,
&cfg->txq_hdl, &cfg->rxq_hdl);
if (err < 0) {
dev_err(cfg->dev, "%s(): queue(%u) init() failed(%d)\n",
__func__, MT7697_MAC80211_QUEUE_TX, err);
......@@ -127,54 +122,6 @@ static void mt7697_init_hw_start(struct work_struct *work)
goto failed;
}
err = mt7697_wr_get_wireless_mode_req(cfg, MT7697_PORT_STA);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_wireless_mode_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_rx_filter_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_rx_filter_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_smart_conn_filter_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_smart_conn_filter_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_listen_interval_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_listen_interval_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_get_radio_state_req(cfg);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_get_radio_state_req() failed(%d)\n",
__func__, err);
goto failed;
}
err = mt7697_wr_mac_addr_req(cfg, MT7697_PORT_STA);
if (err < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_mac_addr_req() failed(%d)\n",
__func__, err);
goto failed;
}
failed:
return;
}
......@@ -184,7 +131,6 @@ static const struct net_device_ops mt7697_netdev_ops = {
.ndo_stop = mt7697_stop,
.ndo_start_xmit = mt7697_data_tx,
.ndo_get_stats = mt7697_get_stats,
.ndo_set_features = mt7697_set_features,
.ndo_set_rx_mode = mt7697_set_multicast_list,
};
......@@ -196,7 +142,7 @@ void mt7697_init_netdev(struct net_device *ndev)
ndev->watchdog_timeo = MT7697_TX_TIMEOUT;
ndev->needed_headroom = sizeof(struct ieee80211_hdr) +
sizeof(struct mt7697_llc_snap_hdr);
ndev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
}
static const struct mt7697q_if_ops if_ops = {
......@@ -224,7 +170,7 @@ static void mt7697_cookie_cleanup(struct mt7697_cfg80211_info *cfg)
cfg->cookie_count = 0;
}
static int mt7697_probe(struct platform_device *pdev)
static int __init mt7697_probe(struct platform_device *pdev)
{
struct wiphy *wiphy;
struct mt7697_cfg80211_info *cfg;
......@@ -241,6 +187,15 @@ static int mt7697_probe(struct platform_device *pdev)
}
sema_init(&cfg->sem, 1);
cfg->tx_workq = create_singlethread_workqueue(DRVNAME);
if (!cfg->tx_workq) {
dev_err(&pdev->dev,
"%s(): mt7697_cfg80211_create() failed()\n",
__func__);
err = -ENOMEM;
goto failed;
}
INIT_WORK(&cfg->init_work, mt7697_init_hw_start);
INIT_WORK(&cfg->tx_work, mt7697_tx_work);
......@@ -251,6 +206,9 @@ static int mt7697_probe(struct platform_device *pdev)
cfg->dev = &pdev->dev;
mt7697_cookie_init(cfg);
cfg->vif_start = itf_idx_start;
cfg->vif_max = MT7697_MAX_STA;
err = mt7697_cfg80211_init(cfg);
if (err < 0) {
dev_err(&pdev->dev,
......@@ -274,31 +232,32 @@ failed:
static int mt7697_remove(struct platform_device *pdev)
{
struct mt7697_cfg80211_info *cfg = platform_get_drvdata(pdev);
int ret;
ret = mt7697q_send_reset(cfg->txq_hdl, cfg->rxq_hdl);
if (ret < 0) {
dev_err(&pdev->dev, "%s(): mt7697q_send_reset() failed(%d)\n",
__func__, ret);
goto failed;
}
mt7697_cookie_cleanup(cfg);
mt7697_cfg80211_cleanup(cfg);
mt7697_cfg80211_destroy(cfg);
mt7697_cookie_cleanup(cfg);
dev_dbg(&pdev->dev, "%s(): removed.\n", __func__);
platform_set_drvdata(pdev, NULL);
pr_info(DRVNAME" %s(): removed.\n", __func__);
return 0;
}
failed:
return ret;
static int mt7697_release(struct platform_device *pdev)
{
pr_info(DRVNAME" %s(): released.\n", __func__);
return 0;
}
static struct platform_device mt7697_platform_device = {
.name = DRVNAME,
.id = PLATFORM_DEVID_NONE,
.dev = {
.release = mt7697_release,
},
};
static struct platform_driver mt7697_platform_driver = {
.driver = {
.name = DRVNAME,
.owner = THIS_MODULE,
.bus = &platform_bus_type,
},
.probe = mt7697_probe,
......@@ -309,41 +268,31 @@ static int __init mt7697_init(void)
{
int ret;
pr_info(DRVNAME" initialize\n");
ret = platform_driver_register(&mt7697_platform_driver);
pr_info(DRVNAME" init\n");
ret = platform_device_register(&mt7697_platform_device);
if (ret) {
pr_err(DRVNAME" %s(): platform_driver_register() failed(%d)\n",
pr_err(DRVNAME" %s(): platform_device_register() failed(%d)\n",
__func__, ret);
goto cleanup;
}
pdev = platform_device_alloc(DRVNAME, -1);
if (!pdev) {
pr_err(DRVNAME" %s(): platform_device_alloc() failed\n",
__func__);
platform_driver_unregister(&mt7697_platform_driver);
ret = -ENOMEM;
goto cleanup;
}
ret = platform_device_add(pdev);
ret = platform_driver_register(&mt7697_platform_driver);
if (ret) {
pr_err(DRVNAME" %s(): platform_device_add() failed(%d)\n",
pr_err(DRVNAME" %s(): platform_driver_register() failed(%d)\n",
__func__, ret);
platform_device_del(pdev);
goto cleanup;
}
platform_device_put(pdev);
cleanup:
return ret;
}
static void __exit mt7697_exit(void)
{
pr_info(DRVNAME" exit\n");
platform_device_del(pdev);
platform_driver_unregister(&mt7697_platform_driver);
platform_device_unregister(&mt7697_platform_device);
pr_info(DRVNAME" exit\n");
}
module_init(mt7697_init);
......@@ -354,7 +303,6 @@ void mt7697_disconnect_timer_hndlr(unsigned long ptr)
struct net_device *ndev = (struct net_device *)ptr;
struct mt7697_vif *vif = netdev_priv(ndev);
// ath6kl_init_profile_info(vif);
schedule_work(&vif->disconnect_work);
}
......@@ -365,23 +313,15 @@ int mt7697_disconnect(struct mt7697_vif *vif)
dev_dbg(vif->cfg->dev, "%s(): disconnect\n", __func__);
if (test_bit(CONNECTED, &vif->flags) ||
test_bit(CONNECT_PEND, &vif->flags)) {
if (vif->cfg->reg_rx_hndlr) {
/* ret = mt7697_wr_set_op_mode_req(vif->cfg,
vif->cfg->wifi_cfg.opmode);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto failed;
}
*/
ret = mt7697_wr_unreg_rx_hndlr_req(vif->cfg);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_unreg_rx_hndlr_req() failed(%d)\n",
__func__, ret);
goto failed;
}
if (vif->sme_state == SME_CONNECTING)
cfg80211_connect_result(vif->ndev, vif->bssid,
NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
else if (vif->sme_state == SME_CONNECTED) {
cfg80211_disconnected(vif->ndev, 0,
NULL, 0, GFP_KERNEL);
}
ret = mt7697_wr_disconnect_req(vif->cfg, vif->fw_vif_idx,
......@@ -390,7 +330,49 @@ int mt7697_disconnect(struct mt7697_vif *vif)
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_disconnect_req() failed(%d)\n",
__func__, ret);
goto failed;
goto cleanup;
}
memset(vif->ssid, 0, IEEE80211_MAX_SSID_LEN);
ret = mt7697_wr_set_ssid_req(vif->cfg, IEEE80211_MAX_SSID_LEN, vif->ssid);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_set_ssid_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
memset(vif->req_bssid, 0, ETH_ALEN);
ret = mt7697_wr_set_bssid_req(vif->cfg, vif->req_bssid);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_set_channel_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
memset(vif->pmk, 0, MT7697_WIFI_LENGTH_PMK);
ret = mt7697_wr_set_pmk_req(vif->cfg, vif->pmk);
if (ret < 0) {
dev_err(vif->cfg->dev, "%s(): mt7697_wr_set_pmk_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697_wr_reload_settings_req(vif->cfg, vif->fw_vif_idx);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697_wr_reload_settings_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697q_wr_unused(vif->cfg->txq_hdl, vif->cfg->rxq_hdl);
if (ret < 0) {
dev_err(vif->cfg->dev,
"%s(): mt7697q_wr_unused() failed(%d)\n",
__func__, ret);
goto cleanup;
}
/*
......@@ -401,7 +383,7 @@ int mt7697_disconnect(struct mt7697_vif *vif)
clear_bit(CONNECT_PEND, &vif->flags);
}
failed:
cleanup:
return ret;
}
......
......@@ -18,78 +18,16 @@
#include "common.h"
#include "core.h"
static int mt7697_80211_to_ethernet(struct sk_buff *skb,
static int mt7697_ethernet_to_80211(struct sk_buff *skb,
struct net_device *ndev)
{
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
struct mt7697_vif *vif = netdev_priv(ndev);
struct ieee80211_hdr *hdr = (struct ieee80211_hdr*) skb->data;
struct ethhdr *ehdr;
u8 *payload;
u16 hdrlen, ethertype;
__be16 len;
u8 dst[ETH_ALEN];
u8 src[ETH_ALEN] __aligned(2);
int ret = 0;
print_hex_dump(KERN_DEBUG, DRVNAME" --> Rx 802.11 Frame",
DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, 0);
if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) {
dev_warn(cfg->dev, "%s(): no data present\n", __func__);
ret = -EINVAL;
goto cleanup;
}
hdrlen = ieee80211_hdrlen(hdr->frame_control);
/* convert IEEE 802.11 header + possible LLC headers into Ethernet
* header
* IEEE 802.11 address fields:
* ToDS FromDS Addr1 Addr2 Addr3 Addr4
* 0 0 DA SA BSSID n/a
* 0 1 DA BSSID SA n/a
* 1 0 BSSID SA DA n/a
* 1 1 RA TA DA SA
*/
memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN);
if (!pskb_may_pull(skb, hdrlen + 8)) {
dev_warn(cfg->dev, "%s(): pskb_may_pull() failed\n", __func__);
ret = -EINVAL;
goto cleanup;
}
payload = skb->data + hdrlen;
ethertype = (payload[6] << 8) | payload[7];
skb_pull(skb, hdrlen);
len = htons(skb->len);
ehdr = (struct ethhdr*)skb_push(skb, sizeof(struct ethhdr));
memcpy(ehdr->h_dest, dst, ETH_ALEN);
memcpy(ehdr->h_source, src, ETH_ALEN);
ehdr->h_proto = len;
print_hex_dump(KERN_DEBUG, DRVNAME" Rx 802.3 Frame ",
DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, 0);
if (!is_broadcast_ether_addr(ehdr->h_dest))
vif->net_stats.multicast++;
cleanup:
return ret;
}
static void mt7697_ethernet_to_80211(struct sk_buff *skb,
struct net_device *ndev)
{
struct ieee80211_hdr hdr;
struct mt7697_cfg80211_info *cfg = mt7697_priv(ndev);
struct mt7697_vif *vif = netdev_priv(ndev);
struct ethhdr *eth_hdr = (struct ethhdr*)skb->data;
struct mt7697_llc_snap_hdr *llc_hdr;
u8 *datap;
u8 *datap;
int ret = 0;
__be16 type = eth_hdr->h_proto;
__le16 fc;
u16 hdrlen;
......@@ -97,17 +35,39 @@ static void mt7697_ethernet_to_80211(struct sk_buff *skb,
dev_dbg(cfg->dev, "%s(): Tx 802.3 Frame len(%u)\n",
__func__, skb->len);
print_hex_dump(KERN_DEBUG, DRVNAME" 802.3 Frame ", DUMP_PREFIX_OFFSET,
16, 1, skb->data, skb->len, 0);
16, 1, skb->data, skb->len, 0);
fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* DA BSSID SA */
hdr.frame_control = fc;
switch (vif->wdev.iftype) {
case NL80211_IFTYPE_STATION:
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
/* BSSID SA DA */
hdr.frame_control = fc;
memcpy(hdr.addr1, vif->bssid, ETH_ALEN);
memcpy(hdr.addr2, eth_hdr->h_source, ETH_ALEN);
memcpy(hdr.addr3, eth_hdr->h_dest, ETH_ALEN);
break;
case NL80211_IFTYPE_AP:
fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
/* DA BSSID SA */
hdr.frame_control = fc;
memcpy(hdr.addr1, eth_hdr->h_dest, ETH_ALEN);
memcpy(hdr.addr2, vif->bssid, ETH_ALEN);
memcpy(hdr.addr3, eth_hdr->h_source, ETH_ALEN);
break;
default:
dev_warn(cfg->dev, "%s(): unsupported iftype(%d)\n",
__func__, vif->wdev.iftype);
ret = -EINVAL;
goto cleanup;
}
hdr.duration_id = 0;
memcpy(hdr.addr1, vif->bssid, ETH_ALEN);
memcpy(hdr.addr2, eth_hdr->h_source, ETH_ALEN);
memcpy(hdr.addr3, eth_hdr->h_dest, ETH_ALEN);
hdr.seq_ctrl = 0;
hdrlen = sizeof(struct ieee80211_hdr_3addr);
......@@ -129,6 +89,9 @@ static void mt7697_ethernet_to_80211(struct sk_buff *skb,
__func__, skb->len);
print_hex_dump(KERN_DEBUG, DRVNAME" <-- Tx 802.11 Frame ",
DUMP_PREFIX_OFFSET, 16, 1, skb->data, skb->len, 0);
cleanup:
return ret;
}
int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
......@@ -162,7 +125,12 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
}
}
mt7697_ethernet_to_80211(skb, ndev);
ret = mt7697_ethernet_to_80211(skb, ndev);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_ethernet_to_80211() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cookie = mt7697_alloc_cookie(cfg);
if (cookie == NULL) {
......@@ -173,7 +141,13 @@ int mt7697_data_tx(struct sk_buff *skb, struct net_device *ndev)
dev_dbg(cfg->dev, "%s(): tx cookie/cnt(0x%p/%u)\n",
__func__, cookie, cfg->cookie_count);
cookie->skb = skb;
schedule_work(&cfg->tx_work);
ret = queue_work(cfg->tx_workq, &cfg->tx_work);
if (ret < 0) {
dev_err(cfg->dev, "%s(): queue_work() failed(%d)\n",
__func__, ret);
goto cleanup;
}
return NETDEV_TX_OK;
......@@ -216,7 +190,6 @@ void mt7697_tx_work(struct work_struct *work)
goto cleanup;
}
ret = mt7697_wr_tx_raw_packet(cfg, cookie->skb->data,
cookie->skb->len);
if (ret < 0) {
......@@ -286,22 +259,27 @@ int mt7697_rx_data(struct mt7697_cfg80211_info *cfg, u32 len, u32 if_idx)
memcpy(skb->data, cfg->rx_data, len);
skb->dev = vif->ndev;
ret = mt7697_80211_to_ethernet(skb, vif->ndev);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_80211_to_ethernet() failed(%d)\n",
__func__, ret);
goto cleanup;
}
vif->net_stats.rx_packets++;
vif->net_stats.rx_bytes += len;
netif_rx_ni(skb);
skb->protocol = eth_type_trans(skb, skb->dev);
ret = netif_rx_ni(skb);
if (ret != NET_RX_SUCCESS) {
if (ret == NET_RX_DROP) {
dev_warn(cfg->dev, "%s(): rx frame dropped\n", __func__);
vif->net_stats.rx_dropped++;
ret = 0;
goto cleanup;
}
dev_err(cfg->dev, "%s(): netif_rx_ni() failed(%d)\n", __func__, ret);
goto cleanup;
}
cleanup:
if (ret < 0) {
vif->net_stats.tx_errors++;
vif->net_stats.rx_errors++;
if (skb) dev_kfree_skb(skb);
}
......
......@@ -36,7 +36,7 @@
/**@brief Specifies 20MHz | 40MHz bandwidth in the 2.4GHz band.
*/
#define MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_2040MHZ (MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_20MHZ | \
MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_40MHZ)
MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_40MHZ)
/**
* @brief Station operation mode. In this mode the device works as a Wi-Fi client.
......@@ -50,7 +50,8 @@
/**
* @brief Repeater mode. There are two virtual ports in repeater mode, one is #WIFI_PORT_AP, and the other is #WIFI_PORT_APCLI.
* Both ports should be configured to operate on the same channel with the same bandwidth, while their other settings can be different. For example, both ports can have different MAC addresses and security modes.
* Both ports should be configured to operate on the same channel with the same bandwidth, while their other settings can be different.
* For example, both ports can have different MAC addresses and security modes.
*/
#define MT7697_WIFI_MODE_REPEATER (3)
......@@ -63,7 +64,7 @@
*/
#define MT7697_WIFI_MODE_MONITOR (4)
enum mt7697_port_types {
enum mt7697_port_type {
MT7697_PORT_STA = 0,
MT7697_PORT_APCLI = MT7697_PORT_STA,
MT7697_PORT_AP,
......@@ -192,9 +193,9 @@ struct mt7697_wifi_ap_config_t {
/** @brief Wi-Fi configuration for initialization.
*/
struct mt7697_wifi_config_t {
u8 opmode; /**< The operation mode. The value should be #WIFI_MODE_STA_ONLY, #WIFI_MODE_AP_ONLY, #WIFI_MODE_REPEATER or #WIFI_MODE_MONITOR*/
struct mt7697_wifi_sta_config_t sta_cfg; /**< The configurations for the STA. It should be set when the OPMODE is #WIFI_MODE_STA_ONLY or #WIFI_MODE_REPEATER. */
struct mt7697_wifi_ap_config_t ap_cfg; /**< The configurations for the AP. It should be set when the OPMODE is #WIFI_MODE_AP_ONLY or #WIFI_MODE_REPEATER. */
u8 opmode; /**< The operation mode. The value should be #WIFI_MODE_STA_ONLY, #WIFI_MODE_AP_ONLY, #WIFI_MODE_REPEATER or #WIFI_MODE_MONITOR*/
struct mt7697_wifi_sta_config_t sta; /**< The configurations for the STA. It should be set when the OPMODE is #WIFI_MODE_STA_ONLY or #WIFI_MODE_REPEATER. */
struct mt7697_wifi_ap_config_t ap; /**< The configurations for the AP. It should be set when the OPMODE is #WIFI_MODE_AP_ONLY or #WIFI_MODE_REPEATER. */
} __attribute__((__packed__));
#endif
......@@ -21,11 +21,13 @@
#include "wmi.h"
#include "core.h"
#include "cfg80211.h"
#include "wifi_api.h"
static int mt7697_proc_mac_addr(const struct mt7697q_rsp_hdr* rsp,
struct mt7697_cfg80211_info *cfg)
{
u8 addr[LEN32_ALIGNED(ETH_ALEN)];
char iname[MT7697_IFACE_NAME_LEN];
struct wireless_dev *wdev;
int ret = 0;
......@@ -54,13 +56,16 @@ static int mt7697_proc_mac_addr(const struct mt7697q_rsp_hdr* rsp,
rtnl_lock();
wdev = mt7697_interface_add(cfg, "wlan%d", NL80211_IFTYPE_STATION, 0);
snprintf(iname, MT7697_IFACE_NAME_LEN, "wlan%d", cfg->vif_start);
wdev = mt7697_interface_add(cfg, iname,
(cfg->wifi_cfg.opmode == MT7697_WIFI_MODE_STA_ONLY) ?
NL80211_IFTYPE_STATION : NL80211_IFTYPE_AP, 0);
rtnl_unlock();
if (!wdev) {
dev_err(cfg->dev, "%s(): mt7697_interface_add() failed\n",
__func__);
__func__);
ret = -ENOMEM;
goto cleanup;
}
......@@ -146,168 +151,116 @@ static int mt7697_proc_get_cfg(const struct mt7697q_rsp_hdr* rsp,
wifi_cfg = (struct mt7697_wifi_config_t*)rd_buf;
dev_dbg(cfg->dev, "%s(): operation mode(%u)\n",
__func__, wifi_cfg->opmode);
if (wifi_cfg->opmode == MT7697_WIFI_MODE_STA_ONLY)
cfg->port_type = MT7697_PORT_STA;
else if (wifi_cfg->opmode == MT7697_WIFI_MODE_AP_ONLY)
cfg->port_type = MT7697_PORT_AP;
else {
dev_err(cfg->dev,
"%s(): unsupported operation mode(%d)\n",
__func__, wifi_cfg->opmode);
ret = -EINVAL;
goto cleanup;
}
if ((wifi_cfg->opmode == MT7697_WIFI_MODE_STA_ONLY) ||
(wifi_cfg->opmode == MT7697_WIFI_MODE_REPEATER)) {
dev_dbg(cfg->dev, "%s(): STA ssid len(%u)\n",
__func__, wifi_cfg->sta_cfg.ssid_len);
if (wifi_cfg->sta_cfg.ssid_len > 0) {
if (wifi_cfg->sta_cfg.ssid_len > IEEE80211_MAX_SSID_LEN) {
__func__, wifi_cfg->sta.ssid_len);
if (wifi_cfg->sta.ssid_len > 0) {
if (wifi_cfg->sta.ssid_len > IEEE80211_MAX_SSID_LEN) {
dev_err(cfg->dev,
"%s(): invalid STA SSID len(%u > %u)\n",
__func__,
wifi_cfg->sta_cfg.ssid_len,
__func__, wifi_cfg->sta.ssid_len,
IEEE80211_MAX_SSID_LEN);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): STA ssid('%s')\n",
__func__, wifi_cfg->sta_cfg.ssid);
__func__, wifi_cfg->sta.ssid);
}
if (wifi_cfg->sta_cfg.bssid_present) {
if (wifi_cfg->sta.bssid_present) {
print_hex_dump(KERN_DEBUG, DRVNAME"STA BSSID ",
DUMP_PREFIX_OFFSET, 16, 1,
wifi_cfg->sta_cfg.bssid, ETH_ALEN, 0);
wifi_cfg->sta.bssid, ETH_ALEN, 0);
}
dev_dbg(cfg->dev, "%s(): STA passphrase len(%u)\n",
__func__, wifi_cfg->sta_cfg.pw_len);
if (wifi_cfg->sta_cfg.pw_len > 0) {
if (wifi_cfg->sta_cfg.pw_len > MT7697_WIFI_LENGTH_PASSPHRASE) {
__func__, wifi_cfg->sta.pw_len);
if (wifi_cfg->sta.pw_len > 0) {
if (wifi_cfg->sta.pw_len > MT7697_WIFI_LENGTH_PASSPHRASE) {
dev_err(cfg->dev,
"%s(): invalid STA passphrase len(%u > %u)\n",
__func__,
wifi_cfg->sta_cfg.pw_len,
__func__, wifi_cfg->sta.pw_len,
MT7697_WIFI_LENGTH_PASSPHRASE);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): STA passphrase('%s')\n",
__func__, wifi_cfg->sta_cfg.pw);
__func__, wifi_cfg->sta.pw);
}
}
if ((wifi_cfg->opmode == MT7697_WIFI_MODE_AP_ONLY) ||
(wifi_cfg->opmode == MT7697_WIFI_MODE_REPEATER)) {
dev_dbg(cfg->dev, "%s(): AP ssid len(%u)\n",
__func__, wifi_cfg->ap_cfg.ssid_len);
if (wifi_cfg->ap_cfg.ssid_len > 0) {
if (wifi_cfg->ap_cfg.ssid_len > IEEE80211_MAX_SSID_LEN) {
__func__, wifi_cfg->ap.ssid_len);
if (wifi_cfg->ap.ssid_len > 0) {
if (wifi_cfg->ap.ssid_len > IEEE80211_MAX_SSID_LEN) {
dev_err(cfg->dev,
"%s(): invalid AP SSID len(%u > %u)\n",
__func__,
wifi_cfg->ap_cfg.ssid_len,
__func__, wifi_cfg->ap.ssid_len,
IEEE80211_MAX_SSID_LEN);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): AP ssid('%s')\n",
__func__, wifi_cfg->ap_cfg.ssid);
__func__, wifi_cfg->ap.ssid);
}
dev_dbg(cfg->dev, "%s(): AP passphrase len(%u)\n",
__func__, wifi_cfg->ap_cfg.pw_len);
if (wifi_cfg->ap_cfg.pw_len > 0) {
if (wifi_cfg->ap_cfg.pw_len > MT7697_WIFI_LENGTH_PASSPHRASE) {
__func__, wifi_cfg->ap.pw_len);
if (wifi_cfg->ap.pw_len > 0) {
if (wifi_cfg->ap.pw_len > MT7697_WIFI_LENGTH_PASSPHRASE) {
dev_err(cfg->dev,
"%s(): invalid AP passphrase len(%u > %u)\n",
__func__,
wifi_cfg->ap_cfg.pw_len,
__func__, wifi_cfg->ap.pw_len,
MT7697_WIFI_LENGTH_PASSPHRASE);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): AP passphrase('%s')\n",
__func__, wifi_cfg->ap_cfg.pw);
__func__, wifi_cfg->ap.pw);
}
dev_dbg(cfg->dev, "%s(): AP auth mode(%u) encrypt type(%u)\n",
__func__, wifi_cfg->ap_cfg.auth_mode,
wifi_cfg->ap_cfg.encrypt_type);
__func__, wifi_cfg->ap.auth_mode,
wifi_cfg->ap.encrypt_type);
dev_dbg(cfg->dev, "%s(): AP channel(%u) bandwidth(%u)\n",
__func__, wifi_cfg->ap_cfg.ch,
wifi_cfg->ap_cfg.bandwidth);
if (wifi_cfg->ap_cfg.bandwidth == MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_40MHZ) {
__func__, wifi_cfg->ap.ch, wifi_cfg->ap.bandwidth);
if (wifi_cfg->ap.bandwidth == MT7697_WIFI_IOT_COMMAND_CONFIG_BANDWIDTH_40MHZ) {
dev_dbg(cfg->dev, "%s(): AP bandwidth ext(%u)\n",
__func__, wifi_cfg->ap_cfg.bandwidth_ext);
__func__, wifi_cfg->ap.bandwidth_ext);
}
}
memcpy(&cfg->wifi_cfg, cfg, sizeof(struct mt7697_wifi_config_t));
memcpy(&cfg->wifi_cfg, wifi_cfg, sizeof(struct mt7697_wifi_config_t));
cleanup:
if (rd_buf) kfree(rd_buf);
return ret;
}
static int mt7697_proc_get_rx_filter(const struct mt7697q_rsp_hdr* rsp,
struct mt7697_cfg80211_info *cfg)
{
u32 rx_filter;
int ret = 0;
dev_dbg(cfg->dev, "%s(): --> GET RX FILTER\n", __func__);
if (rsp->cmd.len - sizeof(struct mt7697q_rsp_hdr) != sizeof(u32)) {
ret = mt7697_cfg80211_get_params(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): invalid rx filter rsp len(%u != %u)\n",
__func__,
rsp->cmd.len - sizeof(struct mt7697q_rsp_hdr),
sizeof(u32));
ret = -EINVAL;
goto cleanup;
}
ret = cfg->hif_ops->read(cfg->rxq_hdl, (u32*)&rx_filter,
LEN_TO_WORD(sizeof(u32)));
if (ret != LEN_TO_WORD(sizeof(u32))) {
dev_err(cfg->dev, "%s(): read() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(sizeof(rx_filter)));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
cfg->rx_filter = rx_filter;
dev_dbg(cfg->dev, "%s(): rx filter(0x%08x)\n",
__func__, cfg->rx_filter);
cleanup:
return ret;
}
static int mt7697_proc_get_smart_conn_filter(const struct mt7697q_rsp_hdr* rsp,
struct mt7697_cfg80211_info *cfg)
{
u32 smart_conn_filter;
int ret = 0;
dev_dbg(cfg->dev, "%s(): --> GET SMART CONN FILTER\n", __func__);
if (rsp->cmd.len - sizeof(struct mt7697q_rsp_hdr) != sizeof(smart_conn_filter)) {
dev_err(cfg->dev, "%s(): invalid rx filter rsp len(%u != %u)\n",
__func__,
rsp->cmd.len - sizeof(struct mt7697q_rsp_hdr),
sizeof(smart_conn_filter));
ret = -EINVAL;
goto cleanup;
"%s(): mt7697_cfg80211_get_params() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = cfg->hif_ops->read(cfg->rxq_hdl, (u32*)&smart_conn_filter,
LEN_TO_WORD(sizeof(u32)));
if (ret != LEN_TO_WORD(sizeof(u32))) {
dev_err(cfg->dev, "%s(): read() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(sizeof(u32)));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
cfg->smart_conn_filter = smart_conn_filter;
dev_dbg(cfg->dev, "%s(): smart connection filter(%u)\n",
__func__, cfg->smart_conn_filter);
cleanup:
if (rd_buf) kfree(rd_buf);
return ret;
}
......@@ -543,7 +496,7 @@ static int mt7697_proc_scan_rsp(const struct mt7697q_rsp_hdr* rsp,
if (!vif) {
dev_err(cfg->dev,
"%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
......@@ -587,36 +540,16 @@ static int mt7697_proc_scan_complete_ind(struct mt7697_cfg80211_info *cfg)
dev_dbg(cfg->dev, "%s(): vif(%u)\n", __func__, vif->fw_vif_idx);
cfg80211_scan_done(vif->scan_req, false);
vif->scan_req = NULL;
/*
ret = mt7697_wr_scan_stop_req(cfg);
if (ret < 0) {
dev_err(cfg->dev, "%s(): mt7697_wr_scan_stop_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}*/
cleanup:
return ret;
}
static void mt7697_proc_reg_rx_hndlr(struct mt7697_cfg80211_info *cfg)
{
dev_dbg(cfg->dev, "%s(): --> REGISTER RX HANDLER RSP\n", __func__);
cfg->reg_rx_hndlr = true;
}
static void mt7697_proc_unreg_rx_hndlr(struct mt7697_cfg80211_info *cfg)
{
dev_dbg(cfg->dev, "%s(): --> UNREGISTER RX HANDLER RSP\n", __func__);
cfg->reg_rx_hndlr = false;
}
static int mt7697_proc_connect_ind(const struct mt7697q_rsp_hdr* rsp,
struct mt7697_cfg80211_info *cfg)
{
u8 bssid[LEN32_ALIGNED(ETH_ALEN)];
struct mt7697_vif *vif;
// enum mt7697_wifi_rx_filter_t rx_filter = cfg->rx_filter;
u32 if_idx;
u32 channel;
int ret;
......@@ -662,97 +595,57 @@ static int mt7697_proc_connect_ind(const struct mt7697q_rsp_hdr* rsp,
print_hex_dump(KERN_DEBUG, DRVNAME" BSSID ",
DUMP_PREFIX_OFFSET, 16, 1, bssid, ETH_ALEN, 0);
vif = mt7697_get_vif_by_idx(cfg, if_idx);
if (!vif) {
dev_err(cfg->dev, "%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
/*
rx_filter &= ~BIT(MT7697_WIFI_RX_FILTER_DROP_NOT_MY_BSSID);
rx_filter &= ~BIT(MT7697_WIFI_RX_FILTER_DROP_NOT_UC2ME);
rx_filter |= BIT(MT7697_WIFI_RX_FILTER_DROP_PROBE_REQ);
rx_filter |= BIT(MT7697_WIFI_RX_FILTER_DROP_STBC_BCN_BC_MC);
rx_filter &= ~BIT(MT7697_WIFI_RX_FILTER_DROP_BC_FRAME);
rx_filter &= ~BIT(MT7697_WIFI_RX_FILTER_DROP_MC_FRAME);
if (rx_filter != cfg->rx_filter) {
ret = mt7697_wr_set_rx_filter_req(cfg, cfg->rx_filter);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_rx_filter_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cfg->rx_filter = rx_filter;
if (list_empty(&cfg->vif_list)) {
dev_dbg(cfg->dev, "%s(): no interfaces\n", __func__);
goto cleanup;
}
if (!cfg->smart_conn_filter) {
ret = mt7697_wr_set_smart_conn_filter_req(cfg, true);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_smart_conn_filter_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
if (cfg->wifi_cfg.opmode == MT7697_WIFI_MODE_STA_ONLY) {
vif = mt7697_get_vif_by_idx(cfg, if_idx);
if (!vif) {
dev_err(cfg->dev, "%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
cfg->smart_conn_filter = true;
}
*/
if (!cfg->reg_rx_hndlr) {
/* ret = mt7697_wr_set_op_mode_req(cfg, MT7697_WIFI_MODE_MONITOR);
dev_dbg(cfg->dev, "%s(): vif(%u)\n", __func__, vif->fw_vif_idx);
ret = mt7697_cfg80211_connect_event(vif, bssid, channel);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
"%s(): mt7697_cfg80211_connect_event() failed(%d)\n",
__func__, ret);
goto cleanup;
}
ret = mt7697_wr_reg_rx_hndlr_req(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_reg_rx_hndlr_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}*/
}
else {
// struct station_info sinfo = {0};
dev_dbg(cfg->dev, "%s(): vif(%u)\n", __func__, vif->fw_vif_idx);
ret = mt7697_cfg80211_connect_event(vif, bssid, channel);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_cfg80211_connect_event() failed(%d)\n",
__func__, ret);
goto cleanup;
}
cleanup:
return ret;
}
static int mt7697_proc_disconnect_rsp(struct mt7697_cfg80211_info *cfg)
{
int ret;
dev_dbg(cfg->dev, "%s(): --> DISCONNECT RSP\n", __func__);
vif = mt7697_get_vif_by_idx(cfg, 0);
if (!vif) {
dev_err(cfg->dev, "%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
if (cfg->reg_rx_hndlr) {
/* ret = mt7697_wr_set_op_mode_req(cfg, cfg->wifi_cfg.opmode);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_set_op_mode_req() failed(%d)\n",
__func__, ret);
goto cleanup;
}
*/
ret = mt7697_wr_unreg_rx_hndlr_req(cfg);
// cfg80211_new_sta(vif->ndev, bssid, &sinfo, GFP_KERNEL);
ret = mt7697_cfg80211_new_sta(vif, bssid);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_wr_unreg_rx_hndlr_req() failed(%d)\n",
"%s(): mt7697_cfg80211_new_sta() failed(%d)\n",
__func__, ret);
goto cleanup;
}
netif_wake_queue(vif->ndev);
/* Update connect & link status atomically */
spin_lock_bh(&vif->if_lock);
set_bit(CONNECTED, &vif->flags);
clear_bit(CONNECT_PEND, &vif->flags);
netif_carrier_on(vif->ndev);
spin_unlock_bh(&vif->if_lock);
}
cleanup:
......@@ -791,26 +684,53 @@ static int mt7697_proc_disconnect_ind(struct mt7697_cfg80211_info *cfg)
print_hex_dump(KERN_DEBUG, DRVNAME" BSSID ",
DUMP_PREFIX_OFFSET, 16, 1, bssid, ETH_ALEN, 0);
vif = mt7697_get_vif_by_idx(cfg, if_idx);
if (!vif) {
dev_err(cfg->dev, "%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
if (list_empty(&cfg->vif_list)) {
dev_dbg(cfg->dev, "%s(): no interfaces\n", __func__);
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): vif(%u)\n", __func__, vif->fw_vif_idx);
if (vif->sme_state == SME_CONNECTING)
cfg80211_connect_result(vif->ndev, bssid,
NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
else if (vif->sme_state == SME_CONNECTED) {
cfg80211_disconnected(vif->ndev, proto_reason,
NULL, 0, GFP_KERNEL);
if (cfg->wifi_cfg.opmode == MT7697_WIFI_MODE_STA_ONLY) {
vif = mt7697_get_vif_by_idx(cfg, if_idx);
if (!vif) {
dev_err(cfg->dev, "%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
dev_dbg(cfg->dev, "%s(): vif(%u)\n", __func__, vif->fw_vif_idx);
if (vif->sme_state == SME_CONNECTING)
cfg80211_connect_result(vif->ndev, bssid,
NULL, 0,
NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
else if (vif->sme_state == SME_CONNECTED) {
cfg80211_disconnected(vif->ndev, proto_reason,
NULL, 0, GFP_KERNEL);
}
}
else {
vif = mt7697_get_vif_by_idx(cfg, 0);
if (!vif) {
dev_err(cfg->dev,
"%s(): mt7697_get_vif_by_idx(%u) failed\n",
__func__, if_idx);
ret = -EINVAL;
goto cleanup;
}
// cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL);
ret = mt7697_cfg80211_del_sta(vif, bssid);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_cfg80211_del_sta() failed(%d)\n",
__func__, ret);
goto cleanup;
}
}
netif_stop_queue(vif->ndev);
vif->sme_state = SME_DISCONNECTED;
spin_lock_bh(&vif->if_lock);
clear_bit(CONNECT_PEND, &vif->flags);
......@@ -856,6 +776,9 @@ static int mt7697_rx_raw(const struct mt7697q_rsp_hdr* rsp,
goto cleanup;
}
print_hex_dump(KERN_DEBUG, DRVNAME" RX ", DUMP_PREFIX_OFFSET,
16, 1, cfg->rx_data, rsp->result, 0);
/* TODO: interface index come from MT7697 */
ret = mt7697_rx_data(cfg, rsp->result, 0);
if (ret) {
......@@ -904,26 +827,6 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
}
break;
case MT7697_CMD_GET_RX_FILTER_RSP:
ret = mt7697_proc_get_rx_filter(rsp, cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_proc_get_rx_filter() failed(%d)\n",
__func__, ret);
goto cleanup;
}
break;
case MT7697_CMD_GET_SMART_CONN_FILTER_RSP:
ret = mt7697_proc_get_smart_conn_filter(rsp, cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_proc_get_smart_conn_filter() failed(%d)\n",
__func__, ret);
goto cleanup;
}
break;
case MT7697_CMD_GET_RADIO_STATE_RSP:
ret = mt7697_proc_get_radio_state(rsp, cfg);
if (ret < 0) {
......@@ -974,14 +877,6 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
}
break;
case MT7697_CMD_REGISTER_RX_HNDLR_RSP:
mt7697_proc_reg_rx_hndlr(cfg);
break;
case MT7697_CMD_UNREGISTER_RX_HNDLR_RSP:
mt7697_proc_unreg_rx_hndlr(cfg);
break;
case MT7697_CMD_CONNECT_IND:
ret = mt7697_proc_connect_ind(rsp, cfg);
if (ret < 0) {
......@@ -992,16 +887,6 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
}
break;
case MT7697_CMD_DISCONNECT_RSP:
ret = mt7697_proc_disconnect_rsp(cfg);
if (ret < 0) {
dev_err(cfg->dev,
"%s(): mt7697_proc_disconnect_rsp() failed(%d)\n",
__func__, ret);
goto cleanup;
}
break;
case MT7697_CMD_DISCONNECT_IND:
ret = mt7697_proc_disconnect_ind(cfg);
if (ret < 0) {
......@@ -1021,6 +906,10 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
}
break;
case MT7697_CMD_SET_OP_MODE_RSP:
dev_dbg(cfg->dev, "%s(): --> SET OP MODE\n", __func__);
break;
case MT7697_CMD_SET_PMK_RSP:
dev_dbg(cfg->dev, "%s(): --> SET PMK\n", __func__);
break;
......@@ -1045,10 +934,6 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
dev_dbg(cfg->dev, "%s(): --> SET LISTEN INTERVAL\n", __func__);
break;
case MT7697_CMD_SET_OP_MODE_RSP:
dev_dbg(cfg->dev, "%s(): --> SET OP MODE\n", __func__);
break;
case MT7697_CMD_SET_WIRELESS_MODE_RSP:
dev_dbg(cfg->dev, "%s(): --> SET WIRELESS MODE\n", __func__);
break;
......@@ -1057,15 +942,6 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
dev_dbg(cfg->dev, "%s(): --> SET RADIO STATE\n", __func__);
break;
case MT7697_CMD_SET_RX_FILTER_RSP:
dev_dbg(cfg->dev, "%s(): --> SET RX FILTER\n", __func__);
break;
case MT7697_CMD_SET_SMART_CONN_FILTER_RSP:
dev_dbg(cfg->dev, "%s(): --> SET SMART CONN FILTER\n",
__func__);
break;
case MT7697_CMD_SET_SECURITY_MODE_RSP:
dev_dbg(cfg->dev, "%s(): --> SET SECURITY MODE\n", __func__);
break;
......@@ -1074,6 +950,10 @@ int mt7697_proc_80211cmd(const struct mt7697q_rsp_hdr* rsp, void* priv)
dev_dbg(cfg->dev, "%s(): --> SCAN STOP\n", __func__);
break;
case MT7697_CMD_DISCONNECT_RSP:
dev_dbg(cfg->dev, "%s(): --> DISCONNECT RSP\n", __func__);
break;
default:
dev_err(cfg->dev, "%s(): unsupported cmd(%u)\n",
__func__, rsp->cmd.type);
......@@ -1085,7 +965,7 @@ cleanup:
return ret;
}
int mt7697_wr_get_wireless_mode_req(struct mt7697_cfg80211_info *cfg, u8 port)
int mt7697_wr_get_wireless_mode_req(const struct mt7697_cfg80211_info *cfg)
{
struct mt7697_get_wireless_mode_req req;
int ret;
......@@ -1093,10 +973,10 @@ int mt7697_wr_get_wireless_mode_req(struct mt7697_cfg80211_info *cfg, u8 port)
req.cmd.len = sizeof(struct mt7697_get_wireless_mode_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_GET_WIRELESS_MODE_REQ;
req.port = port;
req.port = cfg->port_type;
dev_dbg(cfg->dev, "%s(): <-- GET WIRELESS MODE PORT(%u) len(%u)\n",
__func__, port, req.cmd.len);
dev_dbg(cfg->dev, "%s(): <-- GET WIRELESS MODE port(%u) len(%u)\n",
__func__, req.port, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
......@@ -1112,7 +992,7 @@ cleanup:
return ret;
}
int mt7697_wr_set_wireless_mode_req(struct mt7697_cfg80211_info *cfg, u8 port,
int mt7697_wr_set_wireless_mode_req(const struct mt7697_cfg80211_info *cfg,
u8 mode)
{
struct mt7697_set_wireless_mode_req req;
......@@ -1121,11 +1001,11 @@ int mt7697_wr_set_wireless_mode_req(struct mt7697_cfg80211_info *cfg, u8 port,
req.cmd.len = sizeof(struct mt7697_set_wireless_mode_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_WIRELESS_MODE_REQ;
req.port = port;
req.port = cfg->port_type;
req.mode = mode;
dev_dbg(cfg->dev, "%s(): <-- SET WIRELESS MODE port(%u) len(%u)\n",
__func__, port, req.cmd.len);
__func__, req.port, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
......@@ -1141,7 +1021,7 @@ cleanup:
return ret;
}
int mt7697_wr_set_pmk_req(struct mt7697_cfg80211_info *cfg, u8 port,
int mt7697_wr_set_pmk_req(const struct mt7697_cfg80211_info *cfg,
const u8 pmk[MT7697_WIFI_LENGTH_PMK])
{
struct mt7697_set_pmk_req req;
......@@ -1150,11 +1030,11 @@ int mt7697_wr_set_pmk_req(struct mt7697_cfg80211_info *cfg, u8 port,
req.cmd.len = sizeof(struct mt7697_set_pmk_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_PMK_REQ;
req.port = port;
req.port = cfg->port_type;
memcpy(req.pmk, pmk, MT7697_WIFI_LENGTH_PMK);
dev_dbg(cfg->dev, "%s(): <-- SET PMK port(%u) len(%u)\n",
__func__, port, req.cmd.len);
__func__, req.port, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(sizeof(struct mt7697_set_pmk_req)));
if (ret != LEN_TO_WORD(sizeof(struct mt7697_set_pmk_req))) {
......@@ -1171,7 +1051,7 @@ cleanup:
return ret;
}
int mt7697_wr_set_channel_req(struct mt7697_cfg80211_info *cfg, u8 port, u8 ch)
int mt7697_wr_set_channel_req(const struct mt7697_cfg80211_info *cfg, u8 ch)
{
struct mt7697_set_channel_req req;
int ret;
......@@ -1179,11 +1059,11 @@ int mt7697_wr_set_channel_req(struct mt7697_cfg80211_info *cfg, u8 port, u8 ch)
req.cmd.len = sizeof(struct mt7697_set_channel_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_CHANNEL_REQ;
req.port = port;
req.port = cfg->port_type;
req.ch = ch;
dev_dbg(cfg->dev, "%s(): <-- SET CHANNEL port(%u) len(%u)\n",
__func__, port, req.cmd.len);
__func__, req.port, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(sizeof(struct mt7697_set_channel_req)));
if (ret != LEN_TO_WORD(sizeof(struct mt7697_set_channel_req))) {
......@@ -1200,7 +1080,8 @@ cleanup:
return ret;
}
int mt7697_wr_set_bssid_req(struct mt7697_cfg80211_info *cfg, const u8 bssid[ETH_ALEN])
int mt7697_wr_set_bssid_req(const struct mt7697_cfg80211_info *cfg,
const u8 bssid[ETH_ALEN])
{
struct mt7697_set_bssid_req req;
int ret;
......@@ -1228,7 +1109,8 @@ cleanup:
return ret;
}
int mt7697_wr_set_ssid_req(struct mt7697_cfg80211_info *cfg, u8 port, u8 len, const u8 ssid[])
int mt7697_wr_set_ssid_req(const struct mt7697_cfg80211_info *cfg,
u8 len, const u8 ssid[])
{
struct mt7697_set_ssid_req req;
int ret;
......@@ -1236,7 +1118,7 @@ int mt7697_wr_set_ssid_req(struct mt7697_cfg80211_info *cfg, u8 port, u8 len, co
req.cmd.len = sizeof(struct mt7697_set_ssid_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_SSID_REQ;
req.port = port;
req.port = cfg->port_type;
req.len = len;
memcpy(req.ssid, ssid, len);
......@@ -1258,17 +1140,18 @@ cleanup:
return ret;
}
int mt7697_wr_reload_settings_req(struct mt7697_cfg80211_info* cfg)
int mt7697_wr_reload_settings_req(const struct mt7697_cfg80211_info* cfg, u8 if_idx)
{
struct mt7697_reload_settings_req req;
int ret;
req.len = sizeof(struct mt7697_reload_settings_req);
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_RELOAD_SETTINGS_REQ;
req.cmd.len = sizeof(struct mt7697_reload_settings_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_RELOAD_SETTINGS_REQ;
req.if_idx = if_idx;
dev_dbg(cfg->dev, "%s(): <-- RELOAD SETTINGS len(%u)\n",
__func__, req.len);
__func__, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(sizeof(struct mt7697_reload_settings_req)));
if (ret != LEN_TO_WORD(sizeof(struct mt7697_reload_settings_req))) {
......@@ -1285,7 +1168,7 @@ cleanup:
return ret;
}
int mt7697_wr_mac_addr_req(struct mt7697_cfg80211_info *cfg, u8 port)
int mt7697_wr_mac_addr_req(const struct mt7697_cfg80211_info *cfg)
{
struct mt7697_mac_addr_req req;
int ret;
......@@ -1293,10 +1176,10 @@ int mt7697_wr_mac_addr_req(struct mt7697_cfg80211_info *cfg, u8 port)
req.cmd.len = sizeof(struct mt7697_mac_addr_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_MAC_ADDR_REQ;
req.port = port;
req.port = cfg->port_type;
dev_dbg(cfg->dev, "%s(): <-- GET MAC ADDRESS port(%u) len(%u)\n",
__func__, port, req.cmd.len);
__func__, req.port, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
......@@ -1312,7 +1195,7 @@ cleanup:
return ret;
}
int mt7697_wr_set_op_mode_req(struct mt7697_cfg80211_info* cfg, u8 opmode)
int mt7697_wr_set_op_mode_req(const struct mt7697_cfg80211_info* cfg)
{
struct mt7697_set_op_mode_req req;
int ret;
......@@ -1320,10 +1203,10 @@ int mt7697_wr_set_op_mode_req(struct mt7697_cfg80211_info* cfg, u8 opmode)
req.cmd.len = sizeof(struct mt7697_set_op_mode_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_OP_MODE_REQ;
req.opmode = opmode;
req.opmode = cfg->wifi_cfg.opmode;
dev_dbg(cfg->dev, "%s(): <-- SET OPMODE(%u) len(%u)\n",
__func__, opmode, req.cmd.len);
__func__, req.opmode, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
......@@ -1339,7 +1222,7 @@ cleanup:
return ret;
}
int mt7697_wr_cfg_req(struct mt7697_cfg80211_info *cfg)
int mt7697_wr_cfg_req(const struct mt7697_cfg80211_info *cfg)
{
struct mt7697_cfg_req req;
int ret;
......@@ -1348,34 +1231,7 @@ int mt7697_wr_cfg_req(struct mt7697_cfg80211_info *cfg)
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_GET_CFG_REQ;
dev_dbg(cfg->dev, "%s(): <-- GET CONFIG len(%u)\n",
__func__, req.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.len));
if (ret != LEN_TO_WORD(req.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_reg_rx_hndlr_req(struct mt7697_cfg80211_info* cfg)
{
struct mt7697_register_rx_hndlr_req req;
int ret;
req.len = sizeof(struct mt7697_register_rx_hndlr_req);
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_REGISTER_RX_HNDLR_REQ;
dev_dbg(cfg->dev, "%s(): <-- REGISTER RX HANDLER len(%u)\n",
__func__, req.len);
dev_dbg(cfg->dev, "%s(): <-- GET CONFIG len(%u)\n", __func__, req.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.len));
if (ret != LEN_TO_WORD(req.len)) {
......@@ -1391,33 +1247,7 @@ cleanup:
return ret;
}
int mt7697_wr_unreg_rx_hndlr_req(struct mt7697_cfg80211_info* cfg)
{
struct mt7697_unregister_rx_hndlr_req req;
int ret;
req.len = sizeof(struct mt7697_unregister_rx_hndlr_req);
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_UNREGISTER_RX_HNDLR_REQ;
dev_dbg(cfg->dev, "%s(): <-- UNREGISTER RX HANDLER len(%u)\n",
__func__, req.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.len));
if (ret != LEN_TO_WORD(req.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_get_radio_state_req(struct mt7697_cfg80211_info* cfg)
int mt7697_wr_get_radio_state_req(const struct mt7697_cfg80211_info* cfg)
{
struct mt7697_get_radio_state_req req;
int ret;
......@@ -1443,7 +1273,8 @@ cleanup:
return ret;
}
int mt7697_wr_set_radio_state_req(struct mt7697_cfg80211_info* cfg, u8 state)
int mt7697_wr_set_radio_state_req(const struct mt7697_cfg80211_info* cfg,
u8 state)
{
struct mt7697_set_radio_state_req req;
int ret;
......@@ -1470,115 +1301,7 @@ cleanup:
return ret;
}
int mt7697_wr_get_rx_filter_req(struct mt7697_cfg80211_info* cfg)
{
struct mt7697_get_rx_filter_req req;
int ret;
req.len = sizeof(struct mt7697_get_rx_filter_req);
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_GET_RX_FILTER_REQ;
dev_dbg(cfg->dev, "%s(): <-- GET RX FILTER len(%u)\n",
__func__, req.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.len));
if (ret != LEN_TO_WORD(req.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_set_rx_filter_req(struct mt7697_cfg80211_info* cfg,
u32 rx_filter)
{
struct mt7697_set_rx_filter_req req;
int ret;
req.cmd.len = sizeof(struct mt7697_set_rx_filter_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_RX_FILTER_REQ;
req.rx_filter = rx_filter;
dev_dbg(cfg->dev, "%s(): <-- SET RX FILTER(0x%08x) len(%u)\n",
__func__, rx_filter, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.cmd.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_get_smart_conn_filter_req(struct mt7697_cfg80211_info* cfg)
{
struct mt7697_get_smart_conn_filter_req req;
int ret;
req.len = sizeof(struct mt7697_get_smart_conn_filter_req);
req.grp = MT7697_CMD_GRP_80211;
req.type = MT7697_CMD_GET_SMART_CONN_FILTER_REQ;
dev_dbg(cfg->dev, "%s(): <-- GET SMART CONN FILTER len(%u)\n",
__func__, req.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.len));
if (ret != LEN_TO_WORD(req.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_set_smart_conn_filter_req(struct mt7697_cfg80211_info* cfg,
u8 flag)
{
struct mt7697_set_smart_conn_filter_req req;
int ret;
req.cmd.len = sizeof(struct mt7697_set_smart_conn_filter_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_SMART_CONN_FILTER_REQ;
req.flag = flag;
dev_dbg(cfg->dev, "%s(): <-- SET SMART CONN FILTER(%u) len(%u)\n",
__func__, flag, req.cmd.len);
ret = cfg->hif_ops->write(cfg->txq_hdl, (const u32*)&req,
LEN_TO_WORD(req.cmd.len));
if (ret != LEN_TO_WORD(req.cmd.len)) {
dev_err(cfg->dev, "%s(): write() failed(%d != %d)\n",
__func__, ret, LEN_TO_WORD(req.cmd.len));
ret = (ret < 0) ? ret:-EIO;
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
int mt7697_wr_get_listen_interval_req(struct mt7697_cfg80211_info* cfg)
int mt7697_wr_get_listen_interval_req(const struct mt7697_cfg80211_info* cfg)
{
struct mt7697_get_listen_interval_req req;
int ret;
......@@ -1604,7 +1327,7 @@ cleanup:
return ret;
}
int mt7697_wr_set_listen_interval_req(struct mt7697_cfg80211_info* cfg,
int mt7697_wr_set_listen_interval_req(const struct mt7697_cfg80211_info* cfg,
u32 interval)
{
struct mt7697_set_listen_interval_req req;
......@@ -1632,8 +1355,8 @@ cleanup:
return ret;
}
int mt7697_wr_set_security_mode_req(struct mt7697_cfg80211_info* cfg,
u8 port, u8 auth_mode, u8 encrypt_type)
int mt7697_wr_set_security_mode_req(const struct mt7697_cfg80211_info* cfg,
u8 auth_mode, u8 encrypt_type)
{
struct mt7697_set_security_mode_req req;
int ret;
......@@ -1641,7 +1364,7 @@ int mt7697_wr_set_security_mode_req(struct mt7697_cfg80211_info* cfg,
req.cmd.len = sizeof(struct mt7697_set_security_mode_req);
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_SET_SECURITY_MODE_REQ;
req.port = port;
req.port = cfg->port_type;
req.auth_mode = auth_mode;
req.encrypt_type = encrypt_type;
......@@ -1663,8 +1386,8 @@ cleanup:
return ret;
}
int mt7697_wr_get_security_mode_req(struct mt7697_cfg80211_info* cfg,
u32 if_idx, u8 port)
int mt7697_wr_get_security_mode_req(const struct mt7697_cfg80211_info* cfg,
u32 if_idx)
{
struct mt7697_get_security_mode_req req;
int ret;
......@@ -1673,7 +1396,7 @@ int mt7697_wr_get_security_mode_req(struct mt7697_cfg80211_info* cfg,
req.cmd.grp = MT7697_CMD_GRP_80211;
req.cmd.type = MT7697_CMD_GET_SECURITY_MODE_REQ;
req.if_idx = if_idx;
req.port = port;
req.port = cfg->port_type;
dev_dbg(cfg->dev, "%s(): <-- GET SECURITY MODE len(%u)\n",
__func__, req.cmd.len);
......@@ -1692,7 +1415,7 @@ cleanup:
return ret;
}
int mt7697_wr_scan_req(struct mt7697_cfg80211_info *cfg, u32 if_idx,
int mt7697_wr_scan_req(const struct mt7697_cfg80211_info *cfg, u32 if_idx,
const struct cfg80211_scan_request *req)
{
struct mt7697_scan_req scan_req;
......@@ -1736,7 +1459,7 @@ cleanup:
return ret;
}
int mt7697_wr_scan_stop_req(struct mt7697_cfg80211_info* cfg)
int mt7697_wr_scan_stop_req(const struct mt7697_cfg80211_info* cfg)
{
struct mt7697_scan_stop req;
int ret;
......@@ -1761,8 +1484,8 @@ cleanup:
return ret;
}
int mt7697_wr_disconnect_req(struct mt7697_cfg80211_info *cfg, u32 if_idx,
const u8 *addr)
int mt7697_wr_disconnect_req(const struct mt7697_cfg80211_info *cfg,
u32 if_idx, const u8 *addr)
{
struct mt7697_disconnect_req req;
int ret;
......
......@@ -33,9 +33,6 @@
#define mt7697_get_listen_interval_req mt7697q_cmd_hdr
#define mt7697_get_smart_conn_filter_req mt7697q_cmd_hdr
#define mt7697_scan_stop mt7697q_cmd_hdr
#define mt7697_register_rx_hndlr_req mt7697q_cmd_hdr
#define mt7697_unregister_rx_hndlr_req mt7697q_cmd_hdr
#define mt7697_reload_settings_req mt7697q_cmd_hdr
#define mt7697_set_wireless_mode_rsp mt7697q_rsp_hdr
#define mt7697_set_radio_state_rsp mt7697q_rsp_hdr
......@@ -49,8 +46,6 @@
#define mt7697_set_ssid_rsp mt7697q_rsp_hdr
#define mt7697_set_security_mode_rsp mt7697q_rsp_hdr
#define mt7697_scan_stop_rsp mt7697q_rsp_hdr
#define mt7697_register_rx_hndlr_rsp mt7697q_rsp_hdr
#define mt7697_unregister_rx_hndlr_rsp mt7697q_rsp_hdr
#define mt7697_reload_settings_rsp mt7697q_rsp_hdr
#define mt7697_disconnect_rsp mt7697q_rsp_hdr
......@@ -80,11 +75,7 @@ enum mt7697_wifi_cmd_types {
MT7697_CMD_GET_RADIO_STATE_REQ,
MT7697_CMD_GET_RADIO_STATE_RSP,
MT7697_CMD_SET_RADIO_STATE_REQ,
MT7697_CMD_SET_RADIO_STATE_RSP,
MT7697_CMD_GET_RX_FILTER_REQ,
MT7697_CMD_GET_RX_FILTER_RSP,
MT7697_CMD_SET_RX_FILTER_REQ,
MT7697_CMD_SET_RX_FILTER_RSP,
MT7697_CMD_SET_RADIO_STATE_RSP,
MT7697_CMD_GET_LISTEN_INTERVAL_REQ,
MT7697_CMD_GET_LISTEN_INTERVAL_RSP,
MT7697_CMD_SET_LISTEN_INTERVAL_REQ,
......@@ -92,15 +83,7 @@ enum mt7697_wifi_cmd_types {
MT7697_CMD_SET_SECURITY_MODE_REQ,
MT7697_CMD_SET_SECURITY_MODE_RSP,
MT7697_CMD_GET_SECURITY_MODE_REQ,
MT7697_CMD_GET_SECURITY_MODE_RSP,
MT7697_CMD_GET_SMART_CONN_FILTER_REQ,
MT7697_CMD_GET_SMART_CONN_FILTER_RSP,
MT7697_CMD_SET_SMART_CONN_FILTER_REQ,
MT7697_CMD_SET_SMART_CONN_FILTER_RSP,
MT7697_CMD_REGISTER_RX_HNDLR_REQ,
MT7697_CMD_REGISTER_RX_HNDLR_RSP,
MT7697_CMD_UNREGISTER_RX_HNDLR_REQ,
MT7697_CMD_UNREGISTER_RX_HNDLR_RSP,
MT7697_CMD_GET_SECURITY_MODE_RSP,
MT7697_CMD_SCAN_IND,
MT7697_CMD_SCAN_REQ,
MT7697_CMD_SCAN_RSP,
......@@ -174,26 +157,6 @@ struct mt7697_set_radio_state_req {
__be32 state;
} __attribute__((packed, aligned(4)));
struct mt7697_get_rx_filter_rsp {
struct mt7697q_rsp_hdr rsp;
__be32 rx_filter;
} __attribute__((packed, aligned(4)));
struct mt7697_set_rx_filter_req {
struct mt7697q_cmd_hdr cmd;
__be32 rx_filter;
} __attribute__((packed, aligned(4)));
struct mt7697_get_smart_conn_filter_rsp {
struct mt7697q_rsp_hdr rsp;
__be32 flag;
} __attribute__((packed, aligned(4)));
struct mt7697_set_smart_conn_filter_req {
struct mt7697q_cmd_hdr cmd;
__be32 flag;
} __attribute__((packed, aligned(4)));
struct mt7697_get_listen_interval_rsp {
struct mt7697q_rsp_hdr rsp;
__be32 interval;
......@@ -204,6 +167,11 @@ struct mt7697_set_listen_interval_req {
__be32 interval;
} __attribute__((packed, aligned(4)));
struct mt7697_reload_settings_req {
struct mt7697q_cmd_hdr cmd;
__be32 if_idx;
} __attribute__((packed, aligned(4)));
struct mt7697_scan_req {
struct mt7697q_cmd_hdr cmd;
__be32 if_idx;
......@@ -307,35 +275,27 @@ struct mt7697_rx_raw_packet {
u8 data[];
} __attribute__((packed, aligned(4)));
int mt7697_wr_init(struct mt7697_cfg80211_info*);
int mt7697_wr_reset(struct mt7697_cfg80211_info*);
int mt7697_wr_set_wireless_mode_req(struct mt7697_cfg80211_info*, u8, u8);
int mt7697_wr_get_wireless_mode_req(struct mt7697_cfg80211_info*, u8);
int mt7697_wr_set_pmk_req(struct mt7697_cfg80211_info*, u8, const u8[MT7697_WIFI_LENGTH_PMK]);
int mt7697_wr_set_channel_req(struct mt7697_cfg80211_info*, u8, u8);
int mt7697_wr_set_bssid_req(struct mt7697_cfg80211_info*, const u8[ETH_ALEN]);
int mt7697_wr_set_ssid_req(struct mt7697_cfg80211_info*, u8, u8, const u8[]);
int mt7697_wr_reload_settings_req(struct mt7697_cfg80211_info*);
int mt7697_wr_mac_addr_req(struct mt7697_cfg80211_info*, u8);
int mt7697_wr_cfg_req(struct mt7697_cfg80211_info*);
int mt7697_wr_reg_rx_hndlr_req(struct mt7697_cfg80211_info*);
int mt7697_wr_unreg_rx_hndlr_req(struct mt7697_cfg80211_info*);
int mt7697_wr_set_op_mode_req(struct mt7697_cfg80211_info*, u8);
int mt7697_wr_get_radio_state_req(struct mt7697_cfg80211_info*);
int mt7697_wr_set_radio_state_req(struct mt7697_cfg80211_info*, u8);
int mt7697_wr_get_rx_filter_req(struct mt7697_cfg80211_info*);
int mt7697_wr_set_rx_filter_req(struct mt7697_cfg80211_info*, u32);
int mt7697_wr_get_smart_conn_filter_req(struct mt7697_cfg80211_info*);
int mt7697_wr_set_smart_conn_filter_req(struct mt7697_cfg80211_info*, u8);
int mt7697_wr_get_listen_interval_req(struct mt7697_cfg80211_info*);
int mt7697_wr_set_listen_interval_req(struct mt7697_cfg80211_info*, u32);
int mt7697_wr_scan_req(struct mt7697_cfg80211_info*, u32,
const struct cfg80211_scan_request*);
int mt7697_wr_set_security_mode_req(struct mt7697_cfg80211_info*, u8, u8, u8);
int mt7697_wr_get_security_mode_req(struct mt7697_cfg80211_info*, u32, u8);
int mt7697_wr_scan_stop_req(struct mt7697_cfg80211_info*);
int mt7697_wr_disconnect_req(struct mt7697_cfg80211_info*, u32, const u8*);
int mt7697_wr_set_wireless_mode_req(const struct mt7697_cfg80211_info*, u8);
int mt7697_wr_get_wireless_mode_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_set_pmk_req(const struct mt7697_cfg80211_info*,
const u8[MT7697_WIFI_LENGTH_PMK]);
int mt7697_wr_set_channel_req(const struct mt7697_cfg80211_info*, u8);
int mt7697_wr_set_bssid_req(const struct mt7697_cfg80211_info*, const u8[ETH_ALEN]);
int mt7697_wr_set_ssid_req(const struct mt7697_cfg80211_info*, u8, const u8[]);
int mt7697_wr_reload_settings_req(const struct mt7697_cfg80211_info*, u8);
int mt7697_wr_mac_addr_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_cfg_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_set_op_mode_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_get_radio_state_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_set_radio_state_req(const struct mt7697_cfg80211_info*, u8);
int mt7697_wr_get_listen_interval_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_set_listen_interval_req(const struct mt7697_cfg80211_info*, u32);
int mt7697_wr_scan_req(const struct mt7697_cfg80211_info*, u32,
const struct cfg80211_scan_request*);
int mt7697_wr_set_security_mode_req(const struct mt7697_cfg80211_info*, u8, u8);
int mt7697_wr_get_security_mode_req(const struct mt7697_cfg80211_info*, u32);
int mt7697_wr_scan_stop_req(const struct mt7697_cfg80211_info*);
int mt7697_wr_disconnect_req(const struct mt7697_cfg80211_info*, u32, const u8*);
int mt7697_wr_tx_raw_packet(struct mt7697_cfg80211_info*, const u8*, u32);
int mt7697_proc_data(void*);
......
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