Message ID | 20181017114141.27916-2-jesse.sung@canonical.com |
---|---|
State | New |
Headers | show |
Series | [B/C/D,v2,1/1] UBUNTU: SAUCE: mwifiex: Switch WiFi LED state according to the device status | expand |
On 10/17/18 13:41, Wen-chien Jesse Sung wrote: > BugLink: https://launchpad.net/bugs/1798330 > > For Edge Gateway 5000/5100 only. > > Add code for controlling WiFi LED via firmware, and turns the LED on > and off when the interface is up and down accordingly. > > Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> Present on Xenial for a long time, so: Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> > --- > drivers/net/wireless/marvell/mwifiex/fw.h | 18 ++++++++++++ > drivers/net/wireless/marvell/mwifiex/main.c | 5 +++- > drivers/net/wireless/marvell/mwifiex/main.h | 6 ++++ > drivers/net/wireless/marvell/mwifiex/pcie.c | 10 +++++++ > .../net/wireless/marvell/mwifiex/sta_cmd.c | 29 +++++++++++++++++++ > .../wireless/marvell/mwifiex/sta_cmdresp.c | 2 ++ > .../net/wireless/marvell/mwifiex/sta_ioctl.c | 18 ++++++++++++ > 7 files changed, 87 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h > index 13cd58e963b3..bcbfe5335049 100644 > --- a/drivers/net/wireless/marvell/mwifiex/fw.h > +++ b/drivers/net/wireless/marvell/mwifiex/fw.h > @@ -208,6 +208,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { > #define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) > #define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202) > #define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203) > +#define TLV_TYPE_LED_CONTROL (PROPRIETARY_TLV_BASE_ID + 205) > #define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206) > #define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236) > #define TLV_TYPE_CHAN_ATTR_CFG (PROPRIETARY_TLV_BASE_ID + 237) > @@ -353,6 +354,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { > #define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c > #define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040 > #define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D > +#define HostCmd_CMD_802_11_LED_CONTROL 0X004E > #define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b > #define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e > #define HostCmd_CMD_802_11_BG_SCAN_CONFIG 0x006b > @@ -1180,6 +1182,16 @@ struct ieee_types_oper_mode_ntf { > u8 oper_mode; > } __packed; > > +struct mwifiex_led_param { > + __le16 mode; > + __le16 on; > +} __packed; > + > +struct mwifiex_ie_types_led_param { > + struct mwifiex_ie_types_header header; > + struct mwifiex_led_param led_cfg; > +} __packed; > + > struct host_cmd_ds_802_11_ad_hoc_start { > u8 ssid[IEEE80211_MAX_SSID_LEN]; > u8 bss_mode; > @@ -1303,6 +1315,11 @@ struct host_cmd_ds_802_11_hs_cfg_enh { > } params; > } __packed; > > +struct host_cmd_ds_802_11_led_control { > + __le16 action; > + __le16 num_led; > +} __packed; > + > enum SNMP_MIB_INDEX { > OP_RATE_SET_I = 1, > DTIM_PERIOD_I = 3, > @@ -2346,6 +2363,7 @@ struct host_cmd_ds_command { > struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; > struct host_cmd_ds_multi_chan_policy mc_policy; > struct host_cmd_ds_robust_coex coex; > + struct host_cmd_ds_802_11_led_control led_cfg; > struct host_cmd_ds_wakeup_reason hs_wakeup_reason; > struct host_cmd_ds_gtk_rekey_params rekey; > struct host_cmd_ds_chan_region_cfg reg_cfg; > diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c > index a96bd7e653bf..b91768cf9a95 100644 > --- a/drivers/net/wireless/marvell/mwifiex/main.c > +++ b/drivers/net/wireless/marvell/mwifiex/main.c > @@ -727,8 +727,10 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter, > static int > mwifiex_open(struct net_device *dev) > { > - netif_carrier_off(dev); > + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); > > + netif_carrier_off(dev); > + mwifiex_set_led(priv->adapter, MWIFIEX_LED_ON); > return 0; > } > > @@ -759,6 +761,7 @@ mwifiex_close(struct net_device *dev) > cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); > } > > + mwifiex_set_led(priv->adapter, MWIFIEX_LED_OFF); > return 0; > } > > diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h > index 154c0796c0c5..ca791f1cd01d 100644 > --- a/drivers/net/wireless/marvell/mwifiex/main.h > +++ b/drivers/net/wireless/marvell/mwifiex/main.h > @@ -129,6 +129,10 @@ enum { > > #define PKT_TYPE_MGMT 0xE5 > > +#define MWIFIEX_LED_ON 1 > +#define MWIFIEX_LED_OFF 0 > +#define MWIFIEX_LED_MAX 3 > + > /* > * Do not check for data_received for USB, as data_received > * is handled in mwifiex_usb_recv for USB > @@ -680,6 +684,7 @@ struct mwifiex_private { > struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX]; > u8 assoc_resp_ht_param; > bool ht_param_present; > + bool is_edge_gateway; > }; > > > @@ -1473,6 +1478,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, > struct cmd_ctrl_node *cmd_queued); > int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, > struct cfg80211_ssid *req_ssid); > +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on); > int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); > int mwifiex_enable_hs(struct mwifiex_adapter *adapter); > int mwifiex_disable_auto_ds(struct mwifiex_private *priv); > diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c > index 9511f5fe62f4..9fff7774ff96 100644 > --- a/drivers/net/wireless/marvell/mwifiex/pcie.c > +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c > @@ -233,6 +233,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, > const struct pci_device_id *ent) > { > struct pcie_service_card *card; > + struct mwifiex_private *priv; > + struct pci_dev *pdev_host; > int ret; > > pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", > @@ -271,6 +273,14 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, > return -1; > } > > + priv = mwifiex_get_priv(card->adapter, MWIFIEX_BSS_ROLE_STA); > + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); > + if (!pdev_host) > + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); > + if (pdev_host) { > + priv->is_edge_gateway = true; > + pci_dev_put(pdev_host); > + } > return 0; > } > > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > index fb090144a6d8..316ba60f0612 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > @@ -424,6 +424,31 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, > return 0; > } > > +static int mwifiex_cmd_802_11_led_cfg(struct mwifiex_private *priv, > + struct host_cmd_ds_command *cmd, > + u16 cmd_action, > + struct mwifiex_led_param *ledcfg_param) > +{ > + struct host_cmd_ds_802_11_led_control *led_cfg = &cmd->params.led_cfg; > + struct mwifiex_ie_types_led_param *led_tlv; > + u8 *pos; > + > + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_LED_CONTROL); > + cmd->size = cpu_to_le16(S_DS_GEN); > + le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_802_11_led_control)); > + > + led_cfg->action = cpu_to_le16(cmd_action); > + led_cfg->num_led = cpu_to_le16(MWIFIEX_LED_MAX); > + > + pos = (u8 *)led_cfg + sizeof(struct host_cmd_ds_802_11_led_control); > + led_tlv = (void *)pos; > + led_tlv->header.type = cpu_to_le16(TLV_TYPE_LED_CONTROL); > + led_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_led_param)); > + memcpy(&led_tlv->led_cfg, ledcfg_param, sizeof(struct mwifiex_led_param)); > + le16_add_cpu(&cmd->size, sizeof(struct mwifiex_ie_types_led_param)); > + return 0; > +} > + > /* > * This function prepares command to set/get MAC address. > * > @@ -1980,6 +2005,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, > ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action, > (struct mwifiex_hs_config_param *) data_buf); > break; > + case HostCmd_CMD_802_11_LED_CONTROL: > + ret = mwifiex_cmd_802_11_led_cfg(priv, cmd_ptr, cmd_action, > + data_buf); > + break; > case HostCmd_CMD_802_11_SCAN: > ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); > break; > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > index 1bd4e13b8449..5ffb052822f2 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > @@ -1388,6 +1388,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, > case HostCmd_CMD_ROBUST_COEX: > ret = mwifiex_ret_robust_coex(priv, resp, data_buf); > break; > + case HostCmd_CMD_802_11_LED_CONTROL: > + break; > case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: > break; > case HostCmd_CMD_CHAN_REGION_CFG: > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > index a6077ab3efc3..aa9ab1b452c3 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > @@ -601,6 +601,24 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) > } > EXPORT_SYMBOL_GPL(mwifiex_enable_hs); > > +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on) > +{ > + struct mwifiex_private *priv; > + struct mwifiex_led_param ledcfg; > + > + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); > + if (!priv->is_edge_gateway) > + return -ENODEV; > + > + memset(&ledcfg, 0, sizeof(struct mwifiex_led_param)); > + ledcfg.on = cpu_to_le16(on); > + > + return mwifiex_send_cmd(priv, > + HostCmd_CMD_802_11_LED_CONTROL, > + HostCmd_ACT_GEN_SET, 0, > + &ledcfg, true); > +} > + > /* > * IOCTL request handler to get BSS information. > * >
On 17.10.18 13:41, Wen-chien Jesse Sung wrote: > BugLink: https://launchpad.net/bugs/1798330 > > For Edge Gateway 5000/5100 only. > > Add code for controlling WiFi LED via firmware, and turns the LED on > and off when the interface is up and down accordingly. > > Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- Pulling forward a patch which has been in Xenial for a long time. Would have been ok to make this a single bug report but that does not hurt. > drivers/net/wireless/marvell/mwifiex/fw.h | 18 ++++++++++++ > drivers/net/wireless/marvell/mwifiex/main.c | 5 +++- > drivers/net/wireless/marvell/mwifiex/main.h | 6 ++++ > drivers/net/wireless/marvell/mwifiex/pcie.c | 10 +++++++ > .../net/wireless/marvell/mwifiex/sta_cmd.c | 29 +++++++++++++++++++ > .../wireless/marvell/mwifiex/sta_cmdresp.c | 2 ++ > .../net/wireless/marvell/mwifiex/sta_ioctl.c | 18 ++++++++++++ > 7 files changed, 87 insertions(+), 1 deletion(-) > > diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h > index 13cd58e963b3..bcbfe5335049 100644 > --- a/drivers/net/wireless/marvell/mwifiex/fw.h > +++ b/drivers/net/wireless/marvell/mwifiex/fw.h > @@ -208,6 +208,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { > #define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) > #define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202) > #define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203) > +#define TLV_TYPE_LED_CONTROL (PROPRIETARY_TLV_BASE_ID + 205) > #define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206) > #define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236) > #define TLV_TYPE_CHAN_ATTR_CFG (PROPRIETARY_TLV_BASE_ID + 237) > @@ -353,6 +354,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { > #define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c > #define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040 > #define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D > +#define HostCmd_CMD_802_11_LED_CONTROL 0X004E > #define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b > #define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e > #define HostCmd_CMD_802_11_BG_SCAN_CONFIG 0x006b > @@ -1180,6 +1182,16 @@ struct ieee_types_oper_mode_ntf { > u8 oper_mode; > } __packed; > > +struct mwifiex_led_param { > + __le16 mode; > + __le16 on; > +} __packed; > + > +struct mwifiex_ie_types_led_param { > + struct mwifiex_ie_types_header header; > + struct mwifiex_led_param led_cfg; > +} __packed; > + > struct host_cmd_ds_802_11_ad_hoc_start { > u8 ssid[IEEE80211_MAX_SSID_LEN]; > u8 bss_mode; > @@ -1303,6 +1315,11 @@ struct host_cmd_ds_802_11_hs_cfg_enh { > } params; > } __packed; > > +struct host_cmd_ds_802_11_led_control { > + __le16 action; > + __le16 num_led; > +} __packed; > + > enum SNMP_MIB_INDEX { > OP_RATE_SET_I = 1, > DTIM_PERIOD_I = 3, > @@ -2346,6 +2363,7 @@ struct host_cmd_ds_command { > struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; > struct host_cmd_ds_multi_chan_policy mc_policy; > struct host_cmd_ds_robust_coex coex; > + struct host_cmd_ds_802_11_led_control led_cfg; > struct host_cmd_ds_wakeup_reason hs_wakeup_reason; > struct host_cmd_ds_gtk_rekey_params rekey; > struct host_cmd_ds_chan_region_cfg reg_cfg; > diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c > index a96bd7e653bf..b91768cf9a95 100644 > --- a/drivers/net/wireless/marvell/mwifiex/main.c > +++ b/drivers/net/wireless/marvell/mwifiex/main.c > @@ -727,8 +727,10 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter, > static int > mwifiex_open(struct net_device *dev) > { > - netif_carrier_off(dev); > + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); > > + netif_carrier_off(dev); > + mwifiex_set_led(priv->adapter, MWIFIEX_LED_ON); > return 0; > } > > @@ -759,6 +761,7 @@ mwifiex_close(struct net_device *dev) > cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); > } > > + mwifiex_set_led(priv->adapter, MWIFIEX_LED_OFF); > return 0; > } > > diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h > index 154c0796c0c5..ca791f1cd01d 100644 > --- a/drivers/net/wireless/marvell/mwifiex/main.h > +++ b/drivers/net/wireless/marvell/mwifiex/main.h > @@ -129,6 +129,10 @@ enum { > > #define PKT_TYPE_MGMT 0xE5 > > +#define MWIFIEX_LED_ON 1 > +#define MWIFIEX_LED_OFF 0 > +#define MWIFIEX_LED_MAX 3 > + > /* > * Do not check for data_received for USB, as data_received > * is handled in mwifiex_usb_recv for USB > @@ -680,6 +684,7 @@ struct mwifiex_private { > struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX]; > u8 assoc_resp_ht_param; > bool ht_param_present; > + bool is_edge_gateway; > }; > > > @@ -1473,6 +1478,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, > struct cmd_ctrl_node *cmd_queued); > int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, > struct cfg80211_ssid *req_ssid); > +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on); > int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); > int mwifiex_enable_hs(struct mwifiex_adapter *adapter); > int mwifiex_disable_auto_ds(struct mwifiex_private *priv); > diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c > index 9511f5fe62f4..9fff7774ff96 100644 > --- a/drivers/net/wireless/marvell/mwifiex/pcie.c > +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c > @@ -233,6 +233,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, > const struct pci_device_id *ent) > { > struct pcie_service_card *card; > + struct mwifiex_private *priv; > + struct pci_dev *pdev_host; > int ret; > > pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", > @@ -271,6 +273,14 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, > return -1; > } > > + priv = mwifiex_get_priv(card->adapter, MWIFIEX_BSS_ROLE_STA); > + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); > + if (!pdev_host) > + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); > + if (pdev_host) { > + priv->is_edge_gateway = true; > + pci_dev_put(pdev_host); > + } > return 0; > } > > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > index fb090144a6d8..316ba60f0612 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c > @@ -424,6 +424,31 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, > return 0; > } > > +static int mwifiex_cmd_802_11_led_cfg(struct mwifiex_private *priv, > + struct host_cmd_ds_command *cmd, > + u16 cmd_action, > + struct mwifiex_led_param *ledcfg_param) > +{ > + struct host_cmd_ds_802_11_led_control *led_cfg = &cmd->params.led_cfg; > + struct mwifiex_ie_types_led_param *led_tlv; > + u8 *pos; > + > + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_LED_CONTROL); > + cmd->size = cpu_to_le16(S_DS_GEN); > + le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_802_11_led_control)); > + > + led_cfg->action = cpu_to_le16(cmd_action); > + led_cfg->num_led = cpu_to_le16(MWIFIEX_LED_MAX); > + > + pos = (u8 *)led_cfg + sizeof(struct host_cmd_ds_802_11_led_control); > + led_tlv = (void *)pos; > + led_tlv->header.type = cpu_to_le16(TLV_TYPE_LED_CONTROL); > + led_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_led_param)); > + memcpy(&led_tlv->led_cfg, ledcfg_param, sizeof(struct mwifiex_led_param)); > + le16_add_cpu(&cmd->size, sizeof(struct mwifiex_ie_types_led_param)); > + return 0; > +} > + > /* > * This function prepares command to set/get MAC address. > * > @@ -1980,6 +2005,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, > ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action, > (struct mwifiex_hs_config_param *) data_buf); > break; > + case HostCmd_CMD_802_11_LED_CONTROL: > + ret = mwifiex_cmd_802_11_led_cfg(priv, cmd_ptr, cmd_action, > + data_buf); > + break; > case HostCmd_CMD_802_11_SCAN: > ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); > break; > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > index 1bd4e13b8449..5ffb052822f2 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c > @@ -1388,6 +1388,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, > case HostCmd_CMD_ROBUST_COEX: > ret = mwifiex_ret_robust_coex(priv, resp, data_buf); > break; > + case HostCmd_CMD_802_11_LED_CONTROL: > + break; > case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: > break; > case HostCmd_CMD_CHAN_REGION_CFG: > diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > index a6077ab3efc3..aa9ab1b452c3 100644 > --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c > @@ -601,6 +601,24 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) > } > EXPORT_SYMBOL_GPL(mwifiex_enable_hs); > > +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on) > +{ > + struct mwifiex_private *priv; > + struct mwifiex_led_param ledcfg; > + > + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); > + if (!priv->is_edge_gateway) > + return -ENODEV; > + > + memset(&ledcfg, 0, sizeof(struct mwifiex_led_param)); > + ledcfg.on = cpu_to_le16(on); > + > + return mwifiex_send_cmd(priv, > + HostCmd_CMD_802_11_LED_CONTROL, > + HostCmd_ACT_GEN_SET, 0, > + &ledcfg, true); > +} > + > /* > * IOCTL request handler to get BSS information. > * >
diff --git a/drivers/net/wireless/marvell/mwifiex/fw.h b/drivers/net/wireless/marvell/mwifiex/fw.h index 13cd58e963b3..bcbfe5335049 100644 --- a/drivers/net/wireless/marvell/mwifiex/fw.h +++ b/drivers/net/wireless/marvell/mwifiex/fw.h @@ -208,6 +208,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define TLV_TYPE_CHANNEL_STATS (PROPRIETARY_TLV_BASE_ID + 198) #define TLV_BTCOEX_WL_AGGR_WINSIZE (PROPRIETARY_TLV_BASE_ID + 202) #define TLV_BTCOEX_WL_SCANTIME (PROPRIETARY_TLV_BASE_ID + 203) +#define TLV_TYPE_LED_CONTROL (PROPRIETARY_TLV_BASE_ID + 205) #define TLV_TYPE_BSS_MODE (PROPRIETARY_TLV_BASE_ID + 206) #define TLV_TYPE_RANDOM_MAC (PROPRIETARY_TLV_BASE_ID + 236) #define TLV_TYPE_CHAN_ATTR_CFG (PROPRIETARY_TLV_BASE_ID + 237) @@ -353,6 +354,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER { #define HostCmd_CMD_802_11_AD_HOC_JOIN 0x002c #define HostCmd_CMD_802_11_AD_HOC_STOP 0x0040 #define HostCmd_CMD_802_11_MAC_ADDRESS 0x004D +#define HostCmd_CMD_802_11_LED_CONTROL 0X004E #define HostCmd_CMD_802_11D_DOMAIN_INFO 0x005b #define HostCmd_CMD_802_11_KEY_MATERIAL 0x005e #define HostCmd_CMD_802_11_BG_SCAN_CONFIG 0x006b @@ -1180,6 +1182,16 @@ struct ieee_types_oper_mode_ntf { u8 oper_mode; } __packed; +struct mwifiex_led_param { + __le16 mode; + __le16 on; +} __packed; + +struct mwifiex_ie_types_led_param { + struct mwifiex_ie_types_header header; + struct mwifiex_led_param led_cfg; +} __packed; + struct host_cmd_ds_802_11_ad_hoc_start { u8 ssid[IEEE80211_MAX_SSID_LEN]; u8 bss_mode; @@ -1303,6 +1315,11 @@ struct host_cmd_ds_802_11_hs_cfg_enh { } params; } __packed; +struct host_cmd_ds_802_11_led_control { + __le16 action; + __le16 num_led; +} __packed; + enum SNMP_MIB_INDEX { OP_RATE_SET_I = 1, DTIM_PERIOD_I = 3, @@ -2346,6 +2363,7 @@ struct host_cmd_ds_command { struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg; struct host_cmd_ds_multi_chan_policy mc_policy; struct host_cmd_ds_robust_coex coex; + struct host_cmd_ds_802_11_led_control led_cfg; struct host_cmd_ds_wakeup_reason hs_wakeup_reason; struct host_cmd_ds_gtk_rekey_params rekey; struct host_cmd_ds_chan_region_cfg reg_cfg; diff --git a/drivers/net/wireless/marvell/mwifiex/main.c b/drivers/net/wireless/marvell/mwifiex/main.c index a96bd7e653bf..b91768cf9a95 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.c +++ b/drivers/net/wireless/marvell/mwifiex/main.c @@ -727,8 +727,10 @@ static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter, static int mwifiex_open(struct net_device *dev) { - netif_carrier_off(dev); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); + netif_carrier_off(dev); + mwifiex_set_led(priv->adapter, MWIFIEX_LED_ON); return 0; } @@ -759,6 +761,7 @@ mwifiex_close(struct net_device *dev) cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0); } + mwifiex_set_led(priv->adapter, MWIFIEX_LED_OFF); return 0; } diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h index 154c0796c0c5..ca791f1cd01d 100644 --- a/drivers/net/wireless/marvell/mwifiex/main.h +++ b/drivers/net/wireless/marvell/mwifiex/main.h @@ -129,6 +129,10 @@ enum { #define PKT_TYPE_MGMT 0xE5 +#define MWIFIEX_LED_ON 1 +#define MWIFIEX_LED_OFF 0 +#define MWIFIEX_LED_MAX 3 + /* * Do not check for data_received for USB, as data_received * is handled in mwifiex_usb_recv for USB @@ -680,6 +684,7 @@ struct mwifiex_private { struct mwifiex_user_scan_chan hidden_chan[MWIFIEX_USER_SCAN_CHAN_MAX]; u8 assoc_resp_ht_param; bool ht_param_present; + bool is_edge_gateway; }; @@ -1473,6 +1478,7 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, struct cmd_ctrl_node *cmd_queued); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, struct cfg80211_ssid *req_ssid); +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); int mwifiex_enable_hs(struct mwifiex_adapter *adapter); int mwifiex_disable_auto_ds(struct mwifiex_private *priv); diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c index 9511f5fe62f4..9fff7774ff96 100644 --- a/drivers/net/wireless/marvell/mwifiex/pcie.c +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c @@ -233,6 +233,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct pcie_service_card *card; + struct mwifiex_private *priv; + struct pci_dev *pdev_host; int ret; pr_debug("info: vendor=0x%4.04X device=0x%4.04X rev=%d\n", @@ -271,6 +273,14 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, return -1; } + priv = mwifiex_get_priv(card->adapter, MWIFIEX_BSS_ROLE_STA); + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0720, NULL); + if (!pdev_host) + pdev_host = pci_get_subsys(PCI_ANY_ID, PCI_ANY_ID, 0x1028, 0x0733, NULL); + if (pdev_host) { + priv->is_edge_gateway = true; + pci_dev_put(pdev_host); + } return 0; } diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c index fb090144a6d8..316ba60f0612 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmd.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmd.c @@ -424,6 +424,31 @@ mwifiex_cmd_802_11_hs_cfg(struct mwifiex_private *priv, return 0; } +static int mwifiex_cmd_802_11_led_cfg(struct mwifiex_private *priv, + struct host_cmd_ds_command *cmd, + u16 cmd_action, + struct mwifiex_led_param *ledcfg_param) +{ + struct host_cmd_ds_802_11_led_control *led_cfg = &cmd->params.led_cfg; + struct mwifiex_ie_types_led_param *led_tlv; + u8 *pos; + + cmd->command = cpu_to_le16(HostCmd_CMD_802_11_LED_CONTROL); + cmd->size = cpu_to_le16(S_DS_GEN); + le16_add_cpu(&cmd->size, sizeof(struct host_cmd_ds_802_11_led_control)); + + led_cfg->action = cpu_to_le16(cmd_action); + led_cfg->num_led = cpu_to_le16(MWIFIEX_LED_MAX); + + pos = (u8 *)led_cfg + sizeof(struct host_cmd_ds_802_11_led_control); + led_tlv = (void *)pos; + led_tlv->header.type = cpu_to_le16(TLV_TYPE_LED_CONTROL); + led_tlv->header.len = cpu_to_le16(sizeof(struct mwifiex_led_param)); + memcpy(&led_tlv->led_cfg, ledcfg_param, sizeof(struct mwifiex_led_param)); + le16_add_cpu(&cmd->size, sizeof(struct mwifiex_ie_types_led_param)); + return 0; +} + /* * This function prepares command to set/get MAC address. * @@ -1980,6 +2005,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_cmd_802_11_hs_cfg(priv, cmd_ptr, cmd_action, (struct mwifiex_hs_config_param *) data_buf); break; + case HostCmd_CMD_802_11_LED_CONTROL: + ret = mwifiex_cmd_802_11_led_cfg(priv, cmd_ptr, cmd_action, + data_buf); + break; case HostCmd_CMD_802_11_SCAN: ret = mwifiex_cmd_802_11_scan(cmd_ptr, data_buf); break; diff --git a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c index 1bd4e13b8449..5ffb052822f2 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_cmdresp.c @@ -1388,6 +1388,8 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no, case HostCmd_CMD_ROBUST_COEX: ret = mwifiex_ret_robust_coex(priv, resp, data_buf); break; + case HostCmd_CMD_802_11_LED_CONTROL: + break; case HostCmd_CMD_GTK_REKEY_OFFLOAD_CFG: break; case HostCmd_CMD_CHAN_REGION_CFG: diff --git a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c index a6077ab3efc3..aa9ab1b452c3 100644 --- a/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/marvell/mwifiex/sta_ioctl.c @@ -601,6 +601,24 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter) } EXPORT_SYMBOL_GPL(mwifiex_enable_hs); +int mwifiex_set_led(struct mwifiex_adapter *adapter, int on) +{ + struct mwifiex_private *priv; + struct mwifiex_led_param ledcfg; + + priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); + if (!priv->is_edge_gateway) + return -ENODEV; + + memset(&ledcfg, 0, sizeof(struct mwifiex_led_param)); + ledcfg.on = cpu_to_le16(on); + + return mwifiex_send_cmd(priv, + HostCmd_CMD_802_11_LED_CONTROL, + HostCmd_ACT_GEN_SET, 0, + &ledcfg, true); +} + /* * IOCTL request handler to get BSS information. *
BugLink: https://launchpad.net/bugs/1798330 For Edge Gateway 5000/5100 only. Add code for controlling WiFi LED via firmware, and turns the LED on and off when the interface is up and down accordingly. Signed-off-by: Wen-chien Jesse Sung <jesse.sung@canonical.com> --- drivers/net/wireless/marvell/mwifiex/fw.h | 18 ++++++++++++ drivers/net/wireless/marvell/mwifiex/main.c | 5 +++- drivers/net/wireless/marvell/mwifiex/main.h | 6 ++++ drivers/net/wireless/marvell/mwifiex/pcie.c | 10 +++++++ .../net/wireless/marvell/mwifiex/sta_cmd.c | 29 +++++++++++++++++++ .../wireless/marvell/mwifiex/sta_cmdresp.c | 2 ++ .../net/wireless/marvell/mwifiex/sta_ioctl.c | 18 ++++++++++++ 7 files changed, 87 insertions(+), 1 deletion(-)