| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Used to test iwl-phy-db.c. |
| // |
| // A note for the GCC static initialization of flexible array members: |
| // |
| // Since 'struct iwl_calib_res_notif_phy_db' contains a zero-length-array, this requires a special |
| // way to assign initialization value for it. See |
| // |
| // https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html |
| // |
| #include <gtest/gtest.h> |
| |
| extern "C" { |
| #include "third_party/iwlwifi/iwl-phy-db.h" |
| } |
| |
| namespace wlan { |
| namespace testing { |
| namespace { |
| |
| class IwlPhyDbTest : public ::testing::Test { |
| public: |
| IwlPhyDbTest() {} |
| ~IwlPhyDbTest() {} |
| |
| struct iwl_phy_db* phy_db() { |
| return phy_db_; |
| } |
| |
| void SetUp() override { phy_db_ = iwl_phy_db_init(nullptr); } |
| |
| void TearDown() override { iwl_phy_db_free(phy_db_); } |
| |
| private: |
| struct iwl_phy_db* phy_db_; |
| }; |
| |
| // Expect the iwl_phy_db_send_all_channel_groups() returns ZX_OK right after init before there is |
| // no data set yet. This is a regression test to catch a bug involving underflow on the channel |
| // argument to iwl_phy_db_send_all_channel_groups(). |
| TEST_F(IwlPhyDbTest, TestSendAllChannelGroupsAfterInit) { |
| EXPECT_NE(nullptr, phy_db()); |
| |
| EXPECT_EQ(ZX_OK, iwl_phy_db_send_all_channel_groups(phy_db(), IWL_PHY_DB_CALIB_CHG_PAPD, -1)); |
| EXPECT_EQ(ZX_OK, iwl_phy_db_send_all_channel_groups(phy_db(), IWL_PHY_DB_CALIB_CHG_TXP, -1)); |
| } |
| |
| // Test setting the IWL_PHY_DB_CFG section |
| TEST_F(IwlPhyDbTest, SetSectionCfg) { |
| EXPECT_EQ(nullptr, phy_db()->calib_ch_group_papd); |
| EXPECT_EQ(-1, phy_db()->n_group_papd); |
| |
| // A packet to set the cfg db. |
| const size_t chg_id_size = 7; // Just an arbitrary value. |
| struct { |
| struct iwl_rx_packet hdr; // must be at begin of struct. |
| struct { // equal to the 'data' field. |
| struct iwl_calib_res_notif_phy_db hdr; |
| uint8_t data[chg_id_size]; |
| } phy_db_notif; |
| } pkt = { |
| .phy_db_notif = |
| { |
| .hdr = |
| { |
| .type = IWL_PHY_DB_CFG, |
| .length = chg_id_size, |
| }, |
| .data = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}, |
| }, |
| }; |
| struct iwl_rx_packet* pkt_p = reinterpret_cast<struct iwl_rx_packet*>(&pkt); |
| |
| // Expect success |
| EXPECT_EQ(ZX_OK, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| |
| struct iwl_phy_db_entry* entry = iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CFG, 0); |
| EXPECT_NE(nullptr, entry); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_NE(nullptr, entry->data); |
| } |
| |
| // Test setting the IWL_PHY_DB_CALIB_CHG_PAPD section |
| TEST_F(IwlPhyDbTest, SetSectionPapd) { |
| EXPECT_EQ(nullptr, phy_db()->calib_ch_group_papd); |
| EXPECT_EQ(-1, phy_db()->n_group_papd); |
| |
| // A packet to set the calib db with chg_id 0x0102. |
| const size_t chg_id_size = sizeof(__le16); // chg_id |
| struct { |
| struct iwl_rx_packet hdr; // must be at begin of struct. |
| struct { // equal to the 'data' field. |
| struct iwl_calib_res_notif_phy_db hdr; |
| uint8_t data[chg_id_size]; |
| } phy_db_notif; |
| } pkt = { |
| .phy_db_notif = |
| { |
| .hdr = |
| { |
| .type = IWL_PHY_DB_CALIB_CHG_PAPD, |
| .length = chg_id_size, |
| }, |
| .data = |
| { |
| 0x02, 0x01, // chg_id 0x0102 |
| }, |
| }, |
| }; |
| struct iwl_rx_packet* pkt_p = reinterpret_cast<struct iwl_rx_packet*>(&pkt); |
| |
| // Expect success |
| EXPECT_EQ(ZX_OK, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_NE(nullptr, phy_db()->calib_ch_group_papd); |
| EXPECT_EQ(0x0103, phy_db()->n_group_papd); |
| struct iwl_phy_db_entry* entry = |
| iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_PAPD, 0x0102); |
| EXPECT_NE(nullptr, entry); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x02, entry->data[0]); |
| EXPECT_EQ(0x01, entry->data[1]); |
| |
| // Set with a larger chg_id 0x01ff. Expect it is rejected. |
| pkt.phy_db_notif.data[0] = 0xff; // data[1] is still 0x01. |
| EXPECT_EQ(ZX_ERR_INVALID_ARGS, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_EQ(0x0103, phy_db()->n_group_papd); // Expect unchanged. |
| entry = iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_PAPD, 0x0102); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x02, entry->data[0]); |
| EXPECT_EQ(0x01, entry->data[1]); |
| |
| // Set with a smaller chg_id 0x0101. Expect success. |
| pkt.phy_db_notif.data[0] = 0x01; |
| EXPECT_EQ(ZX_OK, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_EQ(0x0103, phy_db()->n_group_papd); // Expect unchanged. |
| entry = iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_PAPD, 0x0101); |
| EXPECT_NE(nullptr, entry); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x01, entry->data[0]); |
| EXPECT_EQ(0x01, entry->data[1]); |
| } |
| |
| // Similar to SetSectionCalib above, but check different fields. |
| TEST_F(IwlPhyDbTest, SetSectionTxp) { |
| EXPECT_EQ(nullptr, phy_db()->calib_ch_group_txp); |
| EXPECT_EQ(-1, phy_db()->n_group_txp); |
| |
| // A packet to set the calib db with chg_id 0x0102. |
| const size_t chg_id_size = sizeof(__le16); // chg_id |
| struct { |
| struct iwl_rx_packet hdr; // must be at begin of struct. |
| struct { // equal to the 'data' field. |
| struct iwl_calib_res_notif_phy_db hdr; |
| uint8_t data[2]; |
| } phy_db_notif; |
| } pkt = { |
| .phy_db_notif = {.hdr = |
| { |
| .type = IWL_PHY_DB_CALIB_CHG_TXP, |
| .length = chg_id_size, |
| }, |
| .data = |
| { |
| 0x04, 0x02, // chg_id 0x0204 |
| }}, |
| }; |
| struct iwl_rx_packet* pkt_p = reinterpret_cast<struct iwl_rx_packet*>(&pkt); |
| |
| // Expect success |
| EXPECT_EQ(ZX_OK, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_NE(nullptr, phy_db()->calib_ch_group_txp); |
| EXPECT_EQ(0x0205, phy_db()->n_group_txp); |
| struct iwl_phy_db_entry* entry = |
| iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_TXP, 0x0204); |
| EXPECT_NE(nullptr, entry); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x04, entry->data[0]); |
| EXPECT_EQ(0x02, entry->data[1]); |
| |
| // Set with a larger chg_id 0x02ff. Expect it is rejected. |
| pkt.phy_db_notif.data[0] = 0xff; // data[1] is still 0x01. |
| EXPECT_EQ(ZX_ERR_INVALID_ARGS, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_EQ(0x0205, phy_db()->n_group_txp); // Expect unchanged. |
| entry = iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_TXP, 0x0204); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x04, entry->data[0]); |
| EXPECT_EQ(0x02, entry->data[1]); |
| |
| // Set with a smaller chg_id 0x0201. Expect success. |
| pkt.phy_db_notif.data[0] = 0x01; |
| EXPECT_EQ(ZX_OK, iwl_phy_db_set_section(phy_db(), pkt_p)); |
| EXPECT_EQ(0x0205, phy_db()->n_group_txp); // Expect unchanged. |
| entry = iwl_phy_db_get_section(phy_db(), IWL_PHY_DB_CALIB_CHG_TXP, 0x0201); |
| EXPECT_NE(nullptr, entry); |
| EXPECT_EQ(chg_id_size, entry->size); |
| EXPECT_EQ(0x01, entry->data[0]); |
| EXPECT_EQ(0x02, entry->data[1]); |
| } |
| |
| } // namespace |
| } // namespace testing |
| } // namespace wlan |