wifi: eswifi: Add access point offload support
The eswifi controller is capable of acting as an Access Point. Implement ap_enable/ap_disable methods. Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
This commit is contained in:
parent
192733c096
commit
8a7b6ffaab
2 changed files with 158 additions and 11 deletions
|
@ -52,6 +52,7 @@ struct eswifi_sta {
|
||||||
enum eswifi_security_type security;
|
enum eswifi_security_type security;
|
||||||
char pass[65];
|
char pass[65];
|
||||||
bool connected;
|
bool connected;
|
||||||
|
uint8_t channel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct eswifi_bus_ops;
|
struct eswifi_bus_ops;
|
||||||
|
|
|
@ -435,15 +435,9 @@ static int eswifi_mgmt_disconnect(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int eswifi_mgmt_connect(struct device *dev,
|
static int __eswifi_sta_config(struct eswifi_dev *eswifi,
|
||||||
struct wifi_connect_req_params *params)
|
struct wifi_connect_req_params *params)
|
||||||
{
|
{
|
||||||
struct eswifi_dev *eswifi = dev->driver_data;
|
|
||||||
|
|
||||||
LOG_DBG("");
|
|
||||||
|
|
||||||
eswifi_lock(eswifi);
|
|
||||||
|
|
||||||
memcpy(eswifi->sta.ssid, params->ssid, params->ssid_length);
|
memcpy(eswifi->sta.ssid, params->ssid, params->ssid_length);
|
||||||
eswifi->sta.ssid[params->ssid_length] = '\0';
|
eswifi->sta.ssid[params->ssid_length] = '\0';
|
||||||
|
|
||||||
|
@ -458,13 +452,163 @@ static int eswifi_mgmt_connect(struct device *dev,
|
||||||
eswifi->sta.security = ESWIFI_SEC_WPA2_MIXED;
|
eswifi->sta.security = ESWIFI_SEC_WPA2_MIXED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_ERR("Unsupported security type %d", params->security);
|
|
||||||
eswifi_unlock(eswifi);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eswifi->req = ESWIFI_REQ_CONNECT;
|
if (params->channel == WIFI_CHANNEL_ANY) {
|
||||||
k_work_submit_to_queue(&eswifi->work_q, &eswifi->request_work);
|
eswifi->sta.channel = 0;
|
||||||
|
} else {
|
||||||
|
eswifi->sta.channel = params->channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int eswifi_mgmt_connect(struct device *dev,
|
||||||
|
struct wifi_connect_req_params *params)
|
||||||
|
{
|
||||||
|
struct eswifi_dev *eswifi = dev->driver_data;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
eswifi_lock(eswifi);
|
||||||
|
|
||||||
|
err = __eswifi_sta_config(eswifi, params);
|
||||||
|
if (!err) {
|
||||||
|
eswifi->req = ESWIFI_REQ_CONNECT;
|
||||||
|
k_work_submit_to_queue(&eswifi->work_q,
|
||||||
|
&eswifi->request_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
eswifi_unlock(eswifi);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_NET_IPV4)
|
||||||
|
static int eswifi_mgmt_ap_enable(struct device *dev,
|
||||||
|
struct wifi_connect_req_params *params)
|
||||||
|
{
|
||||||
|
struct eswifi_dev *eswifi = dev->driver_data;
|
||||||
|
struct net_if_ipv4 *ipv4 = eswifi->iface->config.ip.ipv4;
|
||||||
|
struct net_if_addr *unicast = NULL;
|
||||||
|
int err = -EIO, i;
|
||||||
|
|
||||||
|
LOG_DBG("");
|
||||||
|
|
||||||
|
eswifi_lock(eswifi);
|
||||||
|
|
||||||
|
if (eswifi->role == ESWIFI_ROLE_AP) {
|
||||||
|
err = -EALREADY;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = __eswifi_sta_config(eswifi, params);
|
||||||
|
if (err) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* security */
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "A1=%u\r",
|
||||||
|
eswifi->sta.security);
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to set Security");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Passkey */
|
||||||
|
if (eswifi->sta.security != ESWIFI_SEC_OPEN) {
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "A2=%s\r",
|
||||||
|
eswifi->sta.pass);
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to set passkey");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set SSID (0=no MAC, 1=append MAC) */
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "AS=0,%s\r",
|
||||||
|
eswifi->sta.ssid);
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to set SSID");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set Channel */
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "AC=%u\r",
|
||||||
|
eswifi->sta.channel);
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to set Channel");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set IP Address */
|
||||||
|
for (i = 0; ipv4 && i < NET_IF_MAX_IPV4_ADDR; i++) {
|
||||||
|
if (ipv4->unicast[i].is_used) {
|
||||||
|
unicast = &ipv4->unicast[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!unicast) {
|
||||||
|
LOG_ERR("No IPv4 assigned for AP mode");
|
||||||
|
err = -EADDRNOTAVAIL;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "Z6=%s\r",
|
||||||
|
net_sprint_ipv4_addr(&unicast->address.in_addr));
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to active access point");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable AP */
|
||||||
|
snprintf(eswifi->buf, sizeof(eswifi->buf), "AD\r");
|
||||||
|
err = eswifi_at_cmd(eswifi, eswifi->buf);
|
||||||
|
if (err < 0) {
|
||||||
|
LOG_ERR("Unable to active access point");
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
eswifi->role = ESWIFI_ROLE_AP;
|
||||||
|
|
||||||
|
eswifi_unlock(eswifi);
|
||||||
|
return 0;
|
||||||
|
error:
|
||||||
|
eswifi_unlock(eswifi);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int eswifi_mgmt_ap_enable(struct device *dev,
|
||||||
|
struct wifi_connect_req_params *params)
|
||||||
|
{
|
||||||
|
LOG_ERR("IPv4 requested for AP mode");
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_NET_IPV4 */
|
||||||
|
|
||||||
|
static int eswifi_mgmt_ap_disable(struct device *dev)
|
||||||
|
{
|
||||||
|
struct eswifi_dev *eswifi = dev->driver_data;
|
||||||
|
char cmd[] = "AE\r";
|
||||||
|
int err;
|
||||||
|
|
||||||
|
eswifi_lock(eswifi);
|
||||||
|
|
||||||
|
err = eswifi_at_cmd(eswifi, cmd);
|
||||||
|
if (err < 0) {
|
||||||
|
eswifi_unlock(eswifi);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
eswifi->role = ESWIFI_ROLE_CLIENT;
|
||||||
|
|
||||||
eswifi_unlock(eswifi);
|
eswifi_unlock(eswifi);
|
||||||
|
|
||||||
|
@ -520,6 +664,8 @@ static const struct net_wifi_mgmt_offload eswifi_offload_api = {
|
||||||
.scan = eswifi_mgmt_scan,
|
.scan = eswifi_mgmt_scan,
|
||||||
.connect = eswifi_mgmt_connect,
|
.connect = eswifi_mgmt_connect,
|
||||||
.disconnect = eswifi_mgmt_disconnect,
|
.disconnect = eswifi_mgmt_disconnect,
|
||||||
|
.ap_enable = eswifi_mgmt_ap_enable,
|
||||||
|
.ap_disable = eswifi_mgmt_ap_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
NET_DEVICE_OFFLOAD_INIT(eswifi_mgmt, CONFIG_WIFI_ESWIFI_NAME,
|
NET_DEVICE_OFFLOAD_INIT(eswifi_mgmt, CONFIG_WIFI_ESWIFI_NAME,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue