wlcore/wl18xx: Add functionality to accept TX rate per link
authorMaxim Altshul <maxim.altshul@ti.com>
Mon, 11 Jul 2016 14:22:32 +0000 (17:22 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Mon, 18 Jul 2016 19:35:34 +0000 (22:35 +0300)
FW will provide a TX rate per link for each FW status,
and wlcore will be able to store the information for
the use of the mesh hwmp module.

This is used mainly in mesh.
Rates are reported when a mesh interface is up.

Signed-off-by: Maxim Altshul <maxim.altshul@ti.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
drivers/net/wireless/ti/wl18xx/main.c
drivers/net/wireless/ti/wl18xx/tx.c
drivers/net/wireless/ti/wl18xx/wl18xx.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/rx.c
drivers/net/wireless/ti/wlcore/wlcore_i.h

index 4811b74bf939ae285040194f2a2caff7fd553a02..00a04dfc03d1a569dabb0bba2f4276cef0a7d296 100644 (file)
@@ -1214,6 +1214,10 @@ static void wl18xx_convert_fw_status(struct wl1271 *wl, void *raw_fw_status,
                        int_fw_status->counters.tx_voice_released_blks;
        fw_status->counters.tx_last_rate =
                        int_fw_status->counters.tx_last_rate;
+       fw_status->counters.tx_last_rate_mbps =
+                       int_fw_status->counters.tx_last_rate_mbps;
+       fw_status->counters.hlid =
+                       int_fw_status->counters.hlid;
 
        fw_status->log_start_addr = le32_to_cpu(int_fw_status->log_start_addr);
 
index ebaf66ef3f84435388df178c5932070c51443c6e..876aef10f95a3eba476d284fb328b2dfed7a8737 100644 (file)
@@ -30,9 +30,9 @@
 
 static
 void wl18xx_get_last_tx_rate(struct wl1271 *wl, struct ieee80211_vif *vif,
-                            u8 band, struct ieee80211_tx_rate *rate)
+                            u8 band, struct ieee80211_tx_rate *rate, u8 hlid)
 {
-       u8 fw_rate = wl->fw_status->counters.tx_last_rate;
+       u8 fw_rate = wl->links[hlid].fw_rate_idx;
 
        if (fw_rate > CONF_HW_RATE_INDEX_MAX) {
                wl1271_error("last Tx rate invalid: %d", fw_rate);
@@ -79,6 +79,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
        struct sk_buff *skb;
        int id = tx_stat_byte & WL18XX_TX_STATUS_DESC_ID_MASK;
        bool tx_success;
+       struct wl1271_tx_hw_descr *tx_desc;
 
        /* check for id legality */
        if (unlikely(id >= wl->num_tx_desc || wl->tx_frames[id] == NULL)) {
@@ -91,6 +92,7 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
 
        skb = wl->tx_frames[id];
        info = IEEE80211_SKB_CB(skb);
+       tx_desc = (struct wl1271_tx_hw_descr *)skb->data;
 
        if (wl12xx_is_dummy_packet(wl, skb)) {
                wl1271_free_tx_id(wl, id);
@@ -105,7 +107,9 @@ static void wl18xx_tx_complete_packet(struct wl1271 *wl, u8 tx_stat_byte)
         * the info->status structures
         */
        wl18xx_get_last_tx_rate(wl, info->control.vif,
-                               info->band, &info->status.rates[0]);
+                               info->band,
+                               &info->status.rates[0],
+                               tx_desc->hlid);
 
        info->status.rates[0].count = 1; /* no data about retries */
        info->status.ack_signal = -1;
@@ -144,12 +148,22 @@ void wl18xx_tx_immediate_complete(struct wl1271 *wl)
        struct wl18xx_fw_status_priv *status_priv =
                (struct wl18xx_fw_status_priv *)wl->fw_status->priv;
        struct wl18xx_priv *priv = wl->priv;
-       u8 i;
+       u8 i, hlid;
 
        /* nothing to do here */
        if (priv->last_fw_rls_idx == status_priv->fw_release_idx)
                return;
 
+       /* update rates per link */
+       hlid = wl->fw_status->counters.hlid;
+
+       if (hlid < WLCORE_MAX_LINKS) {
+               wl->links[hlid].fw_rate_idx =
+                               wl->fw_status->counters.tx_last_rate;
+               wl->links[hlid].fw_rate_mbps =
+                               wl->fw_status->counters.tx_last_rate_mbps;
+       }
+
        /* freed Tx descriptors */
        wl1271_debug(DEBUG_TX, "last released desc = %d, current idx = %d",
                     priv->last_fw_rls_idx, status_priv->fw_release_idx);
index d65cc6dd7dff09084c6ea0da6106d447dcc97eca..5371cbdd54e07e9dc934a45670995e2042a4ef20 100644 (file)
@@ -125,7 +125,11 @@ struct wl18xx_fw_packet_counters {
        /* Tx rate of the last transmitted packet */
        u8 tx_last_rate;
 
-       u8 padding[2];
+       /* Tx rate or Tx rate estimate pre-calculated by fw in mbps units */
+       u8 tx_last_rate_mbps;
+
+       /* hlid for which the rates were reported */
+       u8 hlid;
 } __packed;
 
 /* FW status registers */
index 4652636e9ecf509ba11c4f47264332892e5f80a3..45aab1041d7f8445226ec06705510684d7371fa4 100644 (file)
@@ -4986,6 +4986,7 @@ static int wl12xx_sta_add(struct wl1271 *wl,
                return ret;
 
        wl_sta = (struct wl1271_station *)sta->drv_priv;
+       wl_sta->wl = wl;
        hlid = wl_sta->hlid;
 
        ret = wl12xx_cmd_add_peer(wl, wlvif, sta, hlid);
index c9bd294a0aa65b2f294c4168a725f579ab9b4068..b9e14045195fd734c5bff67585b36212305e7820 100644 (file)
@@ -222,6 +222,13 @@ int wlcore_rx(struct wl1271 *wl, struct wl_fw_status *status)
        enum wl_rx_buf_align rx_align;
        int ret = 0;
 
+       /* update rates per link */
+       hlid = status->counters.hlid;
+
+       if (hlid < WLCORE_MAX_LINKS)
+               wl->links[hlid].fw_rate_mbps =
+                               status->counters.tx_last_rate_mbps;
+
        while (drv_rx_counter != fw_rx_counter) {
                buf_size = 0;
                rx_counter = drv_rx_counter;
index f5f910b59d8622f7d89068be0b88807a0e0918d1..242b4e37b94c3504b102312e328566e51c5b555d 100644 (file)
@@ -171,6 +171,12 @@ struct wl_fw_status {
 
                /* Tx rate of the last transmitted packet */
                u8 tx_last_rate;
+
+               /* Tx rate or Tx rate estimate pre calculated by fw in mbps */
+               u8 tx_last_rate_mbps;
+
+               /* hlid for which the rates were reported */
+               u8 hlid;
        } counters;
 
        u32 log_start_addr;
@@ -273,6 +279,12 @@ struct wl1271_link {
        /* bitmap of TIDs where RX BA sessions are active for this link */
        u8 ba_bitmap;
 
+       /* the last fw rate index we used for this link */
+       u8 fw_rate_idx;
+
+       /* the last fw rate [Mbps] we used for this link */
+       u8 fw_rate_mbps;
+
        /* The wlvif this link belongs to. Might be null for global links */
        struct wl12xx_vif *wlvif;
 
@@ -335,6 +347,7 @@ struct wl1271_station {
         * Used in both AP and STA mode.
         */
        u64 total_freed_pkts;
+       struct wl1271 *wl;
 };
 
 struct wl12xx_vif {