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 | 824 | case EVENT_RSSI_LOW: |
| 825 | 825 | cfg80211_cqm_rssi_notify(priv->netdev, |
| 826 | 826 | NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, |
| 827 | − GFP_KERNEL); | |
| 827 | + 0, GFP_KERNEL); | |
| 828 | 828 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, |
| 829 | 829 | HostCmd_ACT_GEN_GET, 0, NULL, false); |
| 830 | 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 | 839 | case EVENT_RSSI_HIGH: |
| 840 | 840 | cfg80211_cqm_rssi_notify(priv->netdev, |
| 841 | 841 | NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, |
| 842 | − GFP_KERNEL); | |
| 842 | + 0, GFP_KERNEL); | |
| 843 | 843 | mwifiex_send_cmd(priv, HostCmd_CMD_RSSI_INFO, |
| 844 | 844 | HostCmd_ACT_GEN_GET, 0, NULL, false); |
| 845 | 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 | 3187 | return; |
| 3188 | 3188 | |
| 3189 | 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 | 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 | 5390 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event |
| 5391 | 5391 | * @dev: network device |
| 5392 | 5392 | * @rssi_event: the triggered RSSI event |
| 5393 | + * @rssi_level: new RSSI level value or 0 if not available | |
| 5393 | 5394 | * @gfp: context flags |
| 5394 | 5395 | * |
| 5395 | 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 | 5399 | void cfg80211_cqm_rssi_notify(struct net_device *dev, |
| 5399 | 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 | 5404 | * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer |
| @@ -3952,6 +3952,8 @@ enum nl80211_ps_state { · 3951 unmodified lines | ||
| 3952 | 3952 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. |
| 3953 | 3953 | * @NL80211_ATTR_CQM_BEACON_LOSS_EVENT: flag attribute that's set in a beacon |
| 3954 | 3954 | * loss event |
| 3955 | + * @NL80211_ATTR_CQM_RSSI_LEVEL: the RSSI value in dBm that triggered the | |
| 3956 | + * RSSI threshold event. | |
| 3955 | 3957 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal |
| 3956 | 3958 | * @NL80211_ATTR_CQM_MAX: highest key attribute |
| 3957 | 3959 | */ |
| @@ -3965,6 +3967,7 @@ enum nl80211_attr_cqm { · 7 unmodified lines | ||
| 3965 | 3967 | NL80211_ATTR_CQM_TXE_PKTS, |
| 3966 | 3968 | NL80211_ATTR_CQM_TXE_INTVL, |
| 3967 | 3969 | NL80211_ATTR_CQM_BEACON_LOSS_EVENT, |
| 3970 | + NL80211_ATTR_CQM_RSSI_LEVEL, | |
| 3968 | 3971 | |
| 3969 | 3972 | /* keep last */ |
| 3970 | 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 | 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 | 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 | 9474 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, |
| 9475 | 9475 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, |
| 9476 | 9476 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, |
| 9477 | + [NL80211_ATTR_CQM_RSSI_LEVEL] = { .type = NLA_S32 }, | |
| 9477 | 9478 | }; |
| 9478 | 9479 | |
| 9479 | 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 | 13961 | void cfg80211_cqm_rssi_notify(struct net_device *dev, |
| 13961 | 13962 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
| 13962 | − gfp_t gfp) | |
| 13963 | + s32 rssi_level, gfp_t gfp) | |
| 13963 | 13964 | { |
| 13964 | 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 | 13969 | if (WARN_ON(rssi_event != NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW && |
| 13969 | 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 | 13978 | rssi_event)) |
| 13978 | 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 | 13985 | cfg80211_send_cqm(msg, gfp); |
| 13981 | 13986 | |
| 13982 | 13987 | return; |
| @@ -2490,18 +2490,21 @@ TRACE_EVENT(cfg80211_mgmt_tx_status, · 2489 unmodified lines | ||
| 2490 | 2490 | |
| 2491 | 2491 | TRACE_EVENT(cfg80211_cqm_rssi_notify, |
| 2492 | 2492 | TP_PROTO(struct net_device *netdev, |
| 2493 | − enum nl80211_cqm_rssi_threshold_event rssi_event), | |
| 2494 | − TP_ARGS(netdev, rssi_event), | |
| 2493 | + enum nl80211_cqm_rssi_threshold_event rssi_event, | |
| 2494 | + s32 rssi_level), | |
| 2495 | + TP_ARGS(netdev, rssi_event, rssi_level), | |
| 2495 | 2496 | TP_STRUCT__entry( |
| 2496 | 2497 | NETDEV_ENTRY |
| 2497 | 2498 | __field(enum nl80211_cqm_rssi_threshold_event, rssi_event) |
| 2499 | + __field(s32, rssi_level) | |
| 2498 | 2500 | ), |
| 2499 | 2501 | TP_fast_assign( |
| 2500 | 2502 | NETDEV_ASSIGN; |
| 2501 | 2503 | __entry->rssi_event = rssi_event; |
| 2504 | + __entry->rssi_level = rssi_level; | |
| 2502 | 2505 | ), |
| 2503 | − TP_printk(NETDEV_PR_FMT ", rssi event: %d", | |
| 2504 | − NETDEV_PR_ARG, __entry->rssi_event) | |
| 2506 | + TP_printk(NETDEV_PR_FMT ", rssi event: %d, level: %d", | |
| 2507 | + NETDEV_PR_ARG, __entry->rssi_event, __entry->rssi_level) | |
| 2505 | 2508 | ); |
| 2506 | 2509 | |
| 2507 | 2510 | TRACE_EVENT(cfg80211_reg_can_beacon, |