LCOV - code coverage report
Current view: top level - drivers/net/wireless/broadcom/b43legacy - xmit.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 359 0.0 %
Date: 2022-03-28 15:32:58 Functions: 0 14 0.0 %
Branches: 0 160 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0-or-later
       2                 :            : /*
       3                 :            : 
       4                 :            :   Broadcom B43legacy wireless driver
       5                 :            : 
       6                 :            :   Transmission (TX/RX) related functions.
       7                 :            : 
       8                 :            :   Copyright (C) 2005 Martin Langer <martin-langer@gmx.de>
       9                 :            :   Copyright (C) 2005 Stefano Brivio <stefano.brivio@polimi.it>
      10                 :            :   Copyright (C) 2005, 2006 Michael Buesch <m@bues.ch>
      11                 :            :   Copyright (C) 2005 Danny van Dyk <kugelfang@gentoo.org>
      12                 :            :   Copyright (C) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
      13                 :            :   Copyright (C) 2007 Larry Finger <Larry.Finger@lwfinger.net>
      14                 :            : 
      15                 :            : 
      16                 :            : */
      17                 :            : 
      18                 :            : #include <net/dst.h>
      19                 :            : 
      20                 :            : #include "xmit.h"
      21                 :            : #include "phy.h"
      22                 :            : #include "dma.h"
      23                 :            : #include "pio.h"
      24                 :            : 
      25                 :            : 
      26                 :            : /* Extract the bitrate out of a CCK PLCP header. */
      27                 :            : static u8 b43legacy_plcp_get_bitrate_idx_cck(struct b43legacy_plcp_hdr6 *plcp)
      28                 :            : {
      29                 :            :         switch (plcp->raw[0]) {
      30                 :            :         case 0x0A:
      31                 :            :                 return 0;
      32                 :            :         case 0x14:
      33                 :            :                 return 1;
      34                 :            :         case 0x37:
      35                 :            :                 return 2;
      36                 :            :         case 0x6E:
      37                 :            :                 return 3;
      38                 :            :         }
      39                 :            :         B43legacy_BUG_ON(1);
      40                 :            :         return -1;
      41                 :            : }
      42                 :            : 
      43                 :            : /* Extract the bitrate out of an OFDM PLCP header. */
      44                 :          0 : static u8 b43legacy_plcp_get_bitrate_idx_ofdm(struct b43legacy_plcp_hdr6 *plcp,
      45                 :            :                                               bool aphy)
      46                 :            : {
      47         [ #  # ]:          0 :         int base = aphy ? 0 : 4;
      48                 :            : 
      49   [ #  #  #  #  :          0 :         switch (plcp->raw[0] & 0xF) {
             #  #  #  #  
                      # ]
      50                 :          0 :         case 0xB:
      51                 :          0 :                 return base + 0;
      52                 :          0 :         case 0xF:
      53                 :          0 :                 return base + 1;
      54                 :          0 :         case 0xA:
      55                 :          0 :                 return base + 2;
      56                 :          0 :         case 0xE:
      57                 :          0 :                 return base + 3;
      58                 :          0 :         case 0x9:
      59                 :          0 :                 return base + 4;
      60                 :          0 :         case 0xD:
      61                 :          0 :                 return base + 5;
      62                 :          0 :         case 0x8:
      63                 :          0 :                 return base + 6;
      64                 :          0 :         case 0xC:
      65                 :          0 :                 return base + 7;
      66                 :            :         }
      67                 :          0 :         B43legacy_BUG_ON(1);
      68                 :            :         return -1;
      69                 :            : }
      70                 :            : 
      71                 :          0 : u8 b43legacy_plcp_get_ratecode_cck(const u8 bitrate)
      72                 :            : {
      73   [ #  #  #  #  :          0 :         switch (bitrate) {
                      # ]
      74                 :            :         case B43legacy_CCK_RATE_1MB:
      75                 :            :                 return 0x0A;
      76                 :          0 :         case B43legacy_CCK_RATE_2MB:
      77                 :          0 :                 return 0x14;
      78                 :          0 :         case B43legacy_CCK_RATE_5MB:
      79                 :          0 :                 return 0x37;
      80                 :          0 :         case B43legacy_CCK_RATE_11MB:
      81                 :          0 :                 return 0x6E;
      82                 :            :         }
      83                 :          0 :         B43legacy_BUG_ON(1);
      84                 :            :         return 0;
      85                 :            : }
      86                 :            : 
      87                 :          0 : u8 b43legacy_plcp_get_ratecode_ofdm(const u8 bitrate)
      88                 :            : {
      89   [ #  #  #  #  :          0 :         switch (bitrate) {
             #  #  #  #  
                      # ]
      90                 :            :         case B43legacy_OFDM_RATE_6MB:
      91                 :            :                 return 0xB;
      92                 :          0 :         case B43legacy_OFDM_RATE_9MB:
      93                 :          0 :                 return 0xF;
      94                 :          0 :         case B43legacy_OFDM_RATE_12MB:
      95                 :          0 :                 return 0xA;
      96                 :          0 :         case B43legacy_OFDM_RATE_18MB:
      97                 :          0 :                 return 0xE;
      98                 :          0 :         case B43legacy_OFDM_RATE_24MB:
      99                 :          0 :                 return 0x9;
     100                 :          0 :         case B43legacy_OFDM_RATE_36MB:
     101                 :          0 :                 return 0xD;
     102                 :          0 :         case B43legacy_OFDM_RATE_48MB:
     103                 :          0 :                 return 0x8;
     104                 :          0 :         case B43legacy_OFDM_RATE_54MB:
     105                 :          0 :                 return 0xC;
     106                 :            :         }
     107                 :          0 :         B43legacy_BUG_ON(1);
     108                 :            :         return 0;
     109                 :            : }
     110                 :            : 
     111                 :          0 : void b43legacy_generate_plcp_hdr(struct b43legacy_plcp_hdr4 *plcp,
     112                 :            :                                  const u16 octets, const u8 bitrate)
     113                 :            : {
     114                 :          0 :         __le32 *data = &(plcp->data);
     115                 :          0 :         __u8 *raw = plcp->raw;
     116                 :            : 
     117         [ #  # ]:          0 :         if (b43legacy_is_ofdm_rate(bitrate)) {
     118                 :          0 :                 u16 d;
     119                 :            : 
     120                 :          0 :                 d = b43legacy_plcp_get_ratecode_ofdm(bitrate);
     121         [ #  # ]:          0 :                 B43legacy_WARN_ON(octets & 0xF000);
     122                 :          0 :                 d |= (octets << 5);
     123                 :          0 :                 *data = cpu_to_le32(d);
     124                 :            :         } else {
     125                 :          0 :                 u32 plen;
     126                 :            : 
     127                 :          0 :                 plen = octets * 16 / bitrate;
     128         [ #  # ]:          0 :                 if ((octets * 16 % bitrate) > 0) {
     129                 :          0 :                         plen++;
     130         [ #  # ]:          0 :                         if ((bitrate == B43legacy_CCK_RATE_11MB)
     131         [ #  # ]:          0 :                             && ((octets * 8 % 11) < 4))
     132                 :          0 :                                 raw[1] = 0x84;
     133                 :            :                         else
     134                 :          0 :                                 raw[1] = 0x04;
     135                 :            :                 } else
     136                 :          0 :                         raw[1] = 0x04;
     137                 :          0 :                 *data |= cpu_to_le32(plen << 16);
     138                 :          0 :                 raw[0] = b43legacy_plcp_get_ratecode_cck(bitrate);
     139                 :            :         }
     140                 :          0 : }
     141                 :            : 
     142                 :          0 : static u8 b43legacy_calc_fallback_rate(u8 bitrate)
     143                 :            : {
     144   [ #  #  #  #  :          0 :         switch (bitrate) {
          #  #  #  #  #  
                #  #  # ]
     145                 :            :         case B43legacy_CCK_RATE_1MB:
     146                 :            :                 return B43legacy_CCK_RATE_1MB;
     147                 :            :         case B43legacy_CCK_RATE_2MB:
     148                 :            :                 return B43legacy_CCK_RATE_1MB;
     149                 :          0 :         case B43legacy_CCK_RATE_5MB:
     150                 :          0 :                 return B43legacy_CCK_RATE_2MB;
     151                 :          0 :         case B43legacy_CCK_RATE_11MB:
     152                 :          0 :                 return B43legacy_CCK_RATE_5MB;
     153                 :          0 :         case B43legacy_OFDM_RATE_6MB:
     154                 :          0 :                 return B43legacy_CCK_RATE_5MB;
     155                 :          0 :         case B43legacy_OFDM_RATE_9MB:
     156                 :          0 :                 return B43legacy_OFDM_RATE_6MB;
     157                 :          0 :         case B43legacy_OFDM_RATE_12MB:
     158                 :          0 :                 return B43legacy_OFDM_RATE_9MB;
     159                 :          0 :         case B43legacy_OFDM_RATE_18MB:
     160                 :          0 :                 return B43legacy_OFDM_RATE_12MB;
     161                 :          0 :         case B43legacy_OFDM_RATE_24MB:
     162                 :          0 :                 return B43legacy_OFDM_RATE_18MB;
     163                 :          0 :         case B43legacy_OFDM_RATE_36MB:
     164                 :          0 :                 return B43legacy_OFDM_RATE_24MB;
     165                 :          0 :         case B43legacy_OFDM_RATE_48MB:
     166                 :          0 :                 return B43legacy_OFDM_RATE_36MB;
     167                 :          0 :         case B43legacy_OFDM_RATE_54MB:
     168                 :          0 :                 return B43legacy_OFDM_RATE_48MB;
     169                 :            :         }
     170                 :          0 :         B43legacy_BUG_ON(1);
     171                 :            :         return 0;
     172                 :            : }
     173                 :            : 
     174                 :          0 : static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
     175                 :            :                                struct b43legacy_txhdr_fw3 *txhdr,
     176                 :            :                                const unsigned char *fragment_data,
     177                 :            :                                unsigned int fragment_len,
     178                 :            :                                struct ieee80211_tx_info *info,
     179                 :            :                                u16 cookie)
     180                 :            : {
     181                 :          0 :         const struct ieee80211_hdr *wlhdr;
     182                 :          0 :         int use_encryption = !!info->control.hw_key;
     183                 :          0 :         u8 rate;
     184                 :          0 :         struct ieee80211_rate *rate_fb;
     185                 :          0 :         int rate_ofdm;
     186                 :          0 :         int rate_fb_ofdm;
     187                 :          0 :         unsigned int plcp_fragment_len;
     188                 :          0 :         u32 mac_ctl = 0;
     189                 :          0 :         u16 phy_ctl = 0;
     190                 :          0 :         struct ieee80211_rate *tx_rate;
     191                 :          0 :         struct ieee80211_tx_rate *rates;
     192                 :            : 
     193                 :          0 :         wlhdr = (const struct ieee80211_hdr *)fragment_data;
     194                 :            : 
     195                 :          0 :         memset(txhdr, 0, sizeof(*txhdr));
     196                 :            : 
     197         [ #  # ]:          0 :         tx_rate = ieee80211_get_tx_rate(dev->wl->hw, info);
     198                 :            : 
     199                 :          0 :         rate = tx_rate->hw_value;
     200         [ #  # ]:          0 :         rate_ofdm = b43legacy_is_ofdm_rate(rate);
     201   [ #  #  #  # ]:          0 :         rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : tx_rate;
     202         [ #  # ]:          0 :         rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
     203                 :            : 
     204                 :          0 :         txhdr->mac_frame_ctl = wlhdr->frame_control;
     205                 :          0 :         memcpy(txhdr->tx_receiver, wlhdr->addr1, ETH_ALEN);
     206                 :            : 
     207                 :            :         /* Calculate duration for fallback rate */
     208         [ #  # ]:          0 :         if ((rate_fb->hw_value == rate) ||
     209   [ #  #  #  # ]:          0 :             (wlhdr->duration_id & cpu_to_le16(0x8000)) ||
     210                 :            :             (wlhdr->duration_id == cpu_to_le16(0))) {
     211                 :            :                 /* If the fallback rate equals the normal rate or the
     212                 :            :                  * dur_id field contains an AID, CFP magic or 0,
     213                 :            :                  * use the original dur_id field. */
     214                 :          0 :                 txhdr->dur_fb = wlhdr->duration_id;
     215                 :            :         } else {
     216                 :          0 :                 txhdr->dur_fb = ieee80211_generic_frame_duration(dev->wl->hw,
     217                 :            :                                                          info->control.vif,
     218                 :          0 :                                                          info->band,
     219                 :            :                                                          fragment_len,
     220                 :            :                                                          rate_fb);
     221                 :            :         }
     222                 :            : 
     223                 :          0 :         plcp_fragment_len = fragment_len + FCS_LEN;
     224         [ #  # ]:          0 :         if (use_encryption) {
     225                 :          0 :                 u8 key_idx = info->control.hw_key->hw_key_idx;
     226                 :          0 :                 struct b43legacy_key *key;
     227                 :          0 :                 int wlhdr_len;
     228                 :          0 :                 size_t iv_len;
     229                 :            : 
     230         [ #  # ]:          0 :                 B43legacy_WARN_ON(key_idx >= dev->max_nr_keys);
     231                 :          0 :                 key = &(dev->key[key_idx]);
     232                 :            : 
     233         [ #  # ]:          0 :                 if (key->enabled) {
     234                 :            :                         /* Hardware appends ICV. */
     235                 :          0 :                         plcp_fragment_len += info->control.hw_key->icv_len;
     236                 :            : 
     237         [ #  # ]:          0 :                         key_idx = b43legacy_kidx_to_fw(dev, key_idx);
     238                 :          0 :                         mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
     239                 :            :                                    B43legacy_TX4_MAC_KEYIDX;
     240                 :          0 :                         mac_ctl |= (key->algorithm <<
     241                 :          0 :                                    B43legacy_TX4_MAC_KEYALG_SHIFT) &
     242                 :            :                                    B43legacy_TX4_MAC_KEYALG;
     243                 :          0 :                         wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
     244                 :          0 :                         iv_len = min_t(size_t, info->control.hw_key->iv_len,
     245                 :            :                                      ARRAY_SIZE(txhdr->iv));
     246                 :          0 :                         memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
     247                 :            :                 } else {
     248                 :            :                         /* This key is invalid. This might only happen
     249                 :            :                          * in a short timeframe after machine resume before
     250                 :            :                          * we were able to reconfigure keys.
     251                 :            :                          * Drop this packet completely. Do not transmit it
     252                 :            :                          * unencrypted to avoid leaking information. */
     253                 :            :                         return -ENOKEY;
     254                 :            :                 }
     255                 :            :         }
     256                 :          0 :         b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
     257                 :          0 :                                     (&txhdr->plcp), plcp_fragment_len,
     258                 :            :                                     rate);
     259                 :          0 :         b43legacy_generate_plcp_hdr(&txhdr->plcp_fb, plcp_fragment_len,
     260                 :          0 :                                     rate_fb->hw_value);
     261                 :            : 
     262                 :            :         /* PHY TX Control word */
     263                 :          0 :         if (rate_ofdm)
     264                 :            :                 phy_ctl |= B43legacy_TX4_PHY_ENC_OFDM;
     265         [ #  # ]:          0 :         if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
     266                 :          0 :                 phy_ctl |= B43legacy_TX4_PHY_SHORTPRMBL;
     267                 :          0 :         phy_ctl |= B43legacy_TX4_PHY_ANTLAST;
     268                 :            : 
     269                 :            :         /* MAC control */
     270                 :          0 :         rates = info->control.rates;
     271         [ #  # ]:          0 :         if (!(info->flags & IEEE80211_TX_CTL_NO_ACK))
     272                 :          0 :                 mac_ctl |= B43legacy_TX4_MAC_ACK;
     273         [ #  # ]:          0 :         if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
     274                 :          0 :                 mac_ctl |= B43legacy_TX4_MAC_HWSEQ;
     275         [ #  # ]:          0 :         if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)
     276                 :          0 :                 mac_ctl |= B43legacy_TX4_MAC_STMSDU;
     277         [ #  # ]:          0 :         if (rate_fb_ofdm)
     278                 :          0 :                 mac_ctl |= B43legacy_TX4_MAC_FALLBACKOFDM;
     279                 :            : 
     280                 :            :         /* Overwrite rates[0].count to make the retry calculation
     281                 :            :          * in the tx status easier. need the actual retry limit to
     282                 :            :          * detect whether the fallback rate was used.
     283                 :            :          */
     284         [ #  # ]:          0 :         if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
     285         [ #  # ]:          0 :             (rates[0].count <= dev->wl->hw->conf.long_frame_max_tx_count)) {
     286                 :          0 :                 rates[0].count = dev->wl->hw->conf.long_frame_max_tx_count;
     287                 :          0 :                 mac_ctl |= B43legacy_TX4_MAC_LONGFRAME;
     288                 :            :         } else {
     289                 :          0 :                 rates[0].count = dev->wl->hw->conf.short_frame_max_tx_count;
     290                 :            :         }
     291                 :            : 
     292                 :            :         /* Generate the RTS or CTS-to-self frame */
     293         [ #  # ]:          0 :         if ((rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
     294                 :            :             (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) {
     295                 :          0 :                 unsigned int len;
     296                 :          0 :                 struct ieee80211_hdr *hdr;
     297                 :          0 :                 int rts_rate;
     298                 :          0 :                 int rts_rate_fb;
     299                 :          0 :                 int rts_rate_fb_ofdm;
     300                 :            : 
     301         [ #  # ]:          0 :                 rts_rate = ieee80211_get_rts_cts_rate(dev->wl->hw, info)->hw_value;
     302                 :          0 :                 rts_rate_fb = b43legacy_calc_fallback_rate(rts_rate);
     303         [ #  # ]:          0 :                 rts_rate_fb_ofdm = b43legacy_is_ofdm_rate(rts_rate_fb);
     304                 :          0 :                 if (rts_rate_fb_ofdm)
     305                 :          0 :                         mac_ctl |= B43legacy_TX4_MAC_CTSFALLBACKOFDM;
     306                 :            : 
     307         [ #  # ]:          0 :                 if (rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
     308                 :          0 :                         ieee80211_ctstoself_get(dev->wl->hw,
     309                 :            :                                                 info->control.vif,
     310                 :            :                                                 fragment_data,
     311                 :            :                                                 fragment_len, info,
     312                 :            :                                                 (struct ieee80211_cts *)
     313                 :          0 :                                                 (txhdr->rts_frame));
     314                 :          0 :                         mac_ctl |= B43legacy_TX4_MAC_SENDCTS;
     315                 :          0 :                         len = sizeof(struct ieee80211_cts);
     316                 :            :                 } else {
     317                 :          0 :                         ieee80211_rts_get(dev->wl->hw,
     318                 :            :                                           info->control.vif,
     319                 :            :                                           fragment_data, fragment_len, info,
     320                 :            :                                           (struct ieee80211_rts *)
     321                 :          0 :                                           (txhdr->rts_frame));
     322                 :          0 :                         mac_ctl |= B43legacy_TX4_MAC_SENDRTS;
     323                 :          0 :                         len = sizeof(struct ieee80211_rts);
     324                 :            :                 }
     325                 :          0 :                 len += FCS_LEN;
     326                 :          0 :                 b43legacy_generate_plcp_hdr((struct b43legacy_plcp_hdr4 *)
     327                 :          0 :                                             (&txhdr->rts_plcp),
     328                 :            :                                             len, rts_rate);
     329                 :          0 :                 b43legacy_generate_plcp_hdr(&txhdr->rts_plcp_fb,
     330                 :            :                                             len, rts_rate_fb);
     331                 :          0 :                 hdr = (struct ieee80211_hdr *)(&txhdr->rts_frame);
     332                 :          0 :                 txhdr->rts_dur_fb = hdr->duration_id;
     333                 :            :         }
     334                 :            : 
     335                 :            :         /* Magic cookie */
     336                 :          0 :         txhdr->cookie = cpu_to_le16(cookie);
     337                 :            : 
     338                 :            :         /* Apply the bitfields */
     339                 :          0 :         txhdr->mac_ctl = cpu_to_le32(mac_ctl);
     340                 :          0 :         txhdr->phy_ctl = cpu_to_le16(phy_ctl);
     341                 :            : 
     342                 :          0 :         return 0;
     343                 :            : }
     344                 :            : 
     345                 :          0 : int b43legacy_generate_txhdr(struct b43legacy_wldev *dev,
     346                 :            :                               u8 *txhdr,
     347                 :            :                               const unsigned char *fragment_data,
     348                 :            :                               unsigned int fragment_len,
     349                 :            :                               struct ieee80211_tx_info *info,
     350                 :            :                               u16 cookie)
     351                 :            : {
     352                 :          0 :         return generate_txhdr_fw3(dev, (struct b43legacy_txhdr_fw3 *)txhdr,
     353                 :            :                            fragment_data, fragment_len,
     354                 :            :                            info, cookie);
     355                 :            : }
     356                 :            : 
     357                 :          0 : static s8 b43legacy_rssi_postprocess(struct b43legacy_wldev *dev,
     358                 :            :                                      u8 in_rssi, int ofdm,
     359                 :            :                                      int adjust_2053, int adjust_2050)
     360                 :            : {
     361                 :          0 :         struct b43legacy_phy *phy = &dev->phy;
     362                 :          0 :         s32 tmp;
     363                 :            : 
     364      [ #  #  # ]:          0 :         switch (phy->radio_ver) {
     365                 :          0 :         case 0x2050:
     366         [ #  # ]:          0 :                 if (ofdm) {
     367                 :          0 :                         tmp = in_rssi;
     368         [ #  # ]:          0 :                         if (tmp > 127)
     369                 :          0 :                                 tmp -= 256;
     370                 :          0 :                         tmp *= 73;
     371                 :          0 :                         tmp /= 64;
     372         [ #  # ]:          0 :                         if (adjust_2050)
     373                 :          0 :                                 tmp += 25;
     374                 :            :                         else
     375                 :          0 :                                 tmp -= 3;
     376                 :            :                 } else {
     377         [ #  # ]:          0 :                         if (dev->dev->bus->sprom.boardflags_lo
     378                 :            :                             & B43legacy_BFL_RSSI) {
     379                 :          0 :                                 if (in_rssi > 63)
     380                 :            :                                         in_rssi = 63;
     381                 :          0 :                                 tmp = phy->nrssi_lt[in_rssi];
     382                 :          0 :                                 tmp = 31 - tmp;
     383                 :          0 :                                 tmp *= -131;
     384                 :          0 :                                 tmp /= 128;
     385                 :          0 :                                 tmp -= 57;
     386                 :            :                         } else {
     387                 :          0 :                                 tmp = in_rssi;
     388                 :          0 :                                 tmp = 31 - tmp;
     389                 :          0 :                                 tmp *= -149;
     390                 :          0 :                                 tmp /= 128;
     391                 :          0 :                                 tmp -= 68;
     392                 :            :                         }
     393   [ #  #  #  # ]:          0 :                         if (phy->type == B43legacy_PHYTYPE_G &&
     394                 :            :                             adjust_2050)
     395                 :          0 :                                 tmp += 25;
     396                 :            :                 }
     397                 :            :                 break;
     398                 :          0 :         case 0x2060:
     399         [ #  # ]:          0 :                 if (in_rssi > 127)
     400                 :          0 :                         tmp = in_rssi - 256;
     401                 :            :                 else
     402                 :          0 :                         tmp = in_rssi;
     403                 :            :                 break;
     404                 :          0 :         default:
     405                 :          0 :                 tmp = in_rssi;
     406                 :          0 :                 tmp -= 11;
     407                 :          0 :                 tmp *= 103;
     408                 :          0 :                 tmp /= 64;
     409         [ #  # ]:          0 :                 if (adjust_2053)
     410                 :          0 :                         tmp -= 109;
     411                 :            :                 else
     412                 :          0 :                         tmp -= 83;
     413                 :            :         }
     414                 :            : 
     415                 :          0 :         return (s8)tmp;
     416                 :            : }
     417                 :            : 
     418                 :          0 : void b43legacy_rx(struct b43legacy_wldev *dev,
     419                 :            :                   struct sk_buff *skb,
     420                 :            :                   const void *_rxhdr)
     421                 :            : {
     422                 :          0 :         struct ieee80211_rx_status status;
     423                 :          0 :         struct b43legacy_plcp_hdr6 *plcp;
     424                 :          0 :         struct ieee80211_hdr *wlhdr;
     425                 :          0 :         const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr;
     426                 :          0 :         __le16 fctl;
     427                 :          0 :         u16 phystat0;
     428                 :          0 :         u16 phystat3;
     429                 :          0 :         u16 chanstat;
     430                 :          0 :         u16 mactime;
     431                 :          0 :         u32 macstat;
     432                 :          0 :         u16 chanid;
     433                 :          0 :         u8 jssi;
     434                 :          0 :         int padding;
     435                 :            : 
     436                 :          0 :         memset(&status, 0, sizeof(status));
     437                 :            : 
     438                 :            :         /* Get metadata about the frame from the header. */
     439                 :          0 :         phystat0 = le16_to_cpu(rxhdr->phy_status0);
     440                 :          0 :         phystat3 = le16_to_cpu(rxhdr->phy_status3);
     441                 :          0 :         jssi = rxhdr->jssi;
     442                 :          0 :         macstat = le16_to_cpu(rxhdr->mac_status);
     443                 :          0 :         mactime = le16_to_cpu(rxhdr->mac_time);
     444                 :          0 :         chanstat = le16_to_cpu(rxhdr->channel);
     445                 :            : 
     446         [ #  # ]:          0 :         if (macstat & B43legacy_RX_MAC_FCSERR)
     447                 :          0 :                 dev->wl->ieee_stats.dot11FCSErrorCount++;
     448                 :            : 
     449                 :            :         /* Skip PLCP and padding */
     450                 :          0 :         padding = (macstat & B43legacy_RX_MAC_PADDING) ? 2 : 0;
     451         [ #  # ]:          0 :         if (unlikely(skb->len < (sizeof(struct b43legacy_plcp_hdr6) +
     452                 :            :             padding))) {
     453                 :          0 :                 b43legacydbg(dev->wl, "RX: Packet size underrun (1)\n");
     454                 :          0 :                 goto drop;
     455                 :            :         }
     456                 :          0 :         plcp = (struct b43legacy_plcp_hdr6 *)(skb->data + padding);
     457                 :          0 :         skb_pull(skb, sizeof(struct b43legacy_plcp_hdr6) + padding);
     458                 :            :         /* The skb contains the Wireless Header + payload data now */
     459         [ #  # ]:          0 :         if (unlikely(skb->len < (2+2+6/*minimum hdr*/ + FCS_LEN))) {
     460                 :          0 :                 b43legacydbg(dev->wl, "RX: Packet size underrun (2)\n");
     461                 :          0 :                 goto drop;
     462                 :            :         }
     463                 :          0 :         wlhdr = (struct ieee80211_hdr *)(skb->data);
     464                 :          0 :         fctl = wlhdr->frame_control;
     465                 :            : 
     466         [ #  # ]:          0 :         if ((macstat & B43legacy_RX_MAC_DEC) &&
     467                 :            :             !(macstat & B43legacy_RX_MAC_DECERR)) {
     468                 :          0 :                 unsigned int keyidx;
     469                 :          0 :                 int wlhdr_len;
     470                 :          0 :                 int iv_len;
     471                 :          0 :                 int icv_len;
     472                 :            : 
     473                 :          0 :                 keyidx = ((macstat & B43legacy_RX_MAC_KEYIDX)
     474                 :          0 :                           >> B43legacy_RX_MAC_KEYIDX_SHIFT);
     475                 :            :                 /* We must adjust the key index here. We want the "physical"
     476                 :            :                  * key index, but the ucode passed it slightly different.
     477                 :            :                  */
     478         [ #  # ]:          0 :                 keyidx = b43legacy_kidx_to_raw(dev, keyidx);
     479         [ #  # ]:          0 :                 B43legacy_WARN_ON(keyidx >= dev->max_nr_keys);
     480                 :            : 
     481         [ #  # ]:          0 :                 if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) {
     482                 :            :                         /* Remove PROTECTED flag to mark it as decrypted. */
     483         [ #  # ]:          0 :                         B43legacy_WARN_ON(!ieee80211_has_protected(fctl));
     484                 :          0 :                         fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED);
     485                 :          0 :                         wlhdr->frame_control = fctl;
     486                 :            : 
     487                 :          0 :                         wlhdr_len = ieee80211_hdrlen(fctl);
     488         [ #  # ]:          0 :                         if (unlikely(skb->len < (wlhdr_len + 3))) {
     489                 :          0 :                                 b43legacydbg(dev->wl, "RX: Packet size"
     490                 :            :                                              " underrun3\n");
     491                 :          0 :                                 goto drop;
     492                 :            :                         }
     493         [ #  # ]:          0 :                         if (skb->data[wlhdr_len + 3] & (1 << 5)) {
     494                 :            :                                 /* The Ext-IV Bit is set in the "KeyID"
     495                 :            :                                  * octet of the IV.
     496                 :            :                                  */
     497                 :            :                                 iv_len = 8;
     498                 :            :                                 icv_len = 8;
     499                 :            :                         } else {
     500                 :          0 :                                 iv_len = 4;
     501                 :          0 :                                 icv_len = 4;
     502                 :            :                         }
     503         [ #  # ]:          0 :                         if (unlikely(skb->len < (wlhdr_len + iv_len +
     504                 :            :                             icv_len))) {
     505                 :          0 :                                 b43legacydbg(dev->wl, "RX: Packet size"
     506                 :            :                                              " underrun4\n");
     507                 :          0 :                                 goto drop;
     508                 :            :                         }
     509                 :            :                         /* Remove the IV */
     510                 :          0 :                         memmove(skb->data + iv_len, skb->data, wlhdr_len);
     511                 :          0 :                         skb_pull(skb, iv_len);
     512                 :            :                         /* Remove the ICV */
     513                 :          0 :                         skb_trim(skb, skb->len - icv_len);
     514                 :            : 
     515                 :          0 :                         status.flag |= RX_FLAG_DECRYPTED;
     516                 :            :                 }
     517                 :            :         }
     518                 :            : 
     519                 :          0 :         status.signal = b43legacy_rssi_postprocess(dev, jssi,
     520                 :            :                                       (phystat0 & B43legacy_RX_PHYST0_OFDM),
     521                 :            :                                       (phystat0 & B43legacy_RX_PHYST0_GAINCTL),
     522                 :            :                                       (phystat3 & B43legacy_RX_PHYST3_TRSTATE));
     523                 :            :         /* change to support A PHY */
     524         [ #  # ]:          0 :         if (phystat0 & B43legacy_RX_PHYST0_OFDM)
     525                 :          0 :                 status.rate_idx = b43legacy_plcp_get_bitrate_idx_ofdm(plcp, false);
     526                 :            :         else
     527                 :          0 :                 status.rate_idx = b43legacy_plcp_get_bitrate_idx_cck(plcp);
     528                 :          0 :         status.antenna = !!(phystat0 & B43legacy_RX_PHYST0_ANT);
     529                 :            : 
     530                 :            :         /*
     531                 :            :          * All frames on monitor interfaces and beacons always need a full
     532                 :            :          * 64-bit timestamp. Monitor interfaces need it for diagnostic
     533                 :            :          * purposes and beacons for IBSS merging.
     534                 :            :          * This code assumes we get to process the packet within 16 bits
     535                 :            :          * of timestamp, i.e. about 65 milliseconds after the PHY received
     536                 :            :          * the first symbol.
     537                 :            :          */
     538   [ #  #  #  # ]:          0 :         if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) {
     539                 :          0 :                 u16 low_mactime_now;
     540                 :            : 
     541                 :          0 :                 b43legacy_tsf_read(dev, &status.mactime);
     542                 :          0 :                 low_mactime_now = status.mactime;
     543                 :          0 :                 status.mactime = status.mactime & ~0xFFFFULL;
     544                 :          0 :                 status.mactime += mactime;
     545         [ #  # ]:          0 :                 if (low_mactime_now <= mactime)
     546                 :          0 :                         status.mactime -= 0x10000;
     547                 :          0 :                 status.flag |= RX_FLAG_MACTIME_START;
     548                 :            :         }
     549                 :            : 
     550                 :          0 :         chanid = (chanstat & B43legacy_RX_CHAN_ID) >>
     551                 :            :                   B43legacy_RX_CHAN_ID_SHIFT;
     552         [ #  # ]:          0 :         switch (chanstat & B43legacy_RX_CHAN_PHYTYPE) {
     553                 :          0 :         case B43legacy_PHYTYPE_B:
     554                 :            :         case B43legacy_PHYTYPE_G:
     555                 :          0 :                 status.band = NL80211_BAND_2GHZ;
     556                 :          0 :                 status.freq = chanid + 2400;
     557                 :          0 :                 break;
     558                 :          0 :         default:
     559                 :          0 :                 b43legacywarn(dev->wl, "Unexpected value for chanstat (0x%X)\n",
     560                 :            :                        chanstat);
     561                 :            :         }
     562                 :            : 
     563                 :          0 :         memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
     564                 :          0 :         ieee80211_rx_irqsafe(dev->wl->hw, skb);
     565                 :            : 
     566                 :          0 :         return;
     567                 :          0 : drop:
     568                 :          0 :         b43legacydbg(dev->wl, "RX: Packet dropped\n");
     569                 :          0 :         dev_kfree_skb_any(skb);
     570                 :            : }
     571                 :            : 
     572                 :          0 : void b43legacy_handle_txstatus(struct b43legacy_wldev *dev,
     573                 :            :                              const struct b43legacy_txstatus *status)
     574                 :            : {
     575                 :          0 :         b43legacy_debugfs_log_txstat(dev, status);
     576                 :            : 
     577         [ #  # ]:          0 :         if (status->intermediate)
     578                 :            :                 return;
     579         [ #  # ]:          0 :         if (status->for_ampdu)
     580                 :            :                 return;
     581         [ #  # ]:          0 :         if (!status->acked)
     582                 :          0 :                 dev->wl->ieee_stats.dot11ACKFailureCount++;
     583         [ #  # ]:          0 :         if (status->rts_count) {
     584         [ #  # ]:          0 :                 if (status->rts_count == 0xF) /* FIXME */
     585                 :          0 :                         dev->wl->ieee_stats.dot11RTSFailureCount++;
     586                 :            :                 else
     587                 :          0 :                         dev->wl->ieee_stats.dot11RTSSuccessCount++;
     588                 :            :         }
     589                 :            : 
     590         [ #  # ]:          0 :         if (b43legacy_using_pio(dev))
     591                 :          0 :                 b43legacy_pio_handle_txstatus(dev, status);
     592                 :            :         else
     593                 :          0 :                 b43legacy_dma_handle_txstatus(dev, status);
     594                 :            : }
     595                 :            : 
     596                 :            : /* Handle TX status report as received through DMA/PIO queues */
     597                 :          0 : void b43legacy_handle_hwtxstatus(struct b43legacy_wldev *dev,
     598                 :            :                                  const struct b43legacy_hwtxstatus *hw)
     599                 :            : {
     600                 :          0 :         struct b43legacy_txstatus status;
     601                 :          0 :         u8 tmp;
     602                 :            : 
     603                 :          0 :         status.cookie = le16_to_cpu(hw->cookie);
     604                 :          0 :         status.seq = le16_to_cpu(hw->seq);
     605                 :          0 :         status.phy_stat = hw->phy_stat;
     606                 :          0 :         tmp = hw->count;
     607                 :          0 :         status.frame_count = (tmp >> 4);
     608                 :          0 :         status.rts_count = (tmp & 0x0F);
     609                 :          0 :         tmp = hw->flags << 1;
     610                 :          0 :         status.supp_reason = ((tmp & 0x1C) >> 2);
     611                 :          0 :         status.pm_indicated = !!(tmp & 0x80);
     612                 :          0 :         status.intermediate = !!(tmp & 0x40);
     613                 :          0 :         status.for_ampdu = !!(tmp & 0x20);
     614                 :          0 :         status.acked = !!(tmp & 0x02);
     615                 :            : 
     616                 :          0 :         b43legacy_handle_txstatus(dev, &status);
     617                 :          0 : }
     618                 :            : 
     619                 :            : /* Stop any TX operation on the device (suspend the hardware queues) */
     620                 :          0 : void b43legacy_tx_suspend(struct b43legacy_wldev *dev)
     621                 :            : {
     622         [ #  # ]:          0 :         if (b43legacy_using_pio(dev))
     623                 :          0 :                 b43legacy_pio_freeze_txqueues(dev);
     624                 :            :         else
     625                 :          0 :                 b43legacy_dma_tx_suspend(dev);
     626                 :          0 : }
     627                 :            : 
     628                 :            : /* Resume any TX operation on the device (resume the hardware queues) */
     629                 :          0 : void b43legacy_tx_resume(struct b43legacy_wldev *dev)
     630                 :            : {
     631         [ #  # ]:          0 :         if (b43legacy_using_pio(dev))
     632                 :          0 :                 b43legacy_pio_thaw_txqueues(dev);
     633                 :            :         else
     634                 :          0 :                 b43legacy_dma_tx_resume(dev);
     635                 :          0 : }
     636                 :            : 
     637                 :            : /* Initialize the QoS parameters */
     638                 :          0 : void b43legacy_qos_init(struct b43legacy_wldev *dev)
     639                 :            : {
     640                 :            :         /* FIXME: This function must probably be called from the mac80211
     641                 :            :          * config callback. */
     642                 :          0 : return;
     643                 :            : 
     644                 :            :         b43legacy_hf_write(dev, b43legacy_hf_read(dev) | B43legacy_HF_EDCF);
     645                 :            :         /* FIXME kill magic */
     646                 :            :         b43legacy_write16(dev, 0x688,
     647                 :            :                           b43legacy_read16(dev, 0x688) | 0x4);
     648                 :            : 
     649                 :            : 
     650                 :            :         /*TODO: We might need some stack support here to get the values. */
     651                 :            : }

Generated by: LCOV version 1.14