diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-rs.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 156 |
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: | 1367 | out: |
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 |