Update the drivers to pass the RSSI level as a cfg80211_cqm_rssi_notify parameter and pass this value to userspace in a new nl80211 attribute. This helps both userspace and also helps in the implementation of the multiple RSSI thresholds CQM mechanism. Note for marvell/mwifiex I pass 0 for the RSSI value because the new RSSI value is not available to the driver at the time of the cfg80211_cqm_rssi_notify call, but the driver queries the new value immediately after that, so it is actually available just a moment later if we wanted to defer caling cfg80211_cqm_rssi_notify until that moment. Without this, the new cfg80211 code (patch 3) will call .get_station which will send a duplicate HostCmd_CMD_RSSI_INFO command to the hardware.
Unified · Split
| @@ -824,7 +824,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) · 823 unmodified lines | |||
| 824 | case EVENT_RSSI_LOW: | 824 | case EVENT_RSSI_LOW: |
| 825 | cfg80211_cqm_rssi_notify(priv->netdev, | 825 | cfg80211_cqm_rssi_notify(priv->netdev, |
| 826 | NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, | 826 | NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, |
| 827 | GFP_KERNEL); | 827 | 0, GFP_KERNEL); |
| 828 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, | 828 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, |
| 829 | HostCmd_ACT_GEN_GET, 0, NULL, false); | 829 | HostCmd_ACT_GEN_GET, 0, NULL, false); |
| 830 | priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; | 830 | priv->subsc_evt_rssi_state = RSSI_LOW_RECVD; |
| @@ -839,7 +839,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv) · 8 unmodified lines | |||
| 839 | case EVENT_RSSI_HIGH: | 839 | case EVENT_RSSI_HIGH: |
| 840 | cfg80211_cqm_rssi_notify(priv->netdev, | 840 | cfg80211_cqm_rssi_notify(priv->netdev, |
| 841 | NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, | 841 | NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, |
| 842 | GFP_KERNEL); | 842 | 0, GFP_KERNEL); |
| 843 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, | 843 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, |
| 844 | HostCmd_ACT_GEN_GET, 0, NULL, false); | 844 | HostCmd_ACT_GEN_GET, 0, NULL, false); |
| 845 | priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; | 845 | priv->subsc_evt_rssi_state = RSSI_HIGH_RECVD; |
| @@ -3187,7 +3187,7 @@ static void rndis_do_cqm(struct usbnet *usbdev, s32 rssi) · 3186 unmodified lines | |||
| 3187 | return; | 3187 | return; |
| 3188 | 3188 | ||
| 3189 | priv->last_cqm_event_rssi = rssi; | 3189 | priv->last_cqm_event_rssi = rssi; |
| 3190 | cfg80211_cqm_rssi_notify(usbdev->net, event, GFP_KERNEL); | 3190 | cfg80211_cqm_rssi_notify(usbdev->net, event, rssi, GFP_KERNEL); |
| 3191 | } | 3191 | } |
| 3192 | 3192 | ||
| 3193 | #define DEVICE_POLLER_JIFFIES (HZ) | 3193 | #define DEVICE_POLLER_JIFFIES (HZ) |
| @@ -5390,6 +5390,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 5389 unmodified lines | |||
| 5390 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event | 5390 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event |
| 5391 | * @dev: network device | 5391 | * @dev: network device |
| 5392 | * @rssi_event: the triggered RSSI event | 5392 | * @rssi_event: the triggered RSSI event |
| 5393 | * @rssi_level: new RSSI level value or 0 if not available | ||
| 5393 | * @gfp: context flags | 5394 | * @gfp: context flags |
| 5394 | * | 5395 | * |
| 5395 | * This function is called when a configured connection quality monitoring | 5396 | * This function is called when a configured connection quality monitoring |
| @@ -5397,7 +5398,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, · 1 unmodified line | |||
| 5397 | */ | 5398 | */ |
| 5398 | void cfg80211_cqm_rssi_notify(struct net_device *dev, | 5399 | void cfg80211_cqm_rssi_notify(struct net_device *dev, |
| 5399 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 5400 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
| 5400 | gfp_t gfp); | 5401 | s32 rssi_level, gfp_t gfp); |
| 5401 | 5402 | ||
| 5402 | /** | 5403 | /** |
| 5403 | * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer | 5404 | * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer |
| @@ -3952,6 +3952,8 @@ enum nl80211_ps_state { · 3951 unmodified lines | |||
| 3952 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. | 3952 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. |
| 3953 | * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon | 3953 | * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon |
| 3954 | * loss event | 3954 | * loss event |
| 3955 | * @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the | ||
| 3956 | * RSSI threshold event. | ||
| 3955 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal | 3957 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal |
| 3956 | * @NL80211_ATTR_CQM_MAX: highest key attribute | 3958 | * @NL80211_ATTR_CQM_MAX: highest key attribute |
| 3957 | */ | 3959 | */ |
| @@ -3965,6 +3967,7 @@ enum nl80211_attr_cqm { · 7 unmodified lines | |||
| 3965 | NL80211_ATTR_CQM_TXE_PKTS, | 3967 | NL80211_ATTR_CQM_TXE_PKTS, |
| 3966 | NL80211_ATTR_CQM_TXE_INTVL, | 3968 | NL80211_ATTR_CQM_TXE_INTVL, |
| 3967 | NL80211_ATTR_CQM_BEACON_LOSS_EVENT, | 3969 | NL80211_ATTR_CQM_BEACON_LOSS_EVENT, |
| 3970 | NL80211_ATTR_CQM_RSSI_LEVEL, | ||
| 3968 | 3971 | ||
| 3969 | /* keep last */ | 3972 | /* keep last */ |
| 3970 | __NL80211_ATTR_CQM_AFTER_LAST, | 3973 | __NL80211_ATTR_CQM_AFTER_LAST, |
| @@ -5048,7 +5048,7 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, · 5047 unmodified lines | |||
| 5048 | 5048 | ||
| 5049 | trace_api_cqm_rssi_notify(sdata, rssi_event, rssi_level); | 5049 | trace_api_cqm_rssi_notify(sdata, rssi_event, rssi_level); |
| 5050 | 5050 | ||
| 5051 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 5051 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, rssi_level, gfp); |
| 5052 | } | 5052 | } |
| 5053 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 5053 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
| 5054 | 5054 | ||
| @@ -9474,6 +9474,7 @@ nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] = { · 9473 unmodified lines | |||
| 9474 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, | 9474 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, |
| 9475 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, | 9475 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, |
| 9476 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, | 9476 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, |
| 9477 | [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 }, | ||
| 9477 | }; | 9478 | }; |
| 9478 | 9479 | ||
| 9479 | static int nl80211_set_cqm_txe(struct genl_info *info, | 9480 | static int nl80211_set_cqm_txe(struct genl_info *info, |
| @@ -13959,11 +13960,11 @@ static void cfg80211_send_cqm(struct sk_buff *msg, gfp_t gfp) · 4479 unmodified lines | |||
| 13959 | 13960 | ||
| 13960 | void cfg80211_cqm_rssi_notify(struct net_device *dev, | 13961 | void cfg80211_cqm_rssi_notify(struct net_device *dev, |
| 13961 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 13962 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
| 13962 | gfp_t gfp) | 13963 | s32 rssi_level, gfp_t gfp) |
| 13963 | { | 13964 | { |
| 13964 | struct sk_buff *msg; | 13965 | struct sk_buff *msg; |
| 13965 | 13966 | ||
| 13966 | trace_cfg80211_cqm_rssi_notify(dev, rssi_event); | 13967 | trace_cfg80211_cqm_rssi_notify(dev, rssi_event, rssi_level); |
| 13967 | 13968 | ||
| 13968 | if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW && | 13969 | if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW && |
| 13969 | rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) | 13970 | rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH)) |
| @@ -13977,6 +13978,10 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev, · 7 unmodified lines | |||
| 13977 | rssi_event)) | 13978 | rssi_event)) |
| 13978 | goto nla_put_failure; | 13979 | goto nla_put_failure; |
| 13979 | 13980 | ||
| 13981 | if (rssi_level && nla_put_s32(msg, NL80211_ATTR_CQM_RSSI_LEVEL, | ||
| 13982 | rssi_level)) | ||
| 13983 | goto nla_put_failure; | ||
| 13984 | |||
| 13980 | cfg80211_send_cqm(msg, gfp); | 13985 | cfg80211_send_cqm(msg, gfp); |
| 13981 | 13986 | ||
| 13982 | return; | 13987 | return; |
| @@ -2490,18 +2490,21 @@ TRACE_EVENT(cfg80211_mgmt_tx_status, · 2489 unmodified lines | |||
| 2490 | 2490 | ||
| 2491 | TRACE_EVENT(cfg80211_cqm_rssi_notify, | 2491 | TRACE_EVENT(cfg80211_cqm_rssi_notify, |
| 2492 | TP_PROTO(struct net_device *netdev, | 2492 | TP_PROTO(struct net_device *netdev, |
| 2493 | enum nl80211_cqm_rssi_threshold_event rssi_event), | 2493 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
| 2494 | TP_ARGS(netdev, rssi_event), | 2494 | s32 rssi_level), |
| 2495 | TP_ARGS(netdev, rssi_event, rssi_level), | ||
| 2495 | TP_STRUCT__entry( | 2496 | TP_STRUCT__entry( |
| 2496 | NETDEV_ENTRY | 2497 | NETDEV_ENTRY |
| 2497 | __field(enum nl80211_cqm_rssi_threshold_event, rssi_event) | 2498 | __field(enum nl80211_cqm_rssi_threshold_event, rssi_event) |
| 2499 | __field(s32, rssi_level) | ||
| 2498 | ), | 2500 | ), |
| 2499 | TP_fast_assign( | 2501 | TP_fast_assign( |
| 2500 | NETDEV_ASSIGN; | 2502 | NETDEV_ASSIGN; |
| 2501 | __entry->rssi_event = rssi_event; | 2503 | __entry->rssi_event = rssi_event; |
| 2504 | __entry->rssi_level = rssi_level; | ||
| 2502 | ), | 2505 | ), |
| 2503 | TP_printk(NETDEV_PR_FMT ", rssi event: %d", | 2506 | TP_printk(NETDEV_PR_FMT ", rssi event: %d, level: %d", |
| 2504 | NETDEV_PR_ARG, __entry->rssi_event) | 2507 | NETDEV_PR_ARG, __entry->rssi_event, __entry->rssi_level) |
| 2505 | ); | 2508 | ); |
| 2506 | 2509 | ||
| 2507 | TRACE_EVENT(cfg80211_reg_can_beacon, | 2510 | TRACE_EVENT(cfg80211_reg_can_beacon, |