aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
diff options
context:
space:
mode:
authorGuy Cohen <guy.cohen@intel.com>2008-09-08 22:54:54 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-11 15:53:39 -0400
commit3110bef78cb4282c58245bc8fd6d95d9ccb19749 (patch)
tree4c867dcaa5e7aa7b7f688fc86eb7c3a654bf1eff /drivers/net/wireless/iwlwifi/iwl-agn-rs.c
parent90d7795e152f9b7095adef77b71a4448f092e3b6 (diff)
iwlwifi: Added support for 3 antennas
Added support for 3 antennas for Legacy, SISO and MIMO2. MIMO3 is still not supported yet. Signed-off-by: Guy Cohen <guy.cohen@intel.com> Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Zhu Yi <yi.zhu@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c156
1 files changed, 104 insertions, 52 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index de00be1bffad..c293e5b6cbb5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -1282,15 +1282,23 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1282 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1282 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1283 u8 start_action = tbl->action; 1283 u8 start_action = tbl->action;
1284 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1284 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1285 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1285 int ret = 0; 1286 int ret = 0;
1286 1287
1287 for (; ;) { 1288 for (; ;) {
1288 switch (tbl->action) { 1289 switch (tbl->action) {
1289 case IWL_LEGACY_SWITCH_ANTENNA: 1290 case IWL_LEGACY_SWITCH_ANTENNA1:
1291 case IWL_LEGACY_SWITCH_ANTENNA2:
1290 IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n"); 1292 IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
1291 1293
1292 lq_sta->action_counter++; 1294 lq_sta->action_counter++;
1293 1295
1296 if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
1297 tx_chains_num <= 1) ||
1298 (tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
1299 tx_chains_num <= 2))
1300 break;
1301
1294 /* Don't change antenna if success has been great */ 1302 /* Don't change antenna if success has been great */
1295 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1303 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1296 break; 1304 break;
@@ -1300,7 +1308,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1300 1308
1301 if (rs_toggle_antenna(valid_tx_ant, 1309 if (rs_toggle_antenna(valid_tx_ant,
1302 &search_tbl->current_rate, search_tbl)) { 1310 &search_tbl->current_rate, search_tbl)) {
1303 lq_sta->search_better_tbl = 1; 1311 rs_set_expected_tpt_table(lq_sta, search_tbl);
1304 goto out; 1312 goto out;
1305 } 1313 }
1306 break; 1314 break;
@@ -1313,43 +1321,54 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1313 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1321 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1314 search_tbl, index); 1322 search_tbl, index);
1315 if (!ret) { 1323 if (!ret) {
1316 lq_sta->search_better_tbl = 1;
1317 lq_sta->action_counter = 0; 1324 lq_sta->action_counter = 0;
1318 goto out; 1325 goto out;
1319 } 1326 }
1320 1327
1321 break; 1328 break;
1322 case IWL_LEGACY_SWITCH_MIMO2: 1329 case IWL_LEGACY_SWITCH_MIMO2_AB:
1330 case IWL_LEGACY_SWITCH_MIMO2_AC:
1331 case IWL_LEGACY_SWITCH_MIMO2_BC:
1323 IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n"); 1332 IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
1324 1333
1325 /* Set up search table to try MIMO */ 1334 /* Set up search table to try MIMO */
1326 memcpy(search_tbl, tbl, sz); 1335 memcpy(search_tbl, tbl, sz);
1327 search_tbl->is_SGI = 0; 1336 search_tbl->is_SGI = 0;
1328 search_tbl->ant_type = ANT_AB;/*FIXME:RS*/ 1337
1329 /*FIXME:RS:need to check ant validity*/ 1338 if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
1339 search_tbl->ant_type = ANT_AB;
1340 else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
1341 search_tbl->ant_type = ANT_AC;
1342 else
1343 search_tbl->ant_type = ANT_BC;
1344
1345 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1346 break;
1347
1330 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1348 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1331 search_tbl, index); 1349 search_tbl, index);
1332 if (!ret) { 1350 if (!ret) {
1333 lq_sta->search_better_tbl = 1;
1334 lq_sta->action_counter = 0; 1351 lq_sta->action_counter = 0;
1335 goto out; 1352 goto out;
1336 } 1353 }
1337 break; 1354 break;
1338 } 1355 }
1339 tbl->action++; 1356 tbl->action++;
1340 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) 1357 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
1341 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1358 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1342 1359
1343 if (tbl->action == start_action) 1360 if (tbl->action == start_action)
1344 break; 1361 break;
1345 1362
1346 } 1363 }
1364 search_tbl->lq_type = LQ_NONE;
1347 return 0; 1365 return 0;
1348 1366
1349 out: 1367out:
1368 lq_sta->search_better_tbl = 1;
1350 tbl->action++; 1369 tbl->action++;
1351 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) 1370 if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
1352 tbl->action = IWL_LEGACY_SWITCH_ANTENNA; 1371 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1353 return 0; 1372 return 0;
1354 1373
1355} 1374}
@@ -1371,34 +1390,51 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1371 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1390 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1372 u8 start_action = tbl->action; 1391 u8 start_action = tbl->action;
1373 u8 valid_tx_ant = priv->hw_params.valid_tx_ant; 1392 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1393 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1374 int ret; 1394 int ret;
1375 1395
1376 for (;;) { 1396 for (;;) {
1377 lq_sta->action_counter++; 1397 lq_sta->action_counter++;
1378 switch (tbl->action) { 1398 switch (tbl->action) {
1379 case IWL_SISO_SWITCH_ANTENNA: 1399 case IWL_SISO_SWITCH_ANTENNA1:
1400 case IWL_SISO_SWITCH_ANTENNA2:
1380 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n"); 1401 IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
1402
1403 if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
1404 tx_chains_num <= 1) ||
1405 (tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
1406 tx_chains_num <= 2))
1407 break;
1408
1381 if (window->success_ratio >= IWL_RS_GOOD_RATIO) 1409 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1382 break; 1410 break;
1383 1411
1384 memcpy(search_tbl, tbl, sz); 1412 memcpy(search_tbl, tbl, sz);
1385 if (rs_toggle_antenna(valid_tx_ant, 1413 if (rs_toggle_antenna(valid_tx_ant,
1386 &search_tbl->current_rate, search_tbl)) { 1414 &search_tbl->current_rate, search_tbl))
1387 lq_sta->search_better_tbl = 1;
1388 goto out; 1415 goto out;
1389 }
1390 break; 1416 break;
1391 case IWL_SISO_SWITCH_MIMO2: 1417 case IWL_SISO_SWITCH_MIMO2_AB:
1418 case IWL_SISO_SWITCH_MIMO2_AC:
1419 case IWL_SISO_SWITCH_MIMO2_BC:
1392 IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n"); 1420 IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
1393 memcpy(search_tbl, tbl, sz); 1421 memcpy(search_tbl, tbl, sz);
1394 search_tbl->is_SGI = 0; 1422 search_tbl->is_SGI = 0;
1395 search_tbl->ant_type = ANT_AB; /*FIXME:RS*/ 1423
1424 if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
1425 search_tbl->ant_type = ANT_AB;
1426 else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
1427 search_tbl->ant_type = ANT_AC;
1428 else
1429 search_tbl->ant_type = ANT_BC;
1430
1431 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1432 break;
1433
1396 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, 1434 ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
1397 search_tbl, index); 1435 search_tbl, index);
1398 if (!ret) { 1436 if (!ret)
1399 lq_sta->search_better_tbl = 1;
1400 goto out; 1437 goto out;
1401 }
1402 break; 1438 break;
1403 case IWL_SISO_SWITCH_GI: 1439 case IWL_SISO_SWITCH_GI:
1404 if (!tbl->is_fat && 1440 if (!tbl->is_fat &&
@@ -1428,22 +1464,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1428 } 1464 }
1429 search_tbl->current_rate = rate_n_flags_from_tbl( 1465 search_tbl->current_rate = rate_n_flags_from_tbl(
1430 search_tbl, index, is_green); 1466 search_tbl, index, is_green);
1431 lq_sta->search_better_tbl = 1;
1432 goto out; 1467 goto out;
1433 } 1468 }
1434 tbl->action++; 1469 tbl->action++;
1435 if (tbl->action > IWL_SISO_SWITCH_GI) 1470 if (tbl->action > IWL_SISO_SWITCH_GI)
1436 tbl->action = IWL_SISO_SWITCH_ANTENNA; 1471 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1437 1472
1438 if (tbl->action == start_action) 1473 if (tbl->action == start_action)
1439 break; 1474 break;
1440 } 1475 }
1476 search_tbl->lq_type = LQ_NONE;
1441 return 0; 1477 return 0;
1442 1478
1443 out: 1479 out:
1480 lq_sta->search_better_tbl = 1;
1444 tbl->action++; 1481 tbl->action++;
1445 if (tbl->action > IWL_SISO_SWITCH_GI) 1482 if (tbl->action > IWL_SISO_SWITCH_GI)
1446 tbl->action = IWL_SISO_SWITCH_ANTENNA; 1483 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1447 return 0; 1484 return 0;
1448} 1485}
1449 1486
@@ -1459,37 +1496,58 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1459 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 1496 struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
1460 struct iwl_scale_tbl_info *search_tbl = 1497 struct iwl_scale_tbl_info *search_tbl =
1461 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); 1498 &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
1499 struct iwl_rate_scale_data *window = &(tbl->win[index]);
1462 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1500 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1463 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1501 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1464 u8 start_action = tbl->action; 1502 u8 start_action = tbl->action;
1465 /*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/ 1503 u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
1504 u8 tx_chains_num = priv->hw_params.tx_chains_num;
1466 int ret; 1505 int ret;
1467 1506
1468 for (;;) { 1507 for (;;) {
1469 lq_sta->action_counter++; 1508 lq_sta->action_counter++;
1470 switch (tbl->action) { 1509 switch (tbl->action) {
1471 case IWL_MIMO_SWITCH_ANTENNA_A: 1510 case IWL_MIMO2_SWITCH_ANTENNA1:
1472 case IWL_MIMO_SWITCH_ANTENNA_B: 1511 case IWL_MIMO2_SWITCH_ANTENNA2:
1512 IWL_DEBUG_RATE("LQ: MIMO toggle Antennas\n");
1513
1514 if (tx_chains_num <= 2)
1515 break;
1516
1517 if (window->success_ratio >= IWL_RS_GOOD_RATIO)
1518 break;
1519
1520 memcpy(search_tbl, tbl, sz);
1521 if (rs_toggle_antenna(valid_tx_ant,
1522 &search_tbl->current_rate, search_tbl))
1523 goto out;
1524 break;
1525 case IWL_MIMO2_SWITCH_SISO_A:
1526 case IWL_MIMO2_SWITCH_SISO_B:
1527 case IWL_MIMO2_SWITCH_SISO_C:
1473 IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n"); 1528 IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
1474 1529
1475 /* Set up new search table for SISO */ 1530 /* Set up new search table for SISO */
1476 memcpy(search_tbl, tbl, sz); 1531 memcpy(search_tbl, tbl, sz);
1477 1532
1478 /*FIXME:RS:need to check ant validity + C*/ 1533 if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
1479 if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
1480 search_tbl->ant_type = ANT_A; 1534 search_tbl->ant_type = ANT_A;
1481 else 1535 else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
1482 search_tbl->ant_type = ANT_B; 1536 search_tbl->ant_type = ANT_B;
1537 else
1538 search_tbl->ant_type = ANT_C;
1539
1540 if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
1541 break;
1483 1542
1484 ret = rs_switch_to_siso(priv, lq_sta, conf, sta, 1543 ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
1485 search_tbl, index); 1544 search_tbl, index);
1486 if (!ret) { 1545 if (!ret)
1487 lq_sta->search_better_tbl = 1;
1488 goto out; 1546 goto out;
1489 } 1547
1490 break; 1548 break;
1491 1549
1492 case IWL_MIMO_SWITCH_GI: 1550 case IWL_MIMO2_SWITCH_GI:
1493 if (!tbl->is_fat && 1551 if (!tbl->is_fat &&
1494 !(priv->current_ht_config.sgf & 1552 !(priv->current_ht_config.sgf &
1495 HT_SHORT_GI_20MHZ)) 1553 HT_SHORT_GI_20MHZ))
@@ -1518,23 +1576,23 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
1518 } 1576 }
1519 search_tbl->current_rate = rate_n_flags_from_tbl( 1577 search_tbl->current_rate = rate_n_flags_from_tbl(
1520 search_tbl, index, is_green); 1578 search_tbl, index, is_green);
1521 lq_sta->search_better_tbl = 1;
1522 goto out; 1579 goto out;
1523 1580
1524 } 1581 }
1525 tbl->action++; 1582 tbl->action++;
1526 if (tbl->action > IWL_MIMO_SWITCH_GI) 1583 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1527 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; 1584 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1528 1585
1529 if (tbl->action == start_action) 1586 if (tbl->action == start_action)
1530 break; 1587 break;
1531 } 1588 }
1532 1589 search_tbl->lq_type = LQ_NONE;
1533 return 0; 1590 return 0;
1534 out: 1591 out:
1592 lq_sta->search_better_tbl = 1;
1535 tbl->action++; 1593 tbl->action++;
1536 if (tbl->action > IWL_MIMO_SWITCH_GI) 1594 if (tbl->action > IWL_MIMO2_SWITCH_GI)
1537 tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; 1595 tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
1538 return 0; 1596 return 0;
1539 1597
1540} 1598}
@@ -1749,19 +1807,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1749 rs_stay_in_table(lq_sta); 1807 rs_stay_in_table(lq_sta);
1750 1808
1751 goto out; 1809 goto out;
1810 }
1752 1811
1753 /* Else we have enough samples; calculate estimate of 1812 /* Else we have enough samples; calculate estimate of
1754 * actual average throughput */ 1813 * actual average throughput */
1755 } else { 1814
1756 /*FIXME:RS remove this else if we don't get this error*/ 1815 BUG_ON(window->average_tpt != ((window->success_ratio *
1757 if (window->average_tpt != ((window->success_ratio * 1816 tbl->expected_tpt[index] + 64) / 128));
1758 tbl->expected_tpt[index] + 64) / 128)) {
1759 IWL_ERROR("expected_tpt should have been calculated"
1760 " by now\n");
1761 window->average_tpt = ((window->success_ratio *
1762 tbl->expected_tpt[index] + 64) / 128);
1763 }
1764 }
1765 1817
1766 /* If we are searching for better modulation mode, check success. */ 1818 /* If we are searching for better modulation mode, check success. */
1767 if (lq_sta->search_better_tbl) { 1819 if (lq_sta->search_better_tbl) {
@@ -1771,7 +1823,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
1771 * continuing to use the setup that we've been trying. */ 1823 * continuing to use the setup that we've been trying. */
1772 if (window->average_tpt > lq_sta->last_tpt) { 1824 if (window->average_tpt > lq_sta->last_tpt) {
1773 1825
1774 IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE " 1826 IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
1775 "suc=%d cur-tpt=%d old-tpt=%d\n", 1827 "suc=%d cur-tpt=%d old-tpt=%d\n",
1776 window->success_ratio, 1828 window->success_ratio,
1777 window->average_tpt, 1829 window->average_tpt,
@@ -2184,7 +2236,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
2184 for (i = 0; i < IWL_RATE_COUNT; i++) 2236 for (i = 0; i < IWL_RATE_COUNT; i++)
2185 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); 2237 rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
2186 2238
2187 IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n"); 2239 IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
2188 /* TODO: what is a good starting rate for STA? About middle? Maybe not 2240 /* TODO: what is a good starting rate for STA? About middle? Maybe not
2189 * the lowest or the highest rate.. Could consider using RSSI from 2241 * the lowest or the highest rate.. Could consider using RSSI from
2190 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2242 * previous packets? Need to have IEEE 802.1X auth succeed immediately