Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Atheros CARL9170 driver
0003  *
0004  * MAC programming
0005  *
0006  * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
0007  *
0008  * This program is free software; you can redistribute it and/or modify
0009  * it under the terms of the GNU General Public License as published by
0010  * the Free Software Foundation; either version 2 of the License, or
0011  * (at your option) any later version.
0012  *
0013  * This program is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0016  * GNU General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU General Public License
0019  * along with this program; see the file COPYING.  If not, see
0020  * http://www.gnu.org/licenses/.
0021  *
0022  * This file incorporates work covered by the following copyright and
0023  * permission notice:
0024  *    Copyright (c) 2007-2008 Atheros Communications, Inc.
0025  *
0026  *    Permission to use, copy, modify, and/or distribute this software for any
0027  *    purpose with or without fee is hereby granted, provided that the above
0028  *    copyright notice and this permission notice appear in all copies.
0029  *
0030  *    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
0031  *    WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
0032  *    MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
0033  *    ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
0034  *    WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
0035  *    ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
0036  *    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0037  */
0038 
0039 #include <asm/unaligned.h>
0040 
0041 #include "carl9170.h"
0042 #include "cmd.h"
0043 
0044 int carl9170_set_dyn_sifs_ack(struct ar9170 *ar)
0045 {
0046     u32 val;
0047 
0048     if (conf_is_ht40(&ar->hw->conf))
0049         val = 0x010a;
0050     else {
0051         if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ)
0052             val = 0x105;
0053         else
0054             val = 0x104;
0055     }
0056 
0057     return carl9170_write_reg(ar, AR9170_MAC_REG_DYNAMIC_SIFS_ACK, val);
0058 }
0059 
0060 int carl9170_set_rts_cts_rate(struct ar9170 *ar)
0061 {
0062     u32 rts_rate, cts_rate;
0063 
0064     if (conf_is_ht(&ar->hw->conf)) {
0065         /* 12 mbit OFDM */
0066         rts_rate = 0x1da;
0067         cts_rate = 0x10a;
0068     } else {
0069         if (ar->hw->conf.chandef.chan->band == NL80211_BAND_2GHZ) {
0070             /* 11 mbit CCK */
0071             rts_rate = 033;
0072             cts_rate = 003;
0073         } else {
0074             /* 6 mbit OFDM */
0075             rts_rate = 0x1bb;
0076             cts_rate = 0x10b;
0077         }
0078     }
0079 
0080     return carl9170_write_reg(ar, AR9170_MAC_REG_RTS_CTS_RATE,
0081                   rts_rate | (cts_rate) << 16);
0082 }
0083 
0084 int carl9170_set_slot_time(struct ar9170 *ar)
0085 {
0086     struct ieee80211_vif *vif;
0087     u32 slottime = 20;
0088 
0089     rcu_read_lock();
0090     vif = carl9170_get_main_vif(ar);
0091     if (!vif) {
0092         rcu_read_unlock();
0093         return 0;
0094     }
0095 
0096     if ((ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ) ||
0097         vif->bss_conf.use_short_slot)
0098         slottime = 9;
0099 
0100     rcu_read_unlock();
0101 
0102     return carl9170_write_reg(ar, AR9170_MAC_REG_SLOT_TIME,
0103                   slottime << 10);
0104 }
0105 
0106 int carl9170_set_mac_rates(struct ar9170 *ar)
0107 {
0108     struct ieee80211_vif *vif;
0109     u32 basic, mandatory;
0110 
0111     rcu_read_lock();
0112     vif = carl9170_get_main_vif(ar);
0113 
0114     if (!vif) {
0115         rcu_read_unlock();
0116         return 0;
0117     }
0118 
0119     basic = (vif->bss_conf.basic_rates & 0xf);
0120     basic |= (vif->bss_conf.basic_rates & 0xff0) << 4;
0121     rcu_read_unlock();
0122 
0123     if (ar->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
0124         mandatory = 0xff00; /* OFDM 6/9/12/18/24/36/48/54 */
0125     else
0126         mandatory = 0xff0f; /* OFDM (6/9../54) + CCK (1/2/5.5/11) */
0127 
0128     carl9170_regwrite_begin(ar);
0129     carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, basic);
0130     carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, mandatory);
0131     carl9170_regwrite_finish();
0132 
0133     return carl9170_regwrite_result();
0134 }
0135 
0136 int carl9170_set_qos(struct ar9170 *ar)
0137 {
0138     carl9170_regwrite_begin(ar);
0139 
0140     carl9170_regwrite(AR9170_MAC_REG_AC0_CW, ar->edcf[0].cw_min |
0141               (ar->edcf[0].cw_max << 16));
0142     carl9170_regwrite(AR9170_MAC_REG_AC1_CW, ar->edcf[1].cw_min |
0143               (ar->edcf[1].cw_max << 16));
0144     carl9170_regwrite(AR9170_MAC_REG_AC2_CW, ar->edcf[2].cw_min |
0145               (ar->edcf[2].cw_max << 16));
0146     carl9170_regwrite(AR9170_MAC_REG_AC3_CW, ar->edcf[3].cw_min |
0147               (ar->edcf[3].cw_max << 16));
0148     carl9170_regwrite(AR9170_MAC_REG_AC4_CW, ar->edcf[4].cw_min |
0149               (ar->edcf[4].cw_max << 16));
0150 
0151     carl9170_regwrite(AR9170_MAC_REG_AC2_AC1_AC0_AIFS,
0152               ((ar->edcf[0].aifs * 9 + 10)) |
0153               ((ar->edcf[1].aifs * 9 + 10) << 12) |
0154               ((ar->edcf[2].aifs * 9 + 10) << 24));
0155     carl9170_regwrite(AR9170_MAC_REG_AC4_AC3_AC2_AIFS,
0156               ((ar->edcf[2].aifs * 9 + 10) >> 8) |
0157               ((ar->edcf[3].aifs * 9 + 10) << 4) |
0158               ((ar->edcf[4].aifs * 9 + 10) << 16));
0159 
0160     carl9170_regwrite(AR9170_MAC_REG_AC1_AC0_TXOP,
0161               ar->edcf[0].txop | ar->edcf[1].txop << 16);
0162     carl9170_regwrite(AR9170_MAC_REG_AC3_AC2_TXOP,
0163               ar->edcf[2].txop | ar->edcf[3].txop << 16 |
0164               ar->edcf[4].txop << 24);
0165 
0166     carl9170_regwrite_finish();
0167 
0168     return carl9170_regwrite_result();
0169 }
0170 
0171 int carl9170_init_mac(struct ar9170 *ar)
0172 {
0173     carl9170_regwrite_begin(ar);
0174 
0175     /* switch MAC to OTUS interface */
0176     carl9170_regwrite(0x1c3600, 0x3);
0177 
0178     carl9170_regwrite(AR9170_MAC_REG_ACK_EXTENSION, 0x40);
0179 
0180     carl9170_regwrite(AR9170_MAC_REG_RETRY_MAX, 0x0);
0181 
0182     carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
0183               AR9170_MAC_FTF_MONITOR);
0184 
0185     /* enable MMIC */
0186     carl9170_regwrite(AR9170_MAC_REG_SNIFFER,
0187             AR9170_MAC_SNIFFER_DEFAULTS);
0188 
0189     carl9170_regwrite(AR9170_MAC_REG_RX_THRESHOLD, 0xc1f80);
0190 
0191     carl9170_regwrite(AR9170_MAC_REG_RX_PE_DELAY, 0x70);
0192     carl9170_regwrite(AR9170_MAC_REG_EIFS_AND_SIFS, 0xa144000);
0193     carl9170_regwrite(AR9170_MAC_REG_SLOT_TIME, 9 << 10);
0194 
0195     /* CF-END & CF-ACK rate => 24M OFDM */
0196     carl9170_regwrite(AR9170_MAC_REG_TID_CFACK_CFEND_RATE, 0x59900000);
0197 
0198     /* NAV protects ACK only (in TXOP) */
0199     carl9170_regwrite(AR9170_MAC_REG_TXOP_DURATION, 0x201);
0200 
0201     /* Set Beacon PHY CTRL's TPC to 0x7, TA1=1 */
0202     /* OTUS set AM to 0x1 */
0203     carl9170_regwrite(AR9170_MAC_REG_BCN_HT1, 0x8000170);
0204 
0205     carl9170_regwrite(AR9170_MAC_REG_BACKOFF_PROTECT, 0x105);
0206 
0207     /* Aggregation MAX number and timeout */
0208     carl9170_regwrite(AR9170_MAC_REG_AMPDU_FACTOR, 0x8000a);
0209     carl9170_regwrite(AR9170_MAC_REG_AMPDU_DENSITY, 0x140a07);
0210 
0211     carl9170_regwrite(AR9170_MAC_REG_FRAMETYPE_FILTER,
0212               AR9170_MAC_FTF_DEFAULTS);
0213 
0214     carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL,
0215               AR9170_MAC_RX_CTRL_DEAGG |
0216               AR9170_MAC_RX_CTRL_SHORT_FILTER);
0217 
0218     /* rate sets */
0219     carl9170_regwrite(AR9170_MAC_REG_BASIC_RATE, 0x150f);
0220     carl9170_regwrite(AR9170_MAC_REG_MANDATORY_RATE, 0x150f);
0221     carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_RATE, 0x0030033);
0222 
0223     /* MIMO response control */
0224     carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, 0x4003c1e);
0225 
0226     carl9170_regwrite(AR9170_MAC_REG_AMPDU_RX_THRESH, 0xffff);
0227 
0228     /* set PHY register read timeout (??) */
0229     carl9170_regwrite(AR9170_MAC_REG_MISC_680, 0xf00008);
0230 
0231     /* Disable Rx TimeOut, workaround for BB. */
0232     carl9170_regwrite(AR9170_MAC_REG_RX_TIMEOUT, 0x0);
0233 
0234     /* Set WLAN DMA interrupt mode: generate int per packet */
0235     carl9170_regwrite(AR9170_MAC_REG_TXRX_MPI, 0x110011);
0236 
0237     carl9170_regwrite(AR9170_MAC_REG_FCS_SELECT,
0238             AR9170_MAC_FCS_FIFO_PROT);
0239 
0240     /* Disables the CF_END frame, undocumented register */
0241     carl9170_regwrite(AR9170_MAC_REG_TXOP_NOT_ENOUGH_IND,
0242             0x141e0f48);
0243 
0244     /* reset group hash table */
0245     carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, 0xffffffff);
0246     carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, 0xffffffff);
0247 
0248     /* disable PRETBTT interrupt */
0249     carl9170_regwrite(AR9170_MAC_REG_PRETBTT, 0x0);
0250     carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, 0x0);
0251 
0252     carl9170_regwrite_finish();
0253 
0254     return carl9170_regwrite_result();
0255 }
0256 
0257 static int carl9170_set_mac_reg(struct ar9170 *ar,
0258                 const u32 reg, const u8 *mac)
0259 {
0260     static const u8 zero[ETH_ALEN] = { 0 };
0261 
0262     if (!mac)
0263         mac = zero;
0264 
0265     carl9170_regwrite_begin(ar);
0266 
0267     carl9170_regwrite(reg, get_unaligned_le32(mac));
0268     carl9170_regwrite(reg + 4, get_unaligned_le16(mac + 4));
0269 
0270     carl9170_regwrite_finish();
0271 
0272     return carl9170_regwrite_result();
0273 }
0274 
0275 int carl9170_mod_virtual_mac(struct ar9170 *ar, const unsigned int id,
0276                  const u8 *mac)
0277 {
0278     if (WARN_ON(id >= ar->fw.vif_num))
0279         return -EINVAL;
0280 
0281     return carl9170_set_mac_reg(ar,
0282         AR9170_MAC_REG_ACK_TABLE + (id - 1) * 8, mac);
0283 }
0284 
0285 int carl9170_update_multicast(struct ar9170 *ar, const u64 mc_hash)
0286 {
0287     int err;
0288 
0289     carl9170_regwrite_begin(ar);
0290     carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_H, mc_hash >> 32);
0291     carl9170_regwrite(AR9170_MAC_REG_GROUP_HASH_TBL_L, mc_hash);
0292     carl9170_regwrite_finish();
0293     err = carl9170_regwrite_result();
0294     if (err)
0295         return err;
0296 
0297     ar->cur_mc_hash = mc_hash;
0298     return 0;
0299 }
0300 
0301 int carl9170_set_operating_mode(struct ar9170 *ar)
0302 {
0303     struct ieee80211_vif *vif;
0304     struct ath_common *common = &ar->common;
0305     u8 *mac_addr, *bssid;
0306     u32 cam_mode = AR9170_MAC_CAM_DEFAULTS;
0307     u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS |
0308         AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE;
0309     u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG |
0310               AR9170_MAC_RX_CTRL_SHORT_FILTER;
0311     u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS;
0312     int err = 0;
0313 
0314     rcu_read_lock();
0315     vif = carl9170_get_main_vif(ar);
0316 
0317     if (vif) {
0318         mac_addr = common->macaddr;
0319         bssid = common->curbssid;
0320 
0321         switch (vif->type) {
0322         case NL80211_IFTYPE_ADHOC:
0323             cam_mode |= AR9170_MAC_CAM_IBSS;
0324             break;
0325         case NL80211_IFTYPE_MESH_POINT:
0326         case NL80211_IFTYPE_AP:
0327             cam_mode |= AR9170_MAC_CAM_AP;
0328 
0329             /* iwlagn 802.11n STA Workaround */
0330             rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0331             break;
0332         case NL80211_IFTYPE_STATION:
0333             cam_mode |= AR9170_MAC_CAM_STA;
0334             rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0335             break;
0336         default:
0337             WARN(1, "Unsupported operation mode %x\n", vif->type);
0338             err = -EOPNOTSUPP;
0339             break;
0340         }
0341     } else {
0342         /*
0343          * Enable monitor mode
0344          *
0345          * rx_ctrl |= AR9170_MAC_RX_CTRL_ACK_IN_SNIFFER;
0346          * sniffer |= AR9170_MAC_SNIFFER_ENABLE_PROMISC;
0347          *
0348          * When the hardware is in SNIFFER_PROMISC mode,
0349          * it generates spurious ACKs for every incoming
0350          * frame. This confuses every peer in the
0351          * vicinity and the network throughput will suffer
0352          * badly.
0353          *
0354          * Hence, the hardware will be put into station
0355          * mode and just the rx filters are disabled.
0356          */
0357         cam_mode |= AR9170_MAC_CAM_STA;
0358         rx_ctrl |= AR9170_MAC_RX_CTRL_PASS_TO_HOST;
0359         mac_addr = common->macaddr;
0360         bssid = NULL;
0361     }
0362     rcu_read_unlock();
0363 
0364     if (err)
0365         return err;
0366 
0367     if (ar->rx_software_decryption)
0368         enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
0369 
0370     if (ar->sniffer_enabled) {
0371         enc_mode |= AR9170_MAC_ENCRYPTION_RX_SOFTWARE;
0372     }
0373 
0374     err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_MAC_ADDR_L, mac_addr);
0375     if (err)
0376         return err;
0377 
0378     err = carl9170_set_mac_reg(ar, AR9170_MAC_REG_BSSID_L, bssid);
0379     if (err)
0380         return err;
0381 
0382     carl9170_regwrite_begin(ar);
0383     carl9170_regwrite(AR9170_MAC_REG_SNIFFER, sniffer);
0384     carl9170_regwrite(AR9170_MAC_REG_CAM_MODE, cam_mode);
0385     carl9170_regwrite(AR9170_MAC_REG_ENCRYPTION, enc_mode);
0386     carl9170_regwrite(AR9170_MAC_REG_RX_CONTROL, rx_ctrl);
0387     carl9170_regwrite_finish();
0388 
0389     return carl9170_regwrite_result();
0390 }
0391 
0392 int carl9170_set_hwretry_limit(struct ar9170 *ar, const unsigned int max_retry)
0393 {
0394     u32 tmp = min_t(u32, 0x33333, max_retry * 0x11111);
0395 
0396     return carl9170_write_reg(ar, AR9170_MAC_REG_RETRY_MAX, tmp);
0397 }
0398 
0399 int carl9170_set_beacon_timers(struct ar9170 *ar)
0400 {
0401     struct ieee80211_vif *vif;
0402     u32 v = 0;
0403     u32 pretbtt = 0;
0404 
0405     rcu_read_lock();
0406     vif = carl9170_get_main_vif(ar);
0407 
0408     if (vif) {
0409         struct carl9170_vif_info *mvif;
0410         mvif = (void *) vif->drv_priv;
0411 
0412         if (mvif->enable_beacon && !WARN_ON(!ar->beacon_enabled)) {
0413             ar->global_beacon_int = vif->bss_conf.beacon_int /
0414                         ar->beacon_enabled;
0415 
0416             SET_VAL(AR9170_MAC_BCN_DTIM, v,
0417                 vif->bss_conf.dtim_period);
0418 
0419             switch (vif->type) {
0420             case NL80211_IFTYPE_MESH_POINT:
0421             case NL80211_IFTYPE_ADHOC:
0422                 v |= AR9170_MAC_BCN_IBSS_MODE;
0423                 break;
0424             case NL80211_IFTYPE_AP:
0425                 v |= AR9170_MAC_BCN_AP_MODE;
0426                 break;
0427             default:
0428                 WARN_ON_ONCE(1);
0429                 break;
0430             }
0431         } else if (vif->type == NL80211_IFTYPE_STATION) {
0432             ar->global_beacon_int = vif->bss_conf.beacon_int;
0433 
0434             SET_VAL(AR9170_MAC_BCN_DTIM, v,
0435                 ar->hw->conf.ps_dtim_period);
0436 
0437             v |= AR9170_MAC_BCN_STA_PS |
0438                  AR9170_MAC_BCN_PWR_MGT;
0439         }
0440 
0441         if (ar->global_beacon_int) {
0442             if (ar->global_beacon_int < 15) {
0443                 rcu_read_unlock();
0444                 return -ERANGE;
0445             }
0446 
0447             ar->global_pretbtt = ar->global_beacon_int -
0448                     CARL9170_PRETBTT_KUS;
0449         } else {
0450             ar->global_pretbtt = 0;
0451         }
0452     } else {
0453         ar->global_beacon_int = 0;
0454         ar->global_pretbtt = 0;
0455     }
0456 
0457     rcu_read_unlock();
0458 
0459     SET_VAL(AR9170_MAC_BCN_PERIOD, v, ar->global_beacon_int);
0460     SET_VAL(AR9170_MAC_PRETBTT, pretbtt, ar->global_pretbtt);
0461     SET_VAL(AR9170_MAC_PRETBTT2, pretbtt, ar->global_pretbtt);
0462 
0463     carl9170_regwrite_begin(ar);
0464     carl9170_regwrite(AR9170_MAC_REG_PRETBTT, pretbtt);
0465     carl9170_regwrite(AR9170_MAC_REG_BCN_PERIOD, v);
0466     carl9170_regwrite_finish();
0467     return carl9170_regwrite_result();
0468 }
0469 
0470 int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac,
0471             const u8 ktype, const u8 keyidx, const u8 *keydata,
0472             const int keylen)
0473 {
0474     struct carl9170_set_key_cmd key = { };
0475     static const u8 bcast[ETH_ALEN] = {
0476         0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
0477 
0478     mac = mac ? : bcast;
0479 
0480     key.user = cpu_to_le16(id);
0481     key.keyId = cpu_to_le16(keyidx);
0482     key.type = cpu_to_le16(ktype);
0483     memcpy(&key.macAddr, mac, ETH_ALEN);
0484     if (keydata)
0485         memcpy(&key.key, keydata, keylen);
0486 
0487     return carl9170_exec_cmd(ar, CARL9170_CMD_EKEY,
0488         sizeof(key), (u8 *)&key, 0, NULL);
0489 }
0490 
0491 int carl9170_disable_key(struct ar9170 *ar, const u8 id)
0492 {
0493     struct carl9170_disable_key_cmd key = { };
0494 
0495     key.user = cpu_to_le16(id);
0496 
0497     return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY,
0498         sizeof(key), (u8 *)&key, 0, NULL);
0499 }
0500 
0501 int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel)
0502 {
0503     unsigned int power, chains;
0504 
0505     if (ar->eeprom.tx_mask != 1)
0506         chains = AR9170_TX_PHY_TXCHAIN_2;
0507     else
0508         chains = AR9170_TX_PHY_TXCHAIN_1;
0509 
0510     switch (channel->band) {
0511     case NL80211_BAND_2GHZ:
0512         power = ar->power_2G_ofdm[0] & 0x3f;
0513         break;
0514     case NL80211_BAND_5GHZ:
0515         power = ar->power_5G_leg[0] & 0x3f;
0516         break;
0517     default:
0518         BUG();
0519     }
0520 
0521     power = min_t(unsigned int, power, ar->hw->conf.power_level * 2);
0522 
0523     carl9170_regwrite_begin(ar);
0524     carl9170_regwrite(AR9170_MAC_REG_ACK_TPC,
0525               0x3c1e | power << 20 | chains << 26);
0526     carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC,
0527               power << 5 | chains << 11 |
0528               power << 21 | chains << 27);
0529     carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC,
0530               power << 5 | chains << 11 |
0531               power << 21 | chains << 27);
0532     carl9170_regwrite_finish();
0533     return carl9170_regwrite_result();
0534 }