Skip to content

Sdr.c

Function openwifi_is_radio_enabled(struct openwifi_priv *priv)

openwifi_is_radio_enabled: The function of openwifi_is_radio_enabled is to determine if the radio is enabled based on the transmission interface configuration.

parameters: The parameters of this Function. · parameter1: struct openwifi_priv *priv - A pointer to the structure that holds the private data for the OpenWiFi device, which includes configuration settings and state information.

Code Description: The openwifi_is_radio_enabled function checks whether the radio is enabled by evaluating the transmission interface configuration stored in the priv structure. It first initializes an integer variable reg to hold the attenuation value retrieved from the AD9361 PHY device. The function checks the value of priv->tx_intf_cfg to determine the appropriate transmission interface configuration. If the configuration matches one of the specified 20MHz bandwidth settings (TX_INTF_BW_20MHZ_AT_0MHZ_ANT0, TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0, or TX_INTF_BW_20MHZ_AT_0MHZ_ANT_BOTH), it calls the ad9361_get_tx_atten function with a parameter of 1. Otherwise, it calls ad9361_get_tx_atten with a parameter of 2.

The attenuation value returned by ad9361_get_tx_atten is then compared against a predefined threshold, AD9361_RADIO_OFF_TX_ATT. If the value of reg is less than AD9361_RADIO_OFF_TX_ATT, the function returns true, indicating that the radio is enabled. If the value is equal to or greater than AD9361_RADIO_OFF_TX_ATT, the function returns false, indicating that the radio is disabled.

Note: It is important to ensure that the priv structure is properly initialized before calling this function to avoid undefined behavior. Additionally, the function assumes that the ad9361_phy member of the priv structure is valid and correctly configured.

Output Example: If the radio is enabled, the function will return true; if the radio is disabled, it will return false. For instance, if the configuration is set to TX_INTF_BW_20MHZ_AT_0MHZ_ANT0 and the attenuation value is below the threshold, the output will be true. Conversely, if the configuration is set to TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0 and the attenuation value is above the threshold, the output will be false.

graph TD
    A[Start] --> B[Check tx_intf_cfg]
    B -->|TX_INTF_BW_20MHZ_AT_0MHZ_ANT0| C[Get tx_atten with parameter 1]
    B -->|TX_INTF_BW_20MHZ_AT_N_10MHZ_ANT0| C
    B -->|TX_INTF_BW_20MHZ_AT_0MHZ_ANT_BOTH| C
    B -->|Other| D[Get tx_atten with parameter 2]
    C --> E[Compare reg with AD9361_RADIO_OFF_TX_ATT]
    D --> E
    E -->|reg < AD9361_RADIO_OFF_TX_ATT| F[Return true]
    E -->|reg >= AD9361_RADIO_OFF_TX_ATT| G[Return false]
    F --> H[End]
    G --> H

Function openwifi_rfkill_init(struct ieee80211_hw *hw)

openwifi_rfkill_init: The function of openwifi_rfkill_init is to initialize the RF kill state for the OpenWiFi device.

parameters: The parameters of this Function. · hw: A pointer to the ieee80211_hw structure, which contains hardware-specific information for the wireless device.

Code Description: The openwifi_rfkill_init function is responsible for setting up the radio frequency (RF) kill switch state for a wireless device managed by the OpenWiFi driver. It begins by retrieving the private data structure associated with the hardware pointer hw, which is of type struct openwifi_priv. This structure contains various device-specific configurations and states.

The function then checks if the radio is enabled by calling the openwifi_is_radio_enabled function, which returns a boolean value indicating the status of the radio. This value is stored in the rfkill_off member of the priv structure. The RF kill state is crucial as it determines whether the wireless functionality is active or disabled.

Next, the function logs the current state of the wireless switch using the printk function. It outputs a message that includes the compatibility string sdr_compatible_str and indicates whether the RF kill switch is "on" or "off" based on the value of priv->rfkill_off.

Following the logging, the function updates the hardware state of the wireless device by calling wiphy_rfkill_set_hw_state. This function is provided with the wiphy pointer from the hw structure and the negation of priv->rfkill_off, effectively setting the hardware state to reflect whether the radio is enabled or disabled.

Finally, the function initiates polling for the RF kill state by invoking wiphy_rfkill_start_polling, which allows the driver to monitor changes in the RF kill switch state over time.

Note: It is important to ensure that the hardware pointer passed to this function is valid and properly initialized before calling openwifi_rfkill_init. Additionally, the function assumes that the necessary structures and functions for managing the RF kill state are correctly implemented and available in the driver context.

graph TD
    A[Start openwifi_rfkill_init] --> B[Retrieve private data from hw]
    B --> C[Check if radio is enabled]
    C --> D[Store radio state in priv->rfkill_off]
    D --> E[Log wireless switch state]
    E --> F[Set hardware state based on rfkill_off]
    F --> G[Start polling for rfkill state]
    G --> H[End openwifi_rfkill_init]

Function openwifi_rfkill_poll(struct ieee80211_hw *hw)

openwifi_rfkill_poll: The function of openwifi_rfkill_poll is to check and update the state of the wireless radio switch based on the current configuration.

parameters: The parameters of this Function. · hw: A pointer to a struct ieee80211_hw that contains hardware-specific information.

Code Description: The openwifi_rfkill_poll function is designed to monitor the state of the wireless radio switch associated with the OpenWiFi device. It begins by declaring a boolean variable enabled and retrieves the private data structure priv from the hardware structure hw. The function then calls openwifi_is_radio_enabled(priv) to determine if the radio is currently enabled.

If the state of the radio (stored in enabled) differs from the previous state stored in priv->rfkill_off, the function updates priv->rfkill_off to reflect the new state. A warning message is printed to the kernel log indicating the current state of the wireless radio switch. The function then calls wiphy_rfkill_set_hw_state(hw->wiphy, !enabled) to update the hardware state of the wireless interface, effectively enabling or disabling the radio based on the value of enabled.

This function is crucial for ensuring that the wireless radio operates according to the user's settings and reflects any changes in the radio's state accurately.

Note: It is important to ensure that the hw parameter is correctly initialized and points to a valid ieee80211_hw structure before calling this function. Additionally, the function should be called periodically or in response to specific events to maintain an accurate representation of the radio state.

graph TD
    A[Start openwifi_rfkill_poll function] --> B[Get private data from hw]
    B --> C[Check if radio is enabled]
    C --> D{Is radio enabled?}
    D -- Yes --> E[Update rfkill_off to enabled]
    E --> F[Log warning about radio state]
    F --> G[Set hardware state to enabled]
    D -- No --> H[Check if rfkill_off needs update]
    H --> I{Is rfkill_off different from enabled?}
    I -- Yes --> J[Update rfkill_off to enabled]
    J --> K[Log warning about radio state]
    K --> L[Set hardware state to enabled]
    I -- No --> M[End function]
    G --> M
    L --> M

Function openwifi_rfkill_exit(struct ieee80211_hw *hw)

openwifi_rfkill_exit: The function of openwifi_rfkill_exit is to stop the polling of the RF kill switch for the specified hardware.

parameters: The parameters of this Function. · hw: A pointer to a struct ieee80211_hw, which represents the wireless hardware.

Code Description: The openwifi_rfkill_exit function is designed to handle the cleanup process related to the RF kill switch functionality in a wireless device. When invoked, it first logs a message to the kernel log using the printk function, indicating that the openwifi_rfkill_exit function has been called. The message includes the value of the sdr_compatible_str variable, which likely contains a string that identifies the SDR (Software Defined Radio) compatibility status or version.

Following the logging operation, the function calls wiphy_rfkill_stop_polling, passing the wiphy member of the ieee80211_hw structure. This call effectively stops the polling mechanism that checks the status of the RF kill switch associated with the wireless hardware. The wiphy structure represents the wireless physical layer and is crucial for managing various aspects of wireless communication, including RF kill functionality.

This function is typically used during the shutdown or exit sequence of a wireless driver to ensure that any ongoing polling related to the RF kill switch is halted, thereby preventing unnecessary resource usage and potential conflicts.

Note: It is important to ensure that this function is called during the appropriate lifecycle events of the driver to maintain proper resource management and to avoid any potential issues related to the RF kill switch polling.

graph TD
    A[Start openwifi_rfkill_exit function] --> B[Log message with sdr_compatible_str]
    B --> C[Stop polling for rfkill on wiphy]
    C --> D[End openwifi_rfkill_exit function]

Function rssi_dbm_to_rssi_half_db(int rssi_dbm, int rssi_correction)

rssi_dbm_to_rssi_half_db: The function of rssi_dbm_to_rssi_half_db is to convert a received signal strength indicator (RSSI) value in dBm to a half dB representation, applying a correction factor.

parameters: The parameters of this Function. · parameter1: int rssi_dbm - This parameter represents the RSSI value in dBm, which is a logarithmic measure of the power level of the received signal. · parameter2: int rssi_correction - This parameter is a correction factor that is added to the RSSI value to account for any discrepancies or adjustments needed in the measurement.

Code Description: The rssi_dbm_to_rssi_half_db function takes two integer inputs: rssi_dbm and rssi_correction. It computes the output by first adding the rssi_correction value to the rssi_dbm value. The sum is then left-shifted by one bit (which is equivalent to multiplying the result by 2). This operation effectively converts the RSSI value from dBm to a half dB scale, which can be useful in various signal processing applications where finer granularity is required. The inline nature of this function suggests that it is intended for performance optimization, allowing the compiler to insert the function's code directly at the point of call, thereby reducing the overhead of a function call.

Note: It is important to ensure that the rssi_correction value is appropriate for the specific context in which the function is used, as an incorrect correction factor may lead to inaccurate results. Additionally, users should be aware of the data type limitations of the integer parameters, as extreme values could lead to overflow or underflow conditions.

Output Example: For example, if rssi_dbm is -70 and rssi_correction is 5, the function would compute the result as follows: (-70 + 5) << 1 = (-65) << 1 = -130. Thus, the function would return -130 as the half dB representation of the input RSSI value.

graph TD
    A[Start] --> B[Receive input rssi_dbm]
    B --> C[Receive input rssi_correction]
    C --> D[Calculate result using formula]
    D --> E[Return result]
    E --> F[End]

Function rssi_correction_lookup_table(u32 freq_MHz)

rssi_correction_lookup_table: The function of rssi_correction_lookup_table is to determine the RSSI (Received Signal Strength Indicator) correction value based on the provided frequency in MHz.

parameters: The parameters of this Function. · freq_MHz: A 32-bit unsigned integer representing the frequency in megahertz for which the RSSI correction value is to be determined.

Code Description: The rssi_correction_lookup_table function takes a single parameter, freq_MHz, which indicates the frequency in megahertz. The function evaluates this frequency against predefined ranges to assign an appropriate RSSI correction value.

  • If the frequency is less than 2412 MHz, the function assigns a correction value of 153.
  • For frequencies between 2412 MHz and 2484 MHz (inclusive), the correction value remains 153.
  • Frequencies from 2485 MHz up to but not including 5160 MHz also receive a correction value of 153.
  • For frequencies between 5160 MHz and 5240 MHz (inclusive), the correction value is adjusted to 145.
  • Frequencies from 5241 MHz to 5320 MHz (inclusive) continue to receive a correction value of 145.
  • Any frequency above 5320 MHz is also assigned a correction value of 145.

The function concludes by returning the determined rssi_correction value, which can be used in further processing related to signal strength adjustments.

Note: It is important to ensure that the input frequency is within a valid range to avoid unexpected behavior. The function does not handle frequencies below 0 MHz or above 6000 MHz, which may lead to incorrect correction values.

Output Example: For an input of freq_MHz = 2400, the function will return 153. For an input of freq_MHz = 5200, the function will return 145.

graph TD
    A[Start] --> B[Receive frequency in MHz]
    B --> C{Check frequency range}
    C -->|freq_MHz < 2412| D[Set rssi_correction to 153]
    C -->|freq_MHz <= 2484| D
    C -->|freq_MHz < 5160| D
    C -->|freq_MHz <= 5240| E[Set rssi_correction to 145]
    C -->|freq_MHz <= 5320| E
    C -->|else| E
    D --> F[Return rssi_correction]
    E --> F
    F --> G[End]

Function ad9361_tx_calibration(struct openwifi_priv *priv, u32 actual_tx_lo)

ad9361_tx_calibration: The function of ad9361_tx_calibration is to perform transmission quadrature calibration for the AD9361 device.

parameters: The parameters of this Function. · priv: A pointer to the structure openwifi_priv, which contains the private data for the OpenWiFi device. · actual_tx_lo: An unsigned 32-bit integer representing the actual transmit local oscillator frequency in MHz.

Code Description: The ad9361_tx_calibration function is designed to execute a calibration routine for the transmission quadrature of the AD9361 device. The function begins by storing the provided actual transmit local oscillator frequency into the last_tx_quad_cal_lo member of the priv structure.

It then reads the current state of the FPGA SPI disable register using the xpu_api interface, which is crucial for ensuring that the SPI communication is properly managed during the calibration process. The function disables the FPGA SPI module by writing a value of 1 to the SPI disable register, preventing any unintended interactions during the calibration.

Next, the function calls ad9361_do_calib_run, passing in the AD9361 PHY structure, the calibration type (TX_QUAD_CAL), and the last known transmit quadrature calibration phase. This function is responsible for executing the actual calibration logic.

After the calibration is completed, the original state of the SPI disable register is restored by writing the previously backed-up value back to the register.

Finally, the function logs a message indicating the completion of the calibration process, including the actual transmit local oscillator frequency. The duration of the calibration is noted as "unknown" since the timing code has been commented out.

Note: It is important to ensure that the SPI module is properly managed before and after the calibration process to avoid any communication issues with the AD9361 device. Additionally, the actual duration of the calibration process is not measured in this implementation, which may be relevant for performance analysis.

graph TD
    A[Start ad9361_tx_calibration] --> B[Set last_tx_quad_cal_lo to actual_tx_lo]
    B --> C[Read current FPGA SPI disable state]
    C --> D[Disable FPGA SPI module]
    D --> E[Run TX_QUAD_CAL calibration]
    E --> F[Restore original SPI disable state]
    F --> G[Log calibration duration]
    G --> H[End ad9361_tx_calibration]

Function openwifi_rf_rx_update_after_tuning(struct openwifi_priv *priv, u32 actual_rx_lo)

openwifi_rf_rx_update_after_tuning: The function of openwifi_rf_rx_update_after_tuning is to update the receiver settings after tuning to a specific frequency.

parameters: The parameters of this Function. · parameter1: struct openwifi_priv *priv - A pointer to the private structure containing the state and configuration of the OpenWiFi device. · parameter2: u32 actual_rx_lo - The actual receive local oscillator frequency in MHz.

Code Description: The openwifi_rf_rx_update_after_tuning function performs several critical tasks to configure the receiver after it has been tuned to a specific frequency.

Initially, it retrieves the RSSI (Received Signal Strength Indicator) correction value from a lookup table based on the actual receive local oscillator frequency (actual_rx_lo). This correction value is stored in the priv structure's rssi_correction member.

Next, the function calculates the appropriate LBT (Listen Before Talk) thresholds. It computes an automatic LBT threshold based on a predefined RSSI value of -62 dBm and the previously obtained RSSI correction. It also calculates a static LBT threshold using a value from the drv_xpu_reg_val array, which is adjusted by the RSSI correction. The FPGA LBT threshold is then determined; if the static LBT threshold is zero, it defaults to the automatic LBT threshold. This value is written to the FPGA register using the XPU_REG_LBT_TH_write function.

The function also sets a receiver RSSI threshold, which is crucial for determining the minimum signal strength that the receiver will respond to. This threshold is calculated based on the value from the drv_rx_reg_val array, with a default value defined in hw_def.h if the register value is zero. The calculated receiver RSSI threshold is then written to the OPENOFDM_RX_REG_POWER_THRES register.

Following this, the function checks the actual receive local oscillator frequency to determine the appropriate band (2.4 GHz or 5.8 GHz). If the current band does not match the determined band based on the frequency, it updates the band in the priv structure and writes the new band and channel information to the XPU_REG_BAND_CHANNEL register.

Finally, the function logs the tuning results, including the actual frequency, RSSI correction, FPGA LBT threshold, automatic and static LBT thresholds, and the receiver threshold values, providing a comprehensive overview of the tuning process.

Note: It is important to ensure that the priv structure is properly initialized before calling this function, as it relies on various fields within the structure to configure the receiver correctly. Additionally, the function assumes that the necessary APIs for writing to the registers are available and functioning correctly.

graph TD
    A[Start openwifi_rf_rx_update_after_tuning] --> B[Get rssi correction value from lookup table]
    B --> C[Set auto lbt threshold]
    C --> D[Set static lbt threshold]
    D --> E[Determine fpga lbt threshold]
    E --> F[Write fpga lbt threshold to register]
    F --> G[Set receiver rssi_half_db threshold]
    G --> H[Check actual_rx_lo value]
    H -->|actual_rx_lo < 2500| I[Check if band is not 2.4GHz]
    H -->|actual_rx_lo >= 2500| J[Check if band is not 5.8GHz]
    I -->|Band is not 2.4GHz| K[Set band to 2.4GHz]
    K --> L[Write band and channel to register]
    I -->|Band is 2.4GHz| M[No change in band]
    J -->|Band is not 5.8GHz| N[Set band to 5.8GHz]
    N --> O[Write band and channel to register]
    J -->|Band is 5.8GHz| P[No change in band]
    L --> Q[Log tuning information]
    M --> Q
    P --> Q
    O --> Q
    Q --> R[End openwifi_rf_rx_update_after_tuning]

Function ad9361_rf_set_channel(struct ieee80211_hw *dev,

              struct ieee80211_conf *conf)

ad9361_rf_set_channel: The function of ad9361_rf_set_channel is to configure the radio frequency (RF) settings for both transmission and reception based on the current channel configuration.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the hardware structure that contains device-specific information. · parameter2: struct ieee80211_conf conf - A pointer to the configuration structure that includes channel definition and other settings.

Code Description: The ad9361_rf_set_channel function is responsible for adjusting the local oscillator (LO) frequencies for both the transmitter and receiver based on the current channel configuration. It begins by retrieving the private data associated with the device from the ieee80211_hw structure. The function calculates the actual receive LO frequency by subtracting a frequency offset from the center frequency of the current channel.

A change flag is set to true if the calculated receive LO frequency differs from the previously stored value. If this flag is true and both the transmitter and receiver frequency registers are set to zero, the function proceeds to calculate the actual transmit LO frequency and the difference between the last known transmit frequency and the newly calculated frequency.

The function then performs tuning for the transmit LO by setting the clock rate for the TX_RFPLL to the calculated transmit LO frequency. Similarly, it tunes the receive LO by setting the clock rate for the RX_RFPLL. If the difference in the transmit LO frequency exceeds 100 MHz, it triggers a calibration routine for the transmitter to ensure optimal performance. Finally, it updates the receiver settings after tuning and logs a message indicating the successful completion of the channel setting.

Note: It is important to ensure that the frequency offsets and previous values are correctly initialized before calling this function to avoid unintended behavior. Additionally, the function assumes that the necessary clock structures are properly set up and accessible through the private data structure.

graph TD
    A[Start] --> B[Get device and configuration]
    B --> C[Calculate actual_rx_lo]
    C --> D[Check if change_flag is true]
    D -->|Yes| E[Check if RF register values are zero]
    D -->|No| F[End]
    E -->|Yes| G[Calculate actual_tx_lo]
    G --> H[Calculate diff_tx_lo]
    H --> I[Tune Tx Lo]
    I --> J[Tune Rx Lo]
    J --> K[Check if diff_tx_lo > 100]
    K -->|Yes| L[Call Tx Quadrature calibration]
    K -->|No| M[Continue]
    L --> N[Update Rx after tuning]
    M --> N
    N --> O[Log completion message]
    O --> F

Function reverse16(u16 d)

reverse16: The function of reverse16 is to reverse the byte order of a 16-bit unsigned integer.

parameters: The parameters of this Function. · parameter1: u16 d - This is a 16-bit unsigned integer whose byte order is to be reversed.

Code Description: The reverse16 function takes a 16-bit unsigned integer as input and reverses its byte order. It utilizes a union named u16_byte2, which allows for accessing the individual bytes of the 16-bit integer. The function begins by assigning the input value 'd' to the first member of the union, tmp0.a. The union tmp0 is then used to access the two bytes of the integer: tmp0.c[0] corresponds to the least significant byte (LSB), and tmp0.c[1] corresponds to the most significant byte (MSB).

Next, the function assigns the LSB of tmp0 to the MSB of another union, tmp1.c[1], and the MSB of tmp0 to the LSB of tmp1.c[0]. This effectively swaps the two bytes. Finally, the function returns the value of tmp1.a, which now contains the original integer with its byte order reversed.

Note: It is important to ensure that the input value is indeed a 16-bit unsigned integer to avoid unexpected behavior. The function assumes that the union u16_byte2 is properly defined to allow access to the bytes of the 16-bit integer.

Output Example: If the input value is 0x1234, the function will return 0x3412, effectively reversing the byte order.

graph TD
    A[Start reverse16 function] --> B[Create union u16_byte2 tmp0]
    B --> C[Assign d to tmp0.a]
    C --> D[Create union u16_byte2 tmp1]
    D --> E[Assign tmp0.c[1] to tmp1.c[0]]
    E --> F[Assign tmp0.c[0] to tmp1.c[1]]
    F --> G[Return tmp1.a]
    G --> H[End reverse16 function]

Function reverse32(u32 d)

reverse32: The function of reverse32 is to reverse the byte order of a 32-bit unsigned integer.

parameters: The parameters of this Function. · parameter1: u32 d - This is the 32-bit unsigned integer input whose byte order is to be reversed.

Code Description: The reverse32 function takes a 32-bit unsigned integer as input and reverses its byte order. It utilizes a union named u32_byte4, which allows access to the same data in different formats. The union is structured to contain an array of four bytes (c[0] to c[3]) and a 32-bit unsigned integer (a).

  1. The input integer d is assigned to the union member tmp0.a, which allows the individual bytes of d to be accessed through tmp0.c.
  2. The function then assigns the bytes of tmp0.c to tmp1.c in reverse order:
  3. tmp1.c[0] is assigned the value of tmp0.c[3] (the most significant byte).
  4. tmp1.c[1] is assigned the value of tmp0.c[2].
  5. tmp1.c[2] is assigned the value of tmp0.c[1].
  6. tmp1.c[3] is assigned the value of tmp0.c[0] (the least significant byte).
  7. Finally, the function returns tmp1.a, which now contains the original integer d with its byte order reversed.

This function is particularly useful in scenarios where data needs to be interpreted in a different byte order, such as in network programming or when dealing with different architectures that may have different endianness.

Note: It is important to ensure that the input to this function is a valid 32-bit unsigned integer. The function does not perform any error checking or validation on the input value.

Output Example: If the input value is 0x12345678, the output of the function will be 0x78563412, which represents the reversed byte order of the original input.

graph TD
    A[Start reverse32 function] --> B[Declare union u32_byte4 tmp0]
    B --> C[Declare union u32_byte4 tmp1]
    C --> D[Assign d to tmp0.a]
    D --> E[Assign tmp0.c[3] to tmp1.c[0]]
    E --> F[Assign tmp0.c[2] to tmp1.c[1]]
    F --> G[Assign tmp0.c[1] to tmp1.c[2]]
    G --> H[Assign tmp0.c[0] to tmp1.c[3]]
    H --> I[Return tmp1.a]
    I --> J[End reverse32 function]

Function openwifi_init_tx_ring(struct openwifi_priv *priv, int ring_idx)

openwifi_init_tx_ring: The function of openwifi_init_tx_ring is to initialize a transmission ring for the OpenWiFi driver.

parameters: The parameters of this Function. · parameter1: struct openwifi_priv *priv - A pointer to the private data structure for the OpenWiFi device, which contains the transmission ring information. · parameter2: int ring_idx - An index indicating which transmission ring to initialize.

Code Description: The openwifi_init_tx_ring function is responsible for setting up a transmission ring in the OpenWiFi driver. It begins by obtaining a pointer to the specific transmission ring structure based on the provided index (ring_idx) from the private data structure (priv).

The function initializes several fields of the transmission ring: - It sets the stop_flag to -1, indicating that the ring is not currently stopped. - It initializes both the write index (bd_wr_idx) and the read index (bd_rd_idx) to 0, which are used to manage the buffer descriptors in the ring.

Next, the function allocates memory for the buffer descriptors (bds) of the transmission ring using kmalloc. The size allocated is determined by the number of transmission buffer descriptors (NUM_TX_BD) multiplied by the size of the openwifi_buffer_descriptor structure. If the memory allocation fails (i.e., if bds is NULL), a warning message is printed to the kernel log, and the function returns an error code (-ENOMEM) indicating that memory could not be allocated.

If memory allocation is successful, the function enters a loop that iterates over each buffer descriptor in the transmission ring. For each buffer descriptor, it initializes the following fields: - skb_linked is set to NULL, indicating that there is no socket buffer linked at this point. - dma_mapping_addr is set to 0, as the DMA mapping will be performed later when the socket buffer is received from the upper layer. - seq_no is initialized to 0xffff, which serves as an invalid value for sequence numbers. - prio is set to 0xff, representing an invalid priority value. - len_mpdu is also set to 0, indicating an invalid length for the MPDU (MAC Protocol Data Unit).

Finally, the function returns 0, indicating successful initialization of the transmission ring.

Note: It is important to ensure that the memory allocated for the buffer descriptors is properly freed when it is no longer needed to prevent memory leaks. Additionally, the function should be called with a valid pointer to the openwifi_priv structure and a valid ring index to avoid undefined behavior.

Output Example: If the function is called successfully, it will return 0. If memory allocation fails, it will return -ENOMEM.

graph TD
    A[Start openwifi_init_tx_ring] --> B[Initialize ring structure]
    B --> C[Set stop_flag to -1]
    C --> D[Set bd_wr_idx to 0]
    D --> E[Set bd_rd_idx to 0]
    E --> F[Allocate memory for buffer descriptors]
    F -->|Memory allocation successful| G[Initialize buffer descriptors]
    F -->|Memory allocation failed| H[Log warning and return error]
    G --> I[For each buffer descriptor]
    I --> J[Set skb_linked to NULL]
    J --> K[Set dma_mapping_addr to 0]
    K --> L[Set seq_no to invalid value]
    L --> M[Set prio to invalid value]
    M --> N[Set len_mpdu to invalid value]
    N --> I
    I --> O[Return success]
    H --> P[Return error]
    O --> Q[End openwifi_init_tx_ring]
    P --> Q

Function openwifi_free_tx_ring(struct openwifi_priv *priv, int ring_idx)

openwifi_free_tx_ring: The function of openwifi_free_tx_ring is to free the transmission ring buffer resources associated with a specified index in the OpenWiFi driver.

parameters: The parameters of this Function. · parameter1: struct openwifi_priv *priv - A pointer to the private data structure that holds the state of the OpenWiFi device. · parameter2: int ring_idx - An integer representing the index of the transmission ring to be freed.

Code Description: The openwifi_free_tx_ring function is responsible for cleaning up and releasing resources associated with a specific transmission ring in the OpenWiFi driver. It takes two parameters: a pointer to the private data structure (priv) and an integer (ring_idx) that indicates which transmission ring to free.

The function begins by obtaining a reference to the transmission ring structure using the provided index. It then sets the stop_flag of the ring to -1, indicating that the ring is no longer active. The write and read indices (bd_wr_idx and bd_rd_idx) are reset to 0, preparing the ring for deallocation.

A loop iterates over each buffer descriptor (BD) in the transmission ring. For each buffer descriptor, the function checks if the skb_linked and dma_mapping_addr fields are both zero, in which case it continues to the next iteration. If the dma_mapping_addr is not zero, it calls dma_unmap_single to unmap the DMA memory associated with the buffer descriptor, ensuring that the memory is properly released back to the system.

The function also includes a warning log that triggers if there is an inconsistency between the skb_linked and dma_mapping_addr fields, which could indicate a potential issue in the buffer descriptor management.

After processing each buffer descriptor, the function sets the skb_linked and dma_mapping_addr fields to NULL and 0, respectively, effectively invalidating the buffer descriptor. It also resets other fields such as seq_no, prio, and len_mpdu to invalid values.

Finally, if the bds array (buffer descriptors) is not NULL, the function calls kfree to release the memory allocated for the buffer descriptors, and sets the bds pointer to NULL to prevent dangling references.

Note: It is important to ensure that this function is called when the transmission ring is no longer needed to prevent memory leaks. Additionally, care should be taken to handle any potential warnings logged during the execution of this function, as they may indicate underlying issues with buffer descriptor management.

graph TD
    A[Start openwifi_free_tx_ring] --> B[Get tx_ring using ring_idx]
    B --> C[Set stop_flag to -1]
    C --> D[Initialize bd_wr_idx to 0]
    D --> E[Initialize bd_rd_idx to 0]
    E --> F[Loop through NUM_TX_BD]
    F --> G{Check if skb_linked and dma_mapping_addr are both 0}
    G -- Yes --> F
    G -- No --> H{Check if dma_mapping_addr is not 0}
    H -- Yes --> I[Call dma_unmap_single]
    H -- No --> J{Check if skb_linked is not 0}
    J -- Yes --> K[Log warning message]
    J -- No --> L[Skip to next iteration]
    I --> M[Set skb_linked to NULL]
    I --> N[Set dma_mapping_addr to 0]
    I --> O[Set seq_no to invalid value]
    I --> P[Set prio to invalid value]
    I --> Q[Set len_mpdu to invalid value]
    K --> M
    M --> F
    F --> R{Check if bds is not NULL}
    R -- Yes --> S[Call kfree on bds]
    R -- No --> T[End openwifi_free_tx_ring]
    S --> T

Function openwifi_init_rx_ring(struct openwifi_priv *priv)

openwifi_init_rx_ring: The function of openwifi_init_rx_ring is to initialize the receive ring buffer for OpenWiFi by allocating memory and setting up initial values.

parameters: The parameters of this Function. · priv: A pointer to the structure openwifi_priv, which contains the necessary context and configuration for the OpenWiFi device.

Code Description: The openwifi_init_rx_ring function is responsible for setting up the receive buffer for incoming packets in the OpenWiFi driver. It begins by attempting to allocate a coherent DMA buffer using the dma_alloc_coherent function. This buffer is essential for receiving data from the network interface. The size of the buffer is determined by the constants RX_BD_BUF_SIZE and NUM_RX_BD, which represent the size of each buffer descriptor and the total number of descriptors, respectively.

If the allocation fails (i.e., if priv->rx_cyclic_buf is NULL), the function logs a warning message indicating the failure and attempts to free any previously allocated memory using dma_free_coherent. The function then returns -1 to signal the error.

If the allocation is successful, the function proceeds to initialize the buffer. It iterates over each buffer descriptor, setting the tsft_low and tsft_high values to zero. This is done by accessing the appropriate offset within each buffer descriptor, which is calculated based on the index and the size of the buffer. Setting these values to zero indicates that there are no packets currently present in the buffer.

Finally, the function logs a message indicating the successful initialization of the receive buffer, including the number of buffer descriptors and their size, before returning 0 to indicate success.

Note: It is important to ensure that the memory allocated for the receive buffer is properly freed when it is no longer needed to prevent memory leaks. Additionally, the function should be called in the appropriate context where the priv structure is correctly initialized.

Output Example: A successful execution of the function would return 0, indicating that the receive ring buffer has been initialized correctly. In case of failure during memory allocation, it would return -1, and a warning message would be printed to the kernel log.

graph TD
    A[Start openwifi_init_rx_ring] --> B[Allocate coherent DMA memory]
    B --> C{Check allocation success}
    C -->|Yes| D[Initialize tsft_low and tsft_high to 0]
    C -->|No| E[Log warning message]
    E --> F[Free allocated DMA memory]
    F --> G[Return error -1]
    D --> H[Log initialization success message]
    D --> I[Return success 0]
    H --> I

Function openwifi_free_rx_ring(struct openwifi_priv *priv)

openwifi_free_rx_ring: The function of openwifi_free_rx_ring is to free the resources allocated for the receive cyclic buffer in the OpenWiFi driver.

parameters: The parameters of this Function. · priv: A pointer to the structure openwifi_priv, which contains the context and state information for the OpenWiFi driver.

Code Description: The openwifi_free_rx_ring function is designed to release the memory resources associated with the receive cyclic buffer used in the OpenWiFi driver. It first checks if the rx_cyclic_buf member of the openwifi_priv structure is not null, indicating that memory has been allocated for the receive buffer. If this condition is met, the function calls dma_free_coherent to free the allocated memory. The dma_free_coherent function takes four arguments: the device associated with the receive channel, the size of the buffer to be freed (calculated as RX_BD_BUF_SIZE multiplied by NUM_RX_BD), the pointer to the cyclic buffer, and the DMA mapping address associated with that buffer.

After successfully freeing the memory, the function resets the rx_cyclic_buf and rx_cyclic_buf_dma_mapping_addr members of the openwifi_priv structure to zero, effectively cleaning up the state of the driver and preventing any dangling pointers or memory leaks.

Note: It is important to ensure that openwifi_free_rx_ring is called only when the receive cyclic buffer has been allocated and is no longer needed. Calling this function without prior allocation may lead to undefined behavior. Additionally, proper synchronization mechanisms should be in place to avoid concurrent access to the rx_cyclic_buf during the free operation.

graph TD
    A[Start openwifi_free_rx_ring function] --> B[Check if rx_cyclic_buf is not null]
    B -->|Yes| C[Call dma_free_coherent with parameters]
    C --> D[Set rx_cyclic_buf_dma_mapping_addr to 0]
    D --> E[Set rx_cyclic_buf to 0]
    B -->|No| D
    E --> F[End openwifi_free_rx_ring function]

Function rx_dma_setup(struct ieee80211_hw *dev)

rx_dma_setup: The function of rx_dma_setup is to configure the DMA for receiving data in a cyclic manner.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device.

Code Description: The rx_dma_setup function initializes the DMA (Direct Memory Access) for receiving data packets. It begins by retrieving the private data structure associated with the hardware device through the dev parameter. This private structure contains information about the DMA channel used for receiving data.

The function then prepares the DMA for cyclic data reception by calling the device_prep_dma_cyclic method on the DMA device associated with the receiving channel. This method is provided with several parameters: the DMA channel, the address of the cyclic buffer for receiving data, the size of the buffer multiplied by the number of receive buffers, the size of each buffer, and flags indicating the direction of data transfer (from device to memory) and control options (acknowledgment and interrupt preparation).

If the preparation of the DMA fails (indicated by a null return value), the function calls openwifi_free_rx_ring to clean up any allocated resources and logs a warning message indicating the failure. The function then returns -1 to signal an error.

If the DMA preparation is successful, the callback and callback_param fields of the prepared DMA descriptor are set to zero, indicating that no callback function is registered for completion notifications.

Next, the function submits the DMA operation using the tx_submit method of the prepared descriptor, storing the result in the rx_cookie variable. If this submission encounters an error, a warning message is logged, and the function returns -1.

Finally, the function issues a command to the DMA engine to start processing the pending operations on the receive channel by calling dma_async_issue_pending. If all operations complete successfully, the function returns 0, indicating successful setup of the DMA for receiving data.

Note: It is important to ensure that the DMA channel and buffer addresses are correctly configured before calling this function to avoid potential errors. Additionally, proper error handling should be implemented to manage any failures during the DMA setup process.

Output Example: A successful execution of the function would return 0, indicating that the DMA has been set up correctly for receiving data. In case of an error, the function would return -1, and a warning message would be printed to the log.

graph TD
    A[Start rx_dma_setup] --> B[Get priv from dev]
    B --> C[Get rx_dev from priv]
    C --> D[Prepare DMA cyclic]
    D --> E{Check if rxd is NULL}
    E -- Yes --> F[Free RX ring]
    F --> G[Log warning about device_prep_dma_cyclic]
    G --> H[Return -1]
    E -- No --> I[Set callback and callback_param to 0]
    I --> J[Submit DMA request]
    J --> K{Check for dma_submit_error}
    K -- Yes --> L[Log warning about dma_submit_error]
    L --> H
    K -- No --> M[Issue pending for rx_chan]
    M --> N[Return 0]
    H --> O[End rx_dma_setup]
    N --> O

Function rssi_half_db_to_rssi_dbm(int rssi_half_db, int rssi_correction)

rssi_half_db_to_rssi_dbm: The function of rssi_half_db_to_rssi_dbm is to convert a received signal strength indicator (RSSI) value represented in half decibels to a value in decibels milliwatts (dBm), applying a correction factor.

parameters: The parameters of this Function. · parameter1: int rssi_half_db - The RSSI value in half decibels, which is the input value that needs to be converted. · parameter2: int rssi_correction - A correction factor in decibels that is subtracted from the converted RSSI value to adjust for calibration or environmental factors.

Code Description: The rssi_half_db_to_rssi_dbm function performs the following operations: 1. It takes an integer input rssi_half_db, which represents the RSSI value in half decibels. This value is right-shifted by one bit (rssi_half_db >> 1), effectively dividing it by two, to convert it to decibels (dB). The result is stored in the variable rssi_db. 2. The function then applies the correction factor by subtracting rssi_correction from rssi_db, resulting in the variable rssi_dbm, which represents the RSSI value in dBm. 3. To ensure that the output does not exceed a minimum threshold, the function checks if rssi_dbm is less than -128. If it is, rssi_dbm is set to -128, thus enforcing a lower limit on the output value. 4. Finally, the function returns the calculated rssi_dbm value.

This function is particularly useful in wireless communication systems where RSSI values need to be interpreted and adjusted for accurate signal strength representation.

Note: It is important to ensure that the rssi_half_db input is a valid integer value representing the RSSI in half decibels, and that the rssi_correction is appropriately calibrated to avoid inaccurate readings.

Output Example: If the input values are rssi_half_db = 30 and rssi_correction = 5, the function would perform the following calculations: - rssi_db = 30 >> 1 = 15 - rssi_dbm = 15 - 5 = 10 Thus, the function would return a value of 10 dBm.

graph TD
    A[Start] --> B[Receive rssi_half_db and rssi_correction]
    B --> C[Calculate rssi_db by right shifting rssi_half_db by 1]
    C --> D[Calculate rssi_dbm by subtracting rssi_correction from rssi_db]
    D --> E[Check if rssi_dbm is less than -128]
    E -->|Yes| F[Set rssi_dbm to -128]
    E -->|No| G[Keep rssi_dbm as is]
    F --> H[Return rssi_dbm]
    G --> H
    H --> I[End]

Function openwifi_tx_interrupt(int irq, void *dev_id)

openwifi_tx_interrupt: The function of openwifi_tx_interrupt is to handle transmission interrupts for the OpenWiFi driver, processing packets that have been sent by the FPGA.

parameters: The parameters of this function. · parameter1: int irq - The interrupt request number associated with the transmission interrupt. · parameter2: void *dev_id - A pointer to the device structure, which contains device-specific information.

Code Description: The openwifi_tx_interrupt function is designed to manage the transmission of packets in the OpenWiFi driver. It begins by acquiring a lock on the private structure associated with the device to ensure thread safety during the interrupt handling process. The function enters a loop to continuously check for packets that have been sent by the FPGA until no more packets are available.

Within the loop, the function reads several registers to gather information about the transmission status, including the number of retries, the priority of the packet, and the queue index. It also checks if there is room in the FPGA's queue to process new packets. If the queue is full, it sets a flag indicating that the queue cannot accept more packets.

The function then iterates through the software transmit rings to determine if any queues need to be woken up based on the current transmission status. If a queue has room, it updates the stop flag and increments the statistics related to the number of wake-ups.

For each packet that has been sent, the function retrieves the corresponding socket buffer (skb) and performs necessary operations such as unmapping the DMA address and clearing the transmission status. It checks if the packet requires acknowledgment and updates the statistics accordingly. The function also handles both aggregation and normal packets, updating the transmission status based on whether the transmission was successful or failed.

Finally, the function cleans up the ring buffer entries by resetting their values to indicate that they are no longer in use. After processing all available packets, the function releases the lock and returns IRQ_HANDLED to indicate that the interrupt has been successfully processed.

Note: It is important to ensure that the function is called in an interrupt context and that the device is properly initialized before invoking this function. Additionally, the statistics collection feature can be enabled or disabled based on the driver's configuration.

Output Example: A possible appearance of the code's return value could be IRQ_HANDLED, indicating that the interrupt was successfully handled and no further action is required.

graph TD
    A[Start openwifi_tx_interrupt] --> B[Acquire lock]
    B --> C[Loop through packets]
    C --> D[Read TX_INTF_REG_PKT_INFO1]
    D --> E[Check if reg_val1 is not all ones]
    E -->|Yes| F[Extract nof_retx, last_bd_rd_idx, prio, num_slot_random, cw]
    F --> G[Check cw value]
    G -->|cw > 10| H[Set cw to 10 and adjust num_slot_random]
    H --> I[Read TX_INTF_REG_PKT_INFO2]
    I --> J[Extract pkt_cnt, blk_ack_ssn]
    J --> K[Read DMA FIFO no room flag]
    K --> L[Read hardware queue length]
    L --> M[Check for stopped Linux priority queues]
    M --> N[Update fpga_queue_has_room based on conditions]
    N --> O[Wake up Linux queue if necessary]
    O --> P[Update statistics if enabled]
    P --> Q[Get the transmission ring for the queue]
    Q --> R[Loop through packets to process]
    R --> S[Update read index and get seq_no]
    S --> T[Check if seq_no is valid]
    T -->|Valid| U[Unmap DMA and clear status]
    U --> V[Check if using HT aggregation]
    V -->|Yes| W[Handle aggregation packet]
    W --> X[Update statistics for ACK needed packets]
    X --> Y[Handle normal packet]
    Y --> Z[Update statistics for ACK needed packets]
    Z --> AA[Check if transmission was successful]
    AA -->|Success| AB[Set ACK flag]
    AB --> AC[Update transmission status]
    AC --> AD[Reset ring buffer entry]
    AD --> AE[Increment loop count]
    AE --> C
    E -->|No| AF[Exit loop]
    AF --> AG[Check loop count for warnings]
    AG --> AH[Release lock]
    AH --> AI[Return IRQ_HANDLED]
    AI --> AJ[End openwifi_tx_interrupt]

Function gen_mpdu_crc(u8 *data_in, u32 num_bytes)

gen_mpdu_crc: The function of gen_mpdu_crc is to compute the CRC (Cyclic Redundancy Check) value for a given input data buffer.

parameters: The parameters of this Function. · parameter1: u8 *data_in - A pointer to the input data buffer that contains the bytes for which the CRC is to be calculated. · parameter2: u32 num_bytes - The number of bytes in the input data buffer that will be processed for CRC calculation.

Code Description: The gen_mpdu_crc function calculates the CRC value for a specified number of bytes in the input data buffer. It initializes a variable crc to zero, which will hold the computed CRC value. The function iterates through each byte of the input data, performing the following steps for each byte:

  1. It calculates an index idx by taking the lower nibble (4 bits) of the current CRC value and XORing it with the lower nibble of the current byte from the input data.
  2. The CRC value is then updated by right-shifting the current CRC value by 4 bits and XORing it with a pre-defined crc_table entry indexed by idx.
  3. The same process is repeated for the upper nibble of the current byte, where the upper nibble is obtained by right-shifting the byte by 4 bits.

This process continues for all bytes specified by num_bytes. Finally, the function returns the computed CRC value.

Note: It is important to ensure that the data_in pointer is valid and that num_bytes does not exceed the allocated size of the input buffer to avoid memory access violations. The crc_table must be defined and initialized prior to calling this function for accurate CRC calculations.

Output Example: For an input buffer containing the bytes {0x01, 0x02, 0x03, 0x04} and a num_bytes value of 4, the function might return a CRC value such as 0xA1B2C3D4, depending on the contents of the crc_table used in the calculations.

graph TD
    A[Start gen_mpdu_crc function] --> B[Initialize variables i, crc, idx]
    B --> C[For each byte in data_in from 0 to num_bytes - 1]
    C --> D[Calculate idx using crc and data_in[i]]
    D --> E[Update crc using crc_table with idx]
    E --> F[Calculate idx using crc and upper nibble of data_in[i]]
    F --> G[Update crc using crc_table with idx]
    G --> C
    C --> H[Return crc]
    H --> I[End gen_mpdu_crc function]

Function gen_mpdu_delim_crc(u16 m)

gen_mpdu_delim_crc: The function of gen_mpdu_delim_crc is to compute the CRC (Cyclic Redundancy Check) value for a given 16-bit input.

parameters: The parameters of this Function. · parameter1: u16 m - A 16-bit unsigned integer input for which the CRC is to be calculated.

Code Description: The gen_mpdu_delim_crc function calculates the CRC value for a 16-bit input using a specific algorithm. It initializes an array c of size 8 with all elements set to 1, which will be used to store intermediate CRC values during the computation. The function iterates 16 times, once for each bit of the input value m.

In each iteration, it computes a temporary variable temp which is the XOR of the most significant bit of the current CRC value (c[7]) and the current bit of the input m (extracted using bitwise operations). The CRC array c is then updated by shifting its values to the right and applying the XOR operation with temp to specific elements of the array.

After completing the iterations, the final CRC value is constructed by taking the negation of each element in the array c and combining them into a single byte. The resulting CRC value is returned as an 8-bit unsigned integer.

Note: It is important to ensure that the input value m is a valid 16-bit unsigned integer. The function assumes that the input is properly formatted and does not handle any error checking for invalid inputs.

Output Example: For an input value of 0xA5A5 (which is 42661 in decimal), the function might return a CRC value of 0x3C (which is 60 in decimal).

graph TD
    A[Start] --> B[Initialize variables i, temp, c, mpdu_delim_crc]
    B --> C[For i from 0 to 15]
    C --> D[Calculate temp as c[7] XOR (m right shift i AND 0x01)]
    D --> E[Shift c values]
    E --> F[Update c[2] as c[2] XOR temp]
    F --> G[Update c[1] as c[1] XOR temp]
    G --> H[Update c[0] as temp]
    H --> C
    C --> I[Calculate mpdu_delim_crc from c values]
    I --> J[Return mpdu_delim_crc]
    J --> K[End]

Function calc_n_ofdm(int num_octet, int n_dbps)

calc_n_ofdm: The function of calc_n_ofdm is to calculate the number of OFDM symbols required based on the number of octets and the number of data bits per symbol.

parameters: The parameters of this Function. · parameter1: int num_octet - This parameter represents the number of octets to be processed. Each octet consists of 8 bits. · parameter2: int n_dbps - This parameter indicates the number of data bits per OFDM symbol.

Code Description: The calc_n_ofdm function computes the total number of OFDM symbols needed to transmit a given number of octets. The function begins by calculating the total number of bits from the input number of octets. This is done using the formula num_bit = 22 + num_octet * 8, where 22 is a constant that may represent a fixed overhead in bits. The total number of bits is then divided by the number of data bits per symbol (n_dbps) to determine the number of OFDM symbols required. The calculation (num_bit / n_dbps) gives the quotient, which represents the complete symbols that can be formed, while ((num_bit % n_dbps) != 0) checks if there is any remainder. If there is a remainder, it indicates that an additional OFDM symbol is needed to accommodate the leftover bits. The function returns the total number of OFDM symbols as an integer.

Note: It is important to ensure that the parameters passed to the function are valid. Specifically, n_dbps should not be zero, as this would lead to a division by zero error. Additionally, num_octet should be a non-negative integer to avoid negative bit calculations.

Output Example: For example, if the function is called with calc_n_ofdm(5, 26), it calculates the total number of bits as 22 + 5 * 8 = 62. Then, it computes the number of OFDM symbols as (62 / 26) + ((62 % 26) != 0), resulting in 2 + 1, which returns 3. Thus, the function would output 3, indicating that three OFDM symbols are required.

graph TD
    A[Start] --> B[Receive num_octet and n_dbps]
    B --> C[Calculate num_bit as 22 plus num_octet times 8]
    C --> D[Calculate num_ofdm_sym as num_bit divided by n_dbps]
    D --> E[Check if num_bit modulo n_dbps is not equal to 0]
    E -->|Yes| F[Add 1 to num_ofdm_sym]
    E -->|No| G[Proceed without addition]
    F --> H[Return num_ofdm_sym]
    G --> H
    H --> I[End]

Function gen_ht_duration_id(__le16 frame_control, __le16 aid, u8 qos_hdr, bool use_ht_aggr, u16 rate_hw_value, u16 sifs)

gen_ht_duration_id: The function of gen_ht_duration_id is to calculate the duration field for high-throughput (HT) Quality of Service (QoS) data frames in wireless communication.

parameters: The parameters of this Function. · frame_control: A 16-bit value representing the frame control field, which indicates the type and subtype of the frame. · aid: A 16-bit value representing the Association ID, used to identify the associated station. · qos_hdr: An 8-bit value representing the QoS header, which includes information about the QoS parameters. · use_ht_aggr: A boolean value indicating whether HT aggregation is being used. · rate_hw_value: A 16-bit value representing the hardware rate index for the transmission. · sifs: A 16-bit value representing the Short Interframe Space time in microseconds.

Code Description: The gen_ht_duration_id function computes the duration for HT QoS data frames based on various parameters related to the frame type and transmission characteristics. The function begins by initializing a duration variable dur to zero and determining the number of data bits per symbol (n_dbps) based on the provided hardware rate value. It checks the type of frame using the frame_control parameter to determine if it is a PS-Poll or a QoS data frame.

For PS-Poll frames, the duration is calculated as the AID combined with a specific constant. For QoS data frames, if the acknowledgment policy does not indicate no acknowledgment, the function calculates the number of octets based on whether HT aggregation is used. It then calculates the number of OFDM symbols required for the transmission and computes the duration as the sum of the Short Interframe Space (SIFS), a legacy preamble time, and the time required for the number of OFDM symbols. If the frame type does not match the expected types, a warning message is logged.

The function ultimately returns the calculated duration value, which is crucial for managing timing in wireless communication to ensure proper frame transmission and acknowledgment.

Note: It is important to ensure that the frame control field accurately reflects the type of frame being processed, as incorrect types may lead to erroneous duration calculations. Additionally, the function assumes that HT QoS data frames are always used for data transmission, while management and control frames are treated differently.

Output Example: A possible return value of the function could be 60, indicating that the calculated duration for the given parameters is 60 microseconds.

graph TD
    A[Start gen_ht_duration_id function] --> B[Initialize duration to 0]
    B --> C[Check if frame_control is pspoll]
    C -->|Yes| D[Set duration to aid OR 0xc000]
    C -->|No| E[Check if frame_control is data qos and not noack]
    E -->|Yes| F[Limit rate_hw_value to 6]
    F --> G[Determine n_dbps based on rate_hw_value]
    G --> H[Set num_octet based on use_ht_aggr]
    H --> I[Calculate num_ofdm_sym using num_octet and n_dbps]
    I --> J[Calculate duration as sifs + 20 + 4 * num_ofdm_sym]
    E -->|No| K[Log warning for wrong packet type]
    D --> L[Return duration]
    J --> L
    K --> L
    L[End function]

Function report_pkt_loss_due_to_driver_drop(struct ieee80211_hw dev, struct sk_buff skb)

report_pkt_loss_due_to_driver_drop: The function of report_pkt_loss_due_to_driver_drop is to report packet loss due to a driver drop by updating the transmission status of a given packet.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the hardware device structure representing the wireless device. · parameter2: struct sk_buff skb - A pointer to the socket buffer structure that contains the packet data.

Code Description: The report_pkt_loss_due_to_driver_drop function is an inline function that handles the reporting of packet loss when a packet is dropped by the driver. It takes two parameters: a pointer to the ieee80211_hw structure, which represents the wireless hardware device, and a pointer to the sk_buff structure, which contains the packet that was dropped.

The function begins by retrieving the private data associated with the device through the dev->priv pointer, which is cast to the openwifi_priv structure. This private data typically contains configuration and runtime information specific to the driver.

Next, the function retrieves the transmission information associated with the packet by calling the IEEE80211_SKB_CB macro on the skb parameter. This macro provides access to the ieee80211_tx_info structure, which holds various details about the transmission status of the packet.

The transmission status is then cleared using the ieee80211_tx_info_clear_status function, ensuring that any previous status information does not interfere with the new reporting. The function sets the count of the first rate entry in the rates array to 1, indicating that one transmission attempt has occurred. The second rate entry's index is set to -1, which typically signifies that there are no further rates to report.

Additionally, the antenna configuration used for transmission is set based on the runtime configuration stored in the priv structure, specifically in the runtime_tx_ant_cfg field.

Finally, the function calls ieee80211_tx_status_irqsafe, passing the device and the skb as arguments. This function is responsible for safely reporting the transmission status back to the network stack, ensuring that the packet loss is properly accounted for in the system.

Note: It is important to ensure that the device and skb parameters are valid before calling this function to avoid dereferencing null pointers. This function is intended to be used in scenarios where packet loss needs to be reported accurately to maintain the integrity of the transmission statistics.

graph TD
    A[Start function report_pkt_loss_due_to_driver_drop] --> B[Retrieve private data from device]
    B --> C[Get transmission info from skb]
    C --> D[Clear transmission status]
    D --> E[Set transmission count to 1]
    E --> F[Set antenna index from private configuration]
    F --> G[Send transmission status safely]
    G --> H[End function]

Function openwifi_tx(struct ieee80211_hw *dev,

           struct ieee80211_tx_control *control, 
           struct sk_buff *skb)

openwifi_tx: The function of openwifi_tx is to handle the transmission of data packets in the OpenWiFi driver by preparing the packet for transmission, managing the transmission queue, and interfacing with the hardware for DMA operations.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device. · control: A pointer to the ieee80211_tx_control structure containing transmission control information. · skb: A pointer to the sk_buff structure representing the socket buffer containing the data to be transmitted.

Code Description: The openwifi_tx function is responsible for managing the transmission of packets in the OpenWiFi driver. It begins by retrieving the private data associated with the hardware device and initializing various local variables used throughout the function. The function checks the length of the data in the socket buffer (skb) and ensures it is valid for transmission.

The function then extracts the priority of the packet and maps it to the appropriate driver ring index, which corresponds to the hardware queue. It locks the transmission ring to ensure thread safety while checking if there is space available in the buffer descriptors (BDs) for new packets. If the buffer is full, it handles the situation by stopping the transmission queue and reporting any packets that could not be transmitted.

Next, the function extracts additional information from the packet header, such as the MAC addresses and frame control fields. It determines the transmission rate and other transmission parameters based on the packet's characteristics and the driver configuration. The function also handles specific cases for RTS/CTS protection and checks for aggregation conditions.

Once all necessary information is gathered and validated, the function prepares the packet for DMA transmission. It ensures that the socket buffer has enough headroom and tailroom for the required data, including any necessary padding. The function then maps the data for DMA transfer, sets up the necessary hardware registers, and submits the DMA request.

Finally, the function updates the buffer descriptor with the transmission details, increments the write index, and issues the pending DMA operations. If any errors occur during the process, such as DMA mapping failures, the function cleans up and reports the packet loss.

Note: It is important to ensure that the socket buffer is properly allocated and that the hardware is configured correctly before calling this function. Additionally, developers should be aware of the potential for packet loss if the transmission queue is full or if DMA mapping fails.

Output Example: The function does not return a value, but it may log warnings or errors to the kernel log if issues arise during the transmission process. For example, a log entry might look like: "openwifi_tx: WARNING TX DMA mapping error".

graph TD
    A[Start openwifi_tx function] --> B[Check skb data length]
    B -->|Data length > 0| C[Log warning and go to early out]
    B -->|Data length <= 0| D[Get length of MPDU]
    D --> E[Get priority and queue mapping]
    E --> F[Check if priority is valid]
    F -->|Invalid priority| C
    F -->|Valid priority| G[Get address from header]
    G --> H[Map Linux priority to driver ring index]
    H --> I[Lock spinlock]
    I --> J[Check if ring buffer is cleared]
    J -->|Not cleared| K[Find empty buffer index]
    K --> L[Check hardware queue length]
    L -->|Empty buffer found| M[Clear buffers and report failure to Linux]
    M --> N[Wake up queue if needed]
    L -->|No empty buffer| O[Stop queue and log warning]
    O --> P[Unlock spinlock and go to early out]
    J -->|Cleared| Q[Unlock spinlock]
    Q --> R[Get additional info from packet header]
    R --> S[Check if packet needs acknowledgment]
    S --> T[Get retry limit and rate settings]
    T --> U[Check if using RTS/CTS]
    U --> V[Handle RTS/CTS settings]
    V --> W[Check if using HT aggregation]
    W -->|Using HT aggregation| X[Process HT aggregation]
    W -->|Not using HT aggregation| Y[Process non-HT aggregation]
    X --> Z[Check if packet is QoS]
    Z -->|Not QoS| C
    Y --> AA[Check DMA buffer size]
    AA -->|Buffer size exceeded| C
    AA -->|Buffer size valid| AB[Prepare sk_buff for DMA]
    AB --> AC[Map DMA address]
    AC --> AD[Check DMA mapping error]
    AD -->|Mapping error| AE[Handle DMA mapping error]
    AD -->|No error| AF[Prepare and submit DMA]
    AF --> AG[Update ring buffer]
    AG --> AH[Unlock spinlock]
    AH --> AI[Update statistics]
    AI --> AJ[Return from function]
    AE --> AK[Unmap DMA and report packet loss]
    AK --> AJ
    C --> AL[Report packet loss and return]
    AL --> AJ

Function openwifi_set_antenna(struct ieee80211_hw *dev, u32 tx_ant, u32 rx_ant)

openwifi_set_antenna: The function of openwifi_set_antenna is to configure the transmission and reception antenna settings for an OpenWiFi device.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device. · tx_ant: An unsigned 32-bit integer representing the transmission antenna index. · rx_ant: An unsigned 32-bit integer representing the reception antenna index.

Code Description: The openwifi_set_antenna function is responsible for setting the transmission and reception antenna configurations for a wireless device. It begins by retrieving the private data structure associated with the hardware device, which contains necessary configuration details. The function then validates the input parameters for the transmission and reception antennas, ensuring that they fall within acceptable ranges (tx_ant must be between 1 and 3, and rx_ant must be between 1 and 2).

Next, the function calculates the FPGA transmission antenna setting and the target reception antenna based on the provided indices. It attempts to set the transmission attenuation for both antennas using the ad9361_set_tx_atten function. If either call fails, it logs a warning and returns an error code.

Following successful attenuation settings, the function configures the control outputs for the selected reception antenna using ad9361_ctrl_outs_setup. Again, if this operation fails, it logs a warning and returns an error code.

The function then writes the calculated antenna settings to the respective interface registers for both transmission and reception. It verifies that the written values match the expected values, logging warnings if discrepancies are found.

Finally, the function updates the internal state variables to reflect the new antenna configurations and returns 0 to indicate success.

Note: It is important to ensure that the input parameters for tx_ant and rx_ant are within the specified ranges to avoid invalid configurations. Additionally, the function relies on successful execution of several hardware-specific function calls, which should be monitored for errors.

Output Example: A successful execution of the function will return 0, indicating that the antenna settings have been configured correctly. If an error occurs due to invalid parameters or hardware failures, the function may return -EINVAL.

graph TD
    A[Start openwifi_set_antenna] --> B[Log tx_ant and rx_ant values]
    B --> C{Check tx_ant validity}
    C -->|Invalid| D[Return -EINVAL]
    C -->|Valid| E{Check rx_ant validity}
    E -->|Invalid| F[Return -EINVAL]
    E -->|Valid| G[Set fpga_tx_ant_setting and target_rx_ant]
    G --> H[Calculate atten_mdb_tx0]
    H --> I[Calculate atten_mdb_tx1]
    I --> J[Call ad9361_set_tx_atten for ant0]
    J --> K{Check ad9361_set_tx_atten ant0 result}
    K -->|Fail| L[Log warning for ant0 and return -EINVAL]
    K -->|Success| M[Log success for ant0]
    M --> N[Call ad9361_set_tx_atten for ant1]
    N --> O{Check ad9361_set_tx_atten ant1 result}
    O -->|Fail| P[Log warning for ant1 and return -EINVAL]
    O -->|Success| Q[Log success for ant1]
    Q --> R[Setup ctrl_outs_control]
    R --> S{Check ad9361_ctrl_outs_setup result}
    S -->|Fail| T[Log warning and return -EINVAL]
    S -->|Success| U[Log setup success]
    U --> V[Write fpga_tx_ant_setting to TX_INTF_REG_ANT_SEL]
    V --> W[Read back TX_INTF_REG_ANT_SEL]
    W --> X{Check read back value}
    X -->|Mismatch| Y[Log warning and return -EINVAL]
    X -->|Match| Z[Log write success]
    Z --> AA[Write target_rx_ant to RX_INTF_REG_ANT_SEL]
    AA --> AB[Read back RX_INTF_REG_ANT_SEL]
    AB --> AC{Check read back value}
    AC -->|Mismatch| AD[Log warning and return -EINVAL]
    AC -->|Match| AE[Log write success]
    AE --> AF[Update internal state variables]
    AF --> AG{Check TX_OFFSET_TUNING_ENABLE}
    AG -->|Enabled| AH[Set tx_intf_cfg for TX_OFFSET_TUNING]
    AG -->|Disabled| AI{Check tx_ant value}
    AI -->|Equal to 3| AJ[Set tx_intf_cfg for both antennas]
    AI -->|Other| AK[Set tx_intf_cfg based on tx_ant]
    AH --> AL[Set rx_intf_cfg based on target_rx_ant]
    AK --> AL
    AL --> AM[Map frequency offsets]
    AM --> AN[Return 0]
    AN --> AO[End openwifi_set_antenna]

Function openwifi_get_antenna(struct ieee80211_hw dev, u32 tx_ant, u32 *rx_ant)

openwifi_get_antenna: The function of openwifi_get_antenna is to retrieve the current transmission and reception antenna configurations for the OpenWiFi device.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device. · tx_ant: A pointer to a variable where the transmission antenna configuration will be stored. · rx_ant: A pointer to a variable where the reception antenna configuration will be stored.

Code Description: The openwifi_get_antenna function begins by obtaining a pointer to the private data structure (openwifi_priv) associated with the provided ieee80211_hw device. This private structure contains runtime configuration details for the device.

The function then assigns the current transmission antenna configuration (runtime_tx_ant_cfg) to the variable pointed to by tx_ant and the current reception antenna configuration (runtime_rx_ant_cfg) to the variable pointed to by rx_ant. This allows the caller to access the current antenna settings.

Subsequently, the function logs the transmission and reception antenna configurations using the printk function, which outputs the information to the kernel log. It includes the values of tx_ant and rx_ant, as well as additional configuration details such as the driver’s transmission and reception interface configurations, frequency offsets, and control output selection.

Further logging is performed to display the antenna selection for both transmission and reception as read from the respective interface APIs. The function also retrieves and logs the RF transmission attenuation settings for two channels, along with the control output pointer value.

Finally, the function returns 0, indicating successful execution.

Note: It is important to ensure that the pointers provided for tx_ant and rx_ant are valid and point to allocated memory before calling this function. Additionally, the function assumes that the ieee80211_hw structure has been properly initialized and that the private data structure is correctly set up.

Output Example: A possible appearance of the code's return value could be:

openwifi_get_antenna: tx_ant 1 rx_ant 2
openwifi_get_antenna: drv tx cfg 3 offset 5 drv rx cfg 4 offset 6 drv ctrl_out sel 0x1A
openwifi_get_antenna: fpga tx sel 1 rx sel 0
openwifi_get_antenna: rf tx att0 10 tx att1 15 ctrl_out sel 0x2B

graph TD
    A[Start openwifi_get_antenna function] --> B[Retrieve private data from device]
    B --> C[Set tx_ant to runtime_tx_ant_cfg]
    C --> D[Set rx_ant to runtime_rx_ant_cfg]
    D --> E[Log tx_ant and rx_ant values]
    E --> F[Log driver tx and rx configurations]
    F --> G[Log FPGA tx and rx selections]
    G --> H[Log RF tx attenuations and control output selection]
    H --> I[Return 0]
    I --> J[End openwifi_get_antenna function]

Function openwifi_start(struct ieee80211_hw *dev)

openwifi_start: The function of openwifi_start is to initialize the OpenWiFi device and prepare it for operation.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device.

Code Description: The openwifi_start function is responsible for setting up the OpenWiFi device by performing several initialization tasks. It begins by retrieving the private data structure associated with the device, which contains configuration and state information. The function then initializes the virtual interfaces (VIFs) by setting them to NULL.

Next, the function configures the radio by setting the antenna and checking the transmit attenuation. It logs whether the radio is successfully turned on or if there was a failure. The function proceeds to initialize various hardware interfaces, including the RX and TX interfaces, as well as the OpenOFDM configurations. It also writes the MAC address to the appropriate register.

The function then disables interrupts for both RX and TX channels and holds the M AXIS in a reset state. It requests DMA channels for RX and TX operations, handling any errors that may occur during this process. If successful, it logs the successful setup of the DMA channels.

Following this, the function initializes the RX and TX rings, which are data structures used for managing incoming and outgoing packets. It sets up the RX DMA and registers interrupt handlers for RX and TX interrupts, ensuring that the system can respond to incoming and outgoing data appropriately.

The function also configures the interrupt settings to enable normal operation and resets the TSF timer. It disables auto calibration for the AD9361 and enables manual calibration, ensuring that the device is correctly configured for operation.

In case of any errors during the initialization process, the function includes error handling that frees allocated resources and logs the error before returning a negative value. If all operations are successful, the function returns 0, indicating that the device has been initialized without issues.

Note: It is important to ensure that the device is correctly configured and that all necessary resources are available before calling this function. Proper error handling should be implemented to manage any failures during initialization.

Output Example: A successful return value of the function would be 0, indicating that the OpenWiFi device has been initialized correctly. In case of an error, the function may return -1, along with appropriate error messages logged to the console.

graph TD
    A[Start openwifi_start function] --> B[Initialize priv and ret variables]
    B --> C[Set all vif entries to NULL]
    C --> D[Set antenna configuration]
    D --> E[Get TX attenuation]
    E --> F{Check TX attenuation}
    F -->|Equal| G[Set rfkill_off to 1]
    F -->|Not Equal| H[Log warning for TX attenuation]
    G --> I[Initialize RX interface]
    H --> I
    I --> J[Initialize TX interface]
    J --> K[Initialize openofdm TX interface]
    K --> L[Initialize openofdm RX interface]
    L --> M[Initialize XPU interface]
    M --> N[Write MAC address to XPU]
    N --> O[Log interface configurations]
    O --> P[Disable TX interrupt]
    P --> Q[Disable RX interrupt]
    Q --> R[Hold M AXIS in reset]
    R --> S[Request RX DMA channel]
    S --> T{Check RX channel request}
    T -->|Success| U[Request TX DMA channel]
    T -->|Failure| V[Log error and go to err_dma]
    U --> W{Check TX channel request}
    W -->|Success| X[Initialize RX ring]
    W -->|Failure| Y[Log error and go to err_free_rings]
    X --> Z{Check RX ring initialization}
    Z -->|Success| AA[Initialize TX rings]
    Z -->|Failure| AB[Log error and go to err_free_rings]
    AA --> AC{Check TX ring initialization}
    AC -->|Success| AD[Setup RX DMA]
    AC -->|Failure| AE[Log error and go to err_free_rings]
    AD --> AF{Check RX DMA setup}
    AF -->|Success| AG[Request RX IRQ]
    AF -->|Failure| AH[Log error and go to err_free_rings]
    AG --> AI{Check RX IRQ request}
    AI -->|Success| AJ[Request TX IRQ]
    AI -->|Failure| AK[Log error and go to err_free_rings]
    AJ --> AL{Check TX IRQ request}
    AL -->|Success| AM[Enable RX interrupt]
    AL -->|Failure| AN[Log error and go to err_free_rings]
    AM --> AO[Enable TX interrupt]
    AO --> AP[Release M AXIS]
    AP --> AQ[Reset TSF timer]
    AQ --> AR[Read CSMA configuration]
    AR --> AS[Disable auto calibration]
    AS --> AT[Log normal end]
    AT --> AU[Return 0]

    err_free_rings --> AV[Free RX ring]
    AV --> AW[Free TX rings]
    err_dma --> AX[Set ret to -1]
    AX --> AY[Log abnormal end]
    AY --> AU

Function openwifi_stop(struct ieee80211_hw *dev)

openwifi_stop: The function of openwifi_stop is to safely stop the OpenWiFi device and release associated resources.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device.

Code Description: The openwifi_stop function is designed to halt the operation of the OpenWiFi device and perform necessary cleanup tasks. It begins by retrieving the private data structure associated with the device, which contains configuration and state information. The function then enables automatic calibration for the AD9361 PHY while disabling manual transmission quadrature calibration. This is crucial for ensuring that the device can properly calibrate itself without manual intervention.

Next, the function disables the SPI control for the OpenWiFi FPGA, which is essential for stopping any ongoing communication with the FPGA. The function then mutes the transmitter by calling ad9361_tx_mute, effectively turning off the radio. It checks the transmission attenuation settings to confirm that the radio has been successfully turned off. If the attenuation settings do not match the expected values, a warning message is logged.

The function proceeds to disable transmission interrupts and reset the receive interface. It also clears the virtual interface pointers in the private structure, ensuring that no references to active interfaces remain. The function then frees the receive and transmit rings, which are data structures used for managing packet transmission and reception.

After releasing the DMA channels associated with both the receive and transmit operations, the function terminates any ongoing DMA operations and releases the channels. This is critical for preventing resource leaks and ensuring that the device can be safely reinitialized later.

Finally, the function frees the interrupts associated with the receive and transmit operations, ensuring that all resources are properly released. A log message is printed to indicate that the openwifi_stop function has completed its execution.

Note: It is important to ensure that this function is called when the device is no longer needed to prevent resource leaks and ensure proper device operation. Proper error handling should be implemented to manage any issues that arise during the stopping process.

graph TD
    A[Start openwifi_stop function] --> B[Get private structure from device]
    B --> C[Enable auto calibration]
    C --> D[Disable manual Tx quadrature calibration]
    D --> E[Disable SPI control]
    E --> F[Turn off radio]
    F --> G[Check Tx attenuation values]
    G -->|If Tx attenuation values are correct| H[Set rfkill_off to 0]
    G -->|If Tx attenuation values are incorrect| I[Log warning message]
    H --> J[Disable Tx interrupt]
    I --> J
    J --> K[Disable FCS valid by interrupt test mode]
    K --> L[Hold M AXIS in reset status]
    L --> M[Clear virtual interfaces]
    M --> N[Free RX ring]
    N --> O[Free TX rings]
    O --> P[Terminate and release RX DMA channel]
    P --> Q[Terminate and release TX DMA channel]
    Q --> R[Free IRQs for RX and TX]
    R --> S[Log completion message]
    S --> T[End openwifi_stop function]

Function openwifi_get_tsf(struct ieee80211_hw *dev,

           struct ieee80211_vif *vif)

openwifi_get_tsf: The function of openwifi_get_tsf is to retrieve the timestamp value from the hardware.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the IEEE 802.11 hardware structure representing the device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure associated with the device.

Code Description: The openwifi_get_tsf function is a static function that retrieves the current timestamp value from the hardware. It takes two parameters: a pointer to the ieee80211_hw structure (dev), which represents the wireless device, and a pointer to the ieee80211_vif structure (vif), which represents the virtual interface.

Inside the function, two local variables, tsft_low and tsft_high, are declared as 32-bit unsigned integers. The function then reads the low and high parts of the timestamp value from the hardware registers using the xpu_api interface. Specifically, it calls the XPU_REG_TSF_RUNTIME_VAL_LOW_read() function to get the lower 32 bits and the XPU_REG_TSF_RUNTIME_VAL_HIGH_read() function to get the upper 32 bits of the timestamp.

After retrieving both parts, the function combines them into a single 64-bit unsigned integer by shifting the high part left by 32 bits and performing a bitwise OR operation with the low part. This results in a complete 64-bit timestamp value, which is then returned by the function.

Note: It is important to ensure that the xpu_api interface is properly initialized and that the hardware registers are accessible before calling this function. Additionally, the returned timestamp value is in a 64-bit format, which may need to be interpreted according to the specific requirements of the application using this function.

Output Example: A possible return value of the function could be a 64-bit integer such as 0x0000000100000002, which represents a combined timestamp value where the lower 32 bits are 0x00000002 and the upper 32 bits are 0x00000001.

graph TD
    A[Start openwifi_get_tsf function] --> B[Read TSF low value from XPU_REG_TSF_RUNTIME_VAL_LOW]
    B --> C[Read TSF high value from XPU_REG_TSF_RUNTIME_VAL_HIGH]
    C --> D[Combine TSF low and high values into a 64-bit result]
    D --> E[Return combined TSF value]
    E --> F[End openwifi_get_tsf function]

Function openwifi_set_tsf(struct ieee80211_hw hw, struct ieee80211_vif vif, u64 tsf)

openwifi_set_tsf: The function of openwifi_set_tsf is to set the timestamp frequency (TSF) value in the hardware.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw hw - A pointer to the hardware structure representing the IEEE 802.11 device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure associated with the device. · parameter3: u64 tsf - The timestamp frequency value to be set, represented as a 64-bit unsigned integer.

Code Description: The openwifi_set_tsf function is a static function that takes three parameters: a pointer to the hardware structure (hw), a pointer to the virtual interface structure (vif), and a 64-bit timestamp frequency value (tsf). The function begins by splitting the 64-bit timestamp value into two 32-bit parts: the high part (tsft_high) and the low part (tsft_low). This is achieved by right-shifting the timestamp value by 32 bits to obtain the high part and using a bitwise AND operation with 0xffffffff to obtain the low part.

Next, the function calls the XPU_REG_TSF_LOAD_VAL_write method from the xpu_api interface, passing the two 32-bit values (tsft_high and tsft_low) as arguments. This operation is responsible for writing the timestamp values to the appropriate register in the hardware.

Finally, the function logs the operation using the printk function, which outputs a formatted string that includes the compatible string (sdr_compatible_str) and the two parts of the timestamp in hexadecimal format. This logging is useful for debugging and monitoring purposes.

Note: It is important to ensure that the hardware is properly initialized before calling this function, as it directly interacts with the hardware registers. Additionally, the timestamp value should be valid and within the expected range to avoid any unintended behavior.

graph TD
    A[Start openwifi_set_tsf function] --> B[Extract high part of TSF]
    A --> C[Extract low part of TSF]
    B --> D[Write high part to XPU register]
    C --> D
    D --> E[Write low part to XPU register]
    E --> F[Log TSF values]
    F --> G[End openwifi_set_tsf function]

Function openwifi_reset_tsf(struct ieee80211_hw hw, struct ieee80211_vif vif)

openwifi_reset_tsf: The function of openwifi_reset_tsf is to reset the TSF (Timestamp Field) value in the OpenWiFi system.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw hw - A pointer to the hardware structure representing the IEEE 802.11 hardware device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure representing the specific virtual interface.

Code Description: The openwifi_reset_tsf function is a static function that is responsible for resetting the Timestamp Field (TSF) value in the context of the OpenWiFi system. The function takes two parameters: a pointer to the ieee80211_hw structure, which contains information about the hardware device, and a pointer to the ieee80211_vif structure, which represents the virtual interface being used.

Inside the function, the first operation performed is a call to the XPU_REG_TSF_LOAD_VAL_write function through the xpu_api interface. This function is invoked with two arguments, both set to zero, which effectively resets the TSF value to its initial state. This operation is crucial for maintaining accurate timing and synchronization within the wireless network.

Following the reset operation, the function logs a message to the kernel log using the printk function. The message includes the string representation of the sdr_compatible_str variable, indicating that the openwifi_reset_tsf function has been executed. This logging is useful for debugging and monitoring purposes, allowing developers to track when the TSF reset occurs.

Note: It is important to ensure that the function is called in the appropriate context where the hardware and virtual interface structures are valid. Additionally, developers should be aware that resetting the TSF may impact ongoing network operations, and thus it should be used judiciously to avoid unintended disruptions in service.

graph TD
    A[Start openwifi_reset_tsf function] --> B[Write TSF load value to 0]
    B --> C[Log message indicating function execution]
    C --> D[End openwifi_reset_tsf function]

Function openwifi_set_rts_threshold(struct ieee80211_hw *hw, u32 value)

openwifi_set_rts_threshold: The function of openwifi_set_rts_threshold is to set the RTS (Request to Send) threshold for the OpenWiFi driver.

parameters: The parameters of this Function. · hw: A pointer to the ieee80211_hw structure, which represents the hardware associated with the wireless device. · value: An unsigned 32-bit integer that specifies the RTS threshold value to be set.

Code Description: The openwifi_set_rts_threshold function is defined as a static function, meaning it is limited in scope to the file in which it is declared (sdr.c). The function takes two parameters: a pointer to an ieee80211_hw structure (hw) and an unsigned 32-bit integer (value).

Within the function, a printk statement is executed, which logs a warning message to the kernel log. This message includes a string (sdr_compatible_str) and the value of the RTS threshold being set. The purpose of this logging is to provide feedback during the execution of the function, particularly if the value being set is noteworthy or potentially problematic.

After logging the message, the function returns 0, indicating successful completion of the operation. It is important to note that while the function currently does not implement any logic to actually set the RTS threshold, it serves as a placeholder for future enhancements or as part of a larger framework where the actual setting of the threshold may be handled elsewhere.

Note: It is essential to ensure that the value passed to this function is within the acceptable range for RTS thresholds as defined by the wireless standards. Additionally, since this function is static, it cannot be called from other files, which may limit its usability in a broader context.

Output Example: A possible appearance of the code's return value would be:

sdr_compatible_str openwifi_set_rts_threshold WARNING value 2346

graph TD
    A[Start openwifi_set_rts_threshold function] --> B[Receive parameters hw and value]
    B --> C[Log warning message with value]
    C --> D[Return 0]
    D --> E[End openwifi_set_rts_threshold function]

Function openwifi_beacon_work(struct work_struct *work)

openwifi_beacon_work: The function of openwifi_beacon_work is to manage the transmission of beacon frames for the OpenWiFi driver.

parameters: The parameters of this Function. · work: A pointer to a struct work_struct, which is used to represent the work item that is being processed.

Code Description: The openwifi_beacon_work function is responsible for handling the periodic transmission of beacon frames in an OpenWiFi environment. It begins by obtaining a pointer to the private data structure openwifi_vif associated with the work item. This is achieved using the container_of macro, which allows the function to retrieve the parent structure from a member pointer. The function then retrieves the ieee80211_vif structure, which represents the virtual interface, and the ieee80211_hw structure, which represents the hardware device.

The function first checks if the transmission queue is stopped using ieee80211_queue_stopped. If the queue is stopped, it proceeds to the rescheduling section without attempting to send a beacon. If the queue is not stopped, the function attempts to obtain a fresh beacon frame using ieee80211_beacon_get. If this operation fails (i.e., skb is NULL), it again goes to the rescheduling section.

Once a beacon frame is successfully retrieved, the function updates the beacon's timestamp with the current TSF (Timestamp Field) value obtained from the openwifi_get_tsf function. This ensures that the beacon frame contains the correct timing information. The skb_set_queue_mapping function is then called to set the queue mapping for the beacon frame, although it currently uses a placeholder value of 0.

The beacon frame is transmitted using the openwifi_tx function, which handles the actual sending of the frame to the hardware.

Finally, the function schedules the next beacon transmission by calling schedule_delayed_work. This sets up the work item to be executed again after a delay determined by the beacon interval configured in the vif structure. The delay is converted from microseconds to jiffies using the usecs_to_jiffies function.

Note: It is important to ensure that the transmission queue is not stopped before attempting to send a beacon. Additionally, the function contains TODO comments indicating areas for future improvement, such as utilizing hardware support for updating the beacon timestamp and managing the beacon queue more effectively.

graph TD
    A[Start openwifi_beacon_work] --> B[Get vif_priv from work]
    B --> C[Get vif from vif_priv]
    C --> D[Get dev from vif_priv]
    D --> E[Check if tx ring is stopped]
    E -->|Yes| F[Go to resched]
    E -->|No| G[Get fresh beacon skb]
    G --> H[Check if skb is valid]
    H -->|No| F
    H -->|Yes| I[Update beacon timestamp with TSF value]
    I --> J[Set skb queue mapping]
    J --> K[Transmit skb using openwifi_tx]
    K --> F
    F --> L[Schedule next beacon]
    L --> M[End openwifi_beacon_work]

Function openwifi_add_interface(struct ieee80211_hw *dev,

             struct ieee80211_vif *vif)

openwifi_add_interface: The function of openwifi_add_interface is to add a new interface to the OpenWiFi driver.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the hardware structure representing the device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure that is to be added.

Code Description: The openwifi_add_interface function is responsible for adding a new virtual interface (VIF) to the OpenWiFi driver. It begins by checking the type of the VIF being added. The function supports several interface types, including Access Point (AP), Station, Ad-Hoc, Monitor, and Mesh Point. If the VIF type is not one of these, the function returns -EOPNOTSUPP, indicating that the operation is not supported.

Next, the function attempts to find an available slot for the new VIF by iterating through a predefined maximum number of VIFs (MAX_NUM_VIF). If all slots are occupied, the function returns -EBUSY, indicating that no more interfaces can be added.

Once a free slot is found, the function assigns the VIF to the corresponding index in the private structure of the driver. It then initializes the driver-specific private area associated with the VIF, setting the index and device pointer. A delayed work structure for beaconing is initialized, and the beaconing feature is disabled by default.

The function also sets the MAC address for the device by copying the address from the VIF structure to the driver's private MAC address array. This MAC address is then written to the FPGA using the XPU_REG_MAC_ADDR_write function.

Finally, the function logs the completion of the operation, including the index of the VIF and its MAC address, before returning 0 to indicate success.

Note: It is important to ensure that the VIF type is supported and that there is an available slot before calling this function. Proper initialization of the ieee80211_hw and ieee80211_vif structures is also necessary to avoid unexpected behavior.

Output Example: A successful call to openwifi_add_interface might return 0, indicating that the interface was added successfully. If the VIF type is unsupported, it would return -EOPNOTSUPP, and if the maximum number of interfaces is reached, it would return -EBUSY.

graph TD
    A[Start openwifi_add_interface] --> B[Get private data from device]
    B --> C[Check vif type]
    C -->|If valid type| D[Find available interface index]
    C -->|If invalid type| E[Return error EOPNOTSUPP]
    D --> F[Check if index is MAX_NUM_VIF]
    F -->|If index is MAX_NUM_VIF| G[Return error EBUSY]
    F -->|If index is available| H[Assign vif to priv->vif[index]]
    H --> I[Initialize driver private area]
    I --> J[Set MAC address]
    J --> K[Write MAC address to FPGA]
    K --> L[Log end of function with vif index and address]
    L --> M[Return success]
    E --> M
    G --> M

Function openwifi_remove_interface(struct ieee80211_hw *dev,

                 struct ieee80211_vif *vif)

openwifi_remove_interface: The function of openwifi_remove_interface is to remove a virtual interface from the OpenWiFi driver.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the hardware structure representing the IEEE 802.11 device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure that is to be removed.

Code Description: The openwifi_remove_interface function is a static function that handles the removal of a virtual interface (vif) from the OpenWiFi driver. It takes two parameters: a pointer to the hardware device structure (dev) and a pointer to the virtual interface structure (vif).

Within the function, a pointer to the private data of the virtual interface (vif_priv) is obtained by casting the driver-specific private data from the vif structure. This private data contains an index (idx) that identifies the specific virtual interface being removed.

The function then accesses the private data of the OpenWiFi driver (priv) through the dev structure. It sets the corresponding entry in the vif array of the OpenWiFi private structure to NULL, effectively removing the reference to the virtual interface being deleted.

Finally, the function logs a message to the kernel log using printk, indicating that the virtual interface has been removed and displaying its index. This logging is useful for debugging and tracking the state of virtual interfaces within the driver.

Note: It is important to ensure that this function is called when a virtual interface is no longer needed to prevent memory leaks and maintain the integrity of the driver’s state. Proper synchronization mechanisms should be considered if this function is called in a multi-threaded environment to avoid race conditions.

graph TD
    A[Start openwifi_remove_interface] --> B[Get private data from device]
    B --> C[Cast drv_priv to openwifi_vif]
    C --> D[Set vif entry to NULL using vif index]
    D --> E[Log removal of vif index]
    E --> F[End openwifi_remove_interface]

Function openwifi_config(struct ieee80211_hw *dev, u32 changed)

openwifi_config: The function of openwifi_config is to configure the OpenWiFi settings based on the current hardware state and any changes requested.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the wireless device. · changed: A bitmask indicating which configuration parameters have changed.

Code Description: The openwifi_config function is designed to handle configuration changes for a wireless device represented by the ieee80211_hw structure. It first retrieves the private data associated with the device through the dev->priv pointer, which is cast to the openwifi_priv structure. It also accesses the current configuration settings via dev->conf.

The function checks if the changed parameter includes the IEEE80211_CONF_CHANGE_CHANNEL flag, indicating that the channel configuration has been modified. If this flag is set, the function then verifies whether the requested frequency (conf->chandef.chan->center_freq) is restricted by the device's private state (priv->stat.restrict_freq_mhz). If the requested frequency does not match the restricted frequency and the restricted frequency is greater than zero, the function logs a message indicating that the requested frequency is being avoided due to restrictions and returns an error code (-EINVAL).

If the frequency is acceptable, the function proceeds to call the set_chan method on the device's radio frequency (RF) structure (priv->rf->set_chan), passing the device and its configuration as arguments to apply the new channel settings.

If the changed parameter does not include the channel change flag, the function logs a message indicating which flags have changed, providing a hexadecimal representation of the changed bitmask.

Finally, the function returns 0, indicating successful completion of the configuration process.

Note: It is important to ensure that the restricted frequency is properly set in the device's private state to avoid conflicts with requested configurations. The function is designed to prevent invalid frequency settings that could lead to operational issues.

Output Example: If the requested frequency is restricted, the output might look like: "openwifi_config avoid Linux requested freq 2412MHz (restrict freq 2412MHz)" and the function would return -EINVAL. If the configuration is successful, the function would return 0 without additional output.

graph TD
    A[Start openwifi_config function] --> B[Get private data from device]
    B --> C[Check if changed includes channel change]
    C -->|Yes| D[Check if restrict frequency is set]
    D -->|Yes| E[Check if current frequency matches restrict frequency]
    E -->|No| F[Set channel using set_chan function]
    E -->|Yes| G[Log message about avoiding requested frequency]
    G --> H[Return error -EINVAL]
    F --> H[Return success 0]
    C -->|No| I[Log message about changed flag]
    I --> H[Return success 0]
    H --> J[End openwifi_config function]

Function openwifi_bss_info_changed(struct ieee80211_hw *dev,

                 struct ieee80211_vif *vif, 
                 struct ieee80211_bss_conf *info, 
                 u32 changed)

openwifi_bss_info_changed: The function of openwifi_bss_info_changed is to handle changes in the Basic Service Set (BSS) configuration for OpenWiFi.

parameters: The parameters of this Function. · parameter1: struct ieee80211_hw dev - A pointer to the hardware structure representing the device. · parameter2: struct ieee80211_vif vif - A pointer to the virtual interface structure. · parameter3: struct ieee80211_bss_conf *info - A pointer to the BSS configuration structure containing updated information. · parameter4: u32 changed - A bitmask indicating which BSS parameters have changed.

Code Description: The openwifi_bss_info_changed function is responsible for processing updates to the BSS configuration based on the changes indicated by the 'changed' parameter. It begins by retrieving the private data associated with the device and the virtual interface. The function checks for specific flags in the 'changed' bitmask to determine which BSS parameters have been modified.

If the BSS identifier (BSSID) has changed (indicated by BSS_CHANGED_BSSID), the function logs the new BSSID and writes it to the hardware registers using the XPU API. The BSSID is split into low and high parts for this operation.

The function also handles other potential changes, such as the beacon interval (BSS_CHANGED_BEACON_INT), transmission power (BSS_CHANGED_TXPOWER), and basic rates (BSS_CHANGED_BASIC_RATES), logging warnings for each of these changes.

For changes related to the Enhanced Distributed Channel Access (EDCA) parameters, such as short slot usage (BSS_CHANGED_ERP_SLOT) and preamble (BSS_CHANGED_ERP_PREAMBLE), the function updates the private structure accordingly and writes the new configuration to the hardware.

If the beacon is enabled or modified (BSS_CHANGED_BEACON_ENABLED or BSS_CHANGED_BEACON), the function manages the scheduling of beacon work, ensuring that the appropriate actions are taken based on the current state of the beacon.

Note: It is important to note that the function contains a cautionary comment regarding the validity of the chip and the addresses used for the BSSID. Developers should ensure that the hardware is properly initialized before invoking this function to avoid potential issues with invalid register access.

graph TD
    A[Start openwifi_bss_info_changed] --> B[Retrieve private data from device]
    B --> C[Check if BSSID changed]
    C -->|Yes| D[Log BSSID change]
    D --> E[Write new BSSID to hardware]
    E --> F[Write BSSID filter low]
    F --> G[Write BSSID filter high]
    C -->|No| H[Check if Beacon Interval changed]
    H -->|Yes| I[Log Beacon Interval warning]
    H -->|No| J[Check if TX Power changed]
    J -->|Yes| K[Log TX Power warning]
    J -->|No| L[Check if ERP CTS Protection changed]
    L -->|Yes| M[Log ERP CTS Protection warning]
    L -->|No| N[Check if Basic Rates changed]
    N -->|Yes| O[Log Basic Rates warning]
    N -->|No| P[Check if ERP Slot or Preamble changed]
    P -->|Yes| Q[Log ERP Slot and Preamble warning]
    Q --> R[Update short slot setting]
    P -->|No| S[Check if Beacon Enabled changed]
    S -->|Yes| T[Log Beacon Enabled warning]
    T --> U[Update beacon enable status]
    S -->|No| V[Check if Beacon Enabled or Beacon changed]
    V -->|Yes| W[Cancel delayed work for beacon]
    W --> X[Check if beacon should be enabled]
    X -->|Yes| Y[Schedule work for beacon]
    X -->|No| Z[End processing]
    V -->|No| Z
    K --> Z
    M --> Z
    O --> Z
    I --> Z
    D --> Z
    Z[End openwifi_bss_info_changed]

Function log2val(u32 val)

log2val: The function of log2val is to calculate the base-2 logarithm of a given unsigned integer value.

parameters: The parameters of this Function. · parameter1: u32 val - The unsigned integer value for which the base-2 logarithm is to be calculated. It must be greater than 0.

Code Description: The log2val function computes the base-2 logarithm of the input value 'val' by repeatedly right-shifting the value until it becomes less than or equal to 1. The function initializes a variable 'ret_val' to 0, which will hold the count of how many times the value can be divided by 2. In each iteration of the while loop, the function checks if 'val' is greater than 1. If true, it performs a right shift operation on 'val', effectively dividing it by 2, and increments 'ret_val' by 1. This process continues until 'val' is no longer greater than 1. Finally, the function returns 'ret_val', which represents the integer part of the base-2 logarithm of the original input value.

Note: It is important to ensure that the input value 'val' is greater than 0 before calling this function, as passing a value of 0 or a negative number will lead to undefined behavior or an infinite loop.

Output Example: For an input value of 16, the function would return 4, as 2 raised to the power of 4 equals 16. For an input value of 8, the return value would be 3, since 2 raised to the power of 3 equals 8.

activityDiagram
    start
    :Initialize ret_val to 0;
    :Check if val is greater than 1;
    repeat while (val > 1)
        :Right shift val by 1;
        :Increment ret_val by 1;
        :Check if val is greater than 1;
    end repeat
    :Return ret_val;
    end

Function openwifi_conf_tx(struct ieee80211_hw dev, struct ieee80211_vif vif, u16 queue,

      const struct ieee80211_tx_queue_params *params)

openwifi_conf_tx: The function of openwifi_conf_tx is to configure the transmission parameters for a specified transmission queue in the OpenWiFi driver.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device. · vif: A pointer to the ieee80211_vif structure representing the virtual interface. · queue: An unsigned 16-bit integer representing the transmission queue index. · params: A pointer to the ieee80211_tx_queue_params structure containing the transmission queue parameters.

Code Description: The openwifi_conf_tx function is designed to configure the transmission parameters for a specific queue in the OpenWiFi driver. It begins by retrieving the private data structure associated with the hardware device, which contains various statistics and configuration settings.

The function checks if the cw_max_min_cfg field of the private structure is set to zero. If it is, the function logs the current configuration parameters, including the queue index, AIFS (Arbitration Inter-Frame Space), and the minimum and maximum contention window sizes. It then reads the current CSMA (Carrier Sense Multiple Access) configuration from the hardware register.

The function calculates the minimum and maximum contention window exponent values using the log2val function, which computes the base-2 logarithm of the given values plus one. Based on the specified queue index, the function updates the appropriate bits in the register value to reflect the new contention window settings. The switch statement handles four specific queues (0 to 3), and if an invalid queue index is provided, a warning message is logged, and the function returns 0.

If the cw_max_min_cfg field is not zero, the function overrides the contention window settings using the values stored in this field. It logs the overridden values for each queue, indicating the minimum and maximum contention window sizes.

Finally, the function writes the updated register value back to the hardware register to apply the new configuration. The function concludes by returning 0, indicating successful execution.

Note: It is important to ensure that the queue index provided is valid (0 to 3) to avoid warnings and potential misconfiguration. The function assumes that the log2val function is correctly implemented and that the hardware register operations are successful.

Output Example: A possible appearance of the code's return value could be 0, indicating that the function executed successfully without errors.

graph TD
    A[Start openwifi_conf_tx function] --> B[Get private structure from device]
    B --> C[Check if cw_max_min_cfg is 0]
    C -->|Yes| D[Log queue parameters and ignore aifs and txop]
    D --> E[Read CSMA configuration register]
    E --> F[Calculate cw_min_exp and cw_max_exp]
    F --> G[Switch based on queue]
    G -->|Case 0| H[Update reg_val for queue 0]
    G -->|Case 1| I[Update reg_val for queue 1]
    G -->|Case 2| J[Update reg_val for queue 2]
    G -->|Case 3| K[Update reg_val for queue 3]
    G -->|Default| L[Log warning for non-existent queue and return 0]
    H --> M[Write updated reg_val to CSMA configuration register]
    I --> M
    J --> M
    K --> M
    C -->|No| N[Set reg_val to cw_max_min_cfg]
    N --> O[Log overridden cw max min values]
    O --> M
    M --> P[Return 0]
    P --> Q[End openwifi_conf_tx function]

Function openwifi_prepare_multicast(struct ieee80211_hw *dev,

                 struct netdev_hw_addr_list *mc_list)

openwifi_prepare_multicast: The function of openwifi_prepare_multicast is to prepare the multicast address list for the OpenWiFi driver.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the hardware device. · mc_list: A pointer to the netdev_hw_addr_list structure containing the multicast addresses.

Code Description: The openwifi_prepare_multicast function is defined as a static function, meaning it is limited in scope to the file in which it is declared. It takes two parameters: a pointer to an ieee80211_hw structure (dev) and a pointer to a netdev_hw_addr_list structure (mc_list). The function begins by logging a message to the kernel log using printk, indicating that the openwifi_prepare_multicast function has been called, along with a string that represents the compatibility of the SDR (Software Defined Radio) driver. This log message can be useful for debugging and monitoring purposes.

After logging the message, the function returns the count of multicast addresses present in the mc_list by calling the netdev_hw_addr_list_count function. This count represents the number of multicast addresses that have been prepared for use by the OpenWiFi driver.

Note: It is important to ensure that the mc_list parameter is properly initialized and populated with multicast addresses before calling this function. Additionally, the function is static, so it cannot be called from other files, which is a design choice to encapsulate its functionality within the driver.

Output Example: If the mc_list contains 5 multicast addresses, the function would return the value 5. The log message would appear in the kernel log as "sdr_compatible_str openwifi_prepare_multicast".

graph TD
    A[Start openwifi_prepare_multicast] --> B[Log function entry]
    B --> C[Count multicast addresses in mc_list]
    C --> D[Return count of multicast addresses]
    D --> E[End openwifi_prepare_multicast]

Function openwifi_configure_filter(struct ieee80211_hw *dev,

                 unsigned int changed_flags, 
                 unsigned int *total_flags, 
                 u64 multicast)

openwifi_configure_filter: The function of openwifi_configure_filter is to configure the filtering options for the OpenWiFi driver based on the current hardware settings and specified flags.

parameters: The parameters of this Function. · dev: A pointer to the ieee80211_hw structure representing the wireless device. · changed_flags: An unsigned integer representing the flags that have changed. · total_flags: A pointer to an unsigned integer that holds the total filter flags after configuration. · multicast: A 64-bit unsigned integer representing the multicast filter settings.

Code Description: The openwifi_configure_filter function is responsible for setting up the filter flags for the OpenWiFi driver. It begins by obtaining the private data structure associated with the device through the dev parameter. The function then modifies the total_flags variable to ensure it only contains supported filter flags by applying a bitwise AND operation with SDR_SUPPORTED_FILTERS. It also ensures that all multicast packets are passed to the upper layer by setting the FIF_ALLMULTI flag.

Next, the function constructs the filter_flag variable by combining the total_flags with specific flags that dictate how unicast and broadcast packets should be handled. The function checks if the device is in monitor mode by evaluating if certain bits in the filter_flag are set. If the device is in monitor mode, it adds the MONITOR_ALL flag; otherwise, it clears this flag.

The function also ensures that the MY_BEACON flag is set unless the FIF_BCN_PRBRESP_PROMISC flag is already set. Additionally, it sets the FIF_PSPOLL flag, which is used for Power Save Polling.

If the rx_monitor_all flag in the private structure is set, the MONITOR_ALL flag is added to the filter_flag. Finally, the function writes the configured filter_flag to the hardware register using the XPU_REG_FILTER_FLAG_write function, including a HIGH_PRIORITY_DISCARD_FLAG to manage packet priority.

The function concludes by logging the current filter settings using printk, providing a detailed output of the various flags that have been configured.

Note: It is important to ensure that the flags being set are compatible with the hardware capabilities and that the device is in the correct mode for the intended operation. Proper understanding of the filter flags and their implications on packet processing is crucial for effective driver operation.

graph TD
    A[Start openwifi_configure_filter] --> B[Retrieve private data from device]
    B --> C[Update total_flags with supported filters]
    C --> D[Set total_flags to allow all multicast]
    D --> E[Store total_flags in filter_flag]
    E --> F[Update filter_flag with unicast and broadcast settings]
    F --> G{Check if monitor mode is active}
    G -->|Yes| H[Set filter_flag to include monitor all]
    G -->|No| I[Remove monitor all from filter_flag]
    H --> J[Check if beacon response is not in promiscuous mode]
    I --> J
    J -->|No| K[Add MY_BEACON to filter_flag]
    J -->|Yes| L[Skip adding MY_BEACON]
    K --> M[Add FIF_PSPOLL to filter_flag]
    L --> M
    M --> N{Check if rx_monitor_all is active}
    N -->|Yes| O[Add monitor all to filter_flag]
    N -->|No| P[Skip adding monitor all]
    O --> Q[Write filter_flag to XPU_REG_FILTER_FLAG with high priority discard]
    P --> Q
    Q --> R[Log filter_flag details]
    R --> S[End openwifi_configure_filter]

Function openwifi_ampdu_action(struct ieee80211_hw hw, struct ieee80211_vif vif, struct ieee80211_ampdu_params *params)

openwifi_ampdu_action: The function of openwifi_ampdu_action is to manage the aggregation actions for both transmission (TX) and reception (RX) in the OpenWiFi driver.

parameters: The parameters of this Function. · hw: A pointer to the ieee80211_hw structure representing the hardware context. · vif: A pointer to the ieee80211_vif structure representing the virtual interface. · params: A pointer to the ieee80211_ampdu_params structure containing parameters for the A-MPDU action.

Code Description: The openwifi_ampdu_action function is responsible for handling various A-MPDU (Aggregated MAC Protocol Data Unit) actions based on the input parameters. It first checks if aggregation is enabled through the AGGR_ENABLE macro. If aggregation is not enabled, the function returns -EOPNOTSUPP, indicating that the operation is not supported.

The function then processes the action specified in the params structure, which can be one of several defined actions:

  1. IEEE80211_AMPDU_TX_START: This action initiates TX aggregation. The function calls ieee80211_start_tx_ba_cb_irqsafe to start the block acknowledgment (BA) for transmission and logs the action.

  2. IEEE80211_AMPDU_TX_STOP_CONT, IEEE80211_AMPDU_TX_STOP_FLUSH, and IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: These actions stop TX aggregation. The function calls ieee80211_stop_tx_ba_cb_irqsafe to stop the BA for transmission and logs the action.

  3. IEEE80211_AMPDU_TX_OPERATIONAL: This action configures the operational parameters for TX aggregation. It calculates the maximum transmission bytes based on the A-MPDU factor and the station's capabilities. The function constructs an ampdu_action_config value that includes the A-MPDU density, buffer size, and maximum TX bytes, which is then written to the TX interface API.

  4. IEEE80211_AMPDU_RX_START: This action indicates the start of RX aggregation and logs the action.

  5. IEEE80211_AMPDU_RX_STOP: This action indicates the stop of RX aggregation and logs the action.

If the action provided does not match any of the defined cases, the function returns -EOPNOTSUPP, indicating that the operation is not supported.

Finally, if the action is processed successfully, the function returns 0, indicating success.

Note: It is important to ensure that aggregation is enabled before calling this function. The function is designed to be called in a context where the hardware and virtual interface are properly initialized.

Output Example: A successful call to openwifi_ampdu_action with the action IEEE80211_AMPDU_TX_START might produce the following log output: "openwifi_ampdu_action: start TX aggregation. tid 1". If aggregation is not supported, the function would return -EOPNOTSUPP.

graph TD
    A[Start openwifi_ampdu_action] --> B[Check AGGR_ENABLE]
    B -->|No| C[Return -EOPNOTSUPP]
    B -->|Yes| D[Get action from params]
    D --> E{Action}
    E -->|IEEE80211_AMPDU_TX_START| F[Start TX aggregation]
    E -->|IEEE80211_AMPDU_TX_STOP_CONT| G[Stop TX aggregation]
    E -->|IEEE80211_AMPDU_TX_STOP_FLUSH| G
    E -->|IEEE80211_AMPDU_TX_STOP_FLUSH_CONT| G
    E -->|IEEE80211_AMPDU_TX_OPERATIONAL| H[Configure TX operational]
    E -->|IEEE80211_AMPDU_RX_START| I[Start RX aggregation]
    E -->|IEEE80211_AMPDU_RX_STOP| J[Stop RX aggregation]
    E -->|Default| C
    F --> K[Log TX aggregation start]
    G --> L[Log TX aggregation stop]
    H --> M[Write ampdu_action_config]
    I --> N[Log RX aggregation start]
    J --> O[Log RX aggregation stop]
    K --> P[Return 0]
    L --> P
    M --> P
    N --> P
    O --> P

Function custom_match_spi_dev(struct device dev, const void data)

custom_match_spi_dev: The function of custom_match_spi_dev is to compare the name of a device node with a given name and return a boolean result indicating whether they match.

parameters: The parameters of this Function. · parameter1: struct device dev - A pointer to the device structure that contains information about the device being matched. · parameter2: const void data - A pointer to the data that contains the name to be compared against the device node's name.

Code Description: The custom_match_spi_dev function is a static function that takes two parameters: a pointer to a device structure and a pointer to a constant data structure. The purpose of this function is to determine if the name of the device node associated with the provided device matches a specified name.

Inside the function, the name is extracted from the data pointer and is cast to a constant character pointer. The function then uses the sysfs_streq function to compare the extracted name with the name of the device node (dev->of_node->name). The result of this comparison is stored in the boolean variable ret, which will be true if the names match and false otherwise.

Additionally, the function logs the comparison result using printk, which outputs a formatted string that includes the compatible string (sdr_compatible_str), the name being compared, the name of the device node, and the result of the comparison (ret). Finally, the function returns the boolean result of the comparison.

Note: It is important to ensure that the device structure passed to this function is properly initialized and that the device node has a valid name. The function assumes that dev->of_node is not NULL and that the name provided in data is a valid string.

Output Example: If the name passed is "spi_device_1" and the device node's name is also "spi_device_1", the function would log a message similar to: "sdr_compatible_str custom_match_spi_dev spi_device_1 spi_device_1 1" and return 1 (true). If the names do not match, it would return 0 (false).

graph TD
    A[Start custom_match_spi_dev function] --> B[Retrieve name from data]
    B --> C[Compare name with dev's of_node name]
    C --> D{Comparison result}
    D -->|True| E[Set ret to true]
    D -->|False| F[Set ret to false]
    E --> G[Log comparison result]
    F --> G[Log comparison result]
    G --> H[Return ret]
    H --> I[End custom_match_spi_dev function]

Function custom_match_platform_dev(struct device dev, const void data)

custom_match_platform_dev: The function of custom_match_platform_dev is to determine if a given device's name matches a specified substring.

parameters: The parameters of this Function. · parameter1: struct device dev - A pointer to the device structure that is being checked for a name match. · parameter2: const void data - A pointer to the substring that is being searched for within the device's name.

Code Description: The custom_match_platform_dev function is a static function that takes two parameters: a pointer to a device structure and a pointer to a substring. It first converts the device pointer to a platform_device pointer using the to_platform_device macro. This conversion allows access to platform-specific fields within the device structure. The function then retrieves the name of the platform device and searches for the occurrence of the substring (provided in the data parameter) within this name using the strstr function. The result of this search is stored in the variable name_in_sys_bus_platform_devices, which will be non-null if the substring is found. A boolean match_flag is then set based on whether the substring was found in the device name.

If a match is found (i.e., match_flag is true), the function logs a message to the kernel log using printk, indicating that a match has occurred along with the name of the platform device. Finally, the function returns the value of match_flag, which indicates whether a match was found (1 for true, 0 for false).

Note: It is important to ensure that the data parameter passed to this function is a valid string that can be searched within the device name. Additionally, this function is intended for use in contexts where device matching is necessary, such as during device enumeration or initialization processes.

Output Example: If the platform device name is "my_platform_device" and the substring provided is "platform", the function would log the following message and return 1: "custom_match_platform_dev my_platform_device"

graph TD
    A[Start] --> B[Convert device to platform_device]
    B --> C[Extract name from data]
    C --> D[Search for name in platform_device name]
    D --> E[Check if match found]
    E -->|Yes| F[Log match information]
    E -->|No| G[Return match flag false]
    F --> H[Return match flag true]
    G --> H
    H[End]

Function openwifi_dev_probe(struct platform_device *pdev)

openwifi_dev_probe: The function of openwifi_dev_probe is to initialize and probe the OpenWiFi device, setting up necessary configurations and resources for its operation.

parameters: The parameters of this Function. · pdev: A pointer to the platform_device structure representing the device being probed.

Code Description: The openwifi_dev_probe function is responsible for initializing the OpenWiFi device driver. It begins by checking if the device tree node associated with the platform device is available. If the device tree node is present, it attempts to match it against predefined device IDs to ensure compatibility. If a match is found, the function proceeds to allocate memory for the ieee80211_hw structure, which is essential for managing the wireless device's operations.

Upon successful allocation, the function retrieves the FPGA model from the device tree and determines the type of FPGA (either LARGE_FPGA or SMALL_FPGA) based on the model name. It then initializes various parameters related to the device's operation, including the actual receive and transmit local oscillator frequencies, and attempts to find the associated ad9361-phy driver for controlling the radio frequency components.

The function continues by locating the axi_ad9361 driver for the digital-to-analog converter (DAC) and retrieves the necessary driver data. It also sets up the interface configurations for both receiving and transmitting data, based on the specified bandwidth. The function configures the device's capabilities, including supported rates and channels for both 2.4GHz and 5GHz bands.

Additionally, the function initializes various statistics structures to track the performance and status of the device. It creates sysfs entries for arbitrary IQ settings and statistics, allowing user-space applications to interact with the driver. Finally, the function registers the hardware with the ieee80211 subsystem and sets up the device's MAC address, ensuring that it is valid before proceeding.

In case of any errors during the initialization process, the function performs cleanup by freeing allocated resources and returning the appropriate error code.

Note: It is important to ensure that the device tree is correctly configured to match the expected device IDs. Any discrepancies may lead to initialization failures. Additionally, the function assumes that the ad9361-phy and axi_ad9361 drivers are available and properly configured in the system.

Output Example: A successful execution of the function would return 0, indicating that the device has been successfully probed and initialized. If an error occurs, it may return negative values such as -ENOMEM for memory allocation failures or -ENODEV if a required device cannot be found.

graph TD
    A[Start openwifi_dev_probe] --> B[Get device node from platform device]
    B --> C{Is device node valid?}
    C -- Yes --> D[Match device node with openwifi_dev_of_ids]
    D --> E{Is match found?}
    E -- Yes --> F[Set error to 0]
    E -- No --> G[Set error to 1]
    G --> H[Return error]
    F --> I[Allocate ieee80211 hardware]
    I --> J{Is allocation successful?}
    J -- No --> K[Log allocation failure]
    K --> H
    J -- Yes --> L[Initialize private structure]
    L --> M[Read FPGA model from device tree]
    M --> N{Is read successful?}
    N -- No --> O[Set FPGA type to SMALL_FPGA]
    N -- Yes --> P[Determine FPGA type based on model]
    P --> Q[Find ad9361-phy driver]
    Q --> R{Is driver found?}
    R -- No --> S[Log driver not found]
    S --> H
    R -- Yes --> T[Check driver data]
    T --> U{Is driver data valid?}
    U -- No --> V[Log driver data invalid]
    V --> H
    U -- Yes --> W[Get ad9361_phy from driver]
    W --> X[Find cf-ad9361-dds-core-lpc driver]
    X --> Y{Is driver found?}
    Y -- No --> Z[Log driver not found]
    Z --> H
    Y -- Yes --> AA[Get platform device data]
    AA --> AB{Is data valid?}
    AB -- No --> AC[Log data retrieval failure]
    AC --> H
    AB -- Yes --> AD[Get IIO private data]
    AD --> AE{Is IIO private data valid?}
    AE -- No --> AF[Log IIO data retrieval failure]
    AF --> H
    AE -- Yes --> AG[Set up DDS data selection]
    AG --> AH[Configure RF settings]
    AH --> AI[Set antenna configuration]
    AI --> AJ{Is antenna configuration successful?}
    AJ -- No --> AK[Log antenna configuration failure]
    AK --> H
    AJ -- Yes --> AL[Register hardware]
    AL --> AM{Is registration successful?}
    AM -- No --> AN[Log registration failure]
    AN --> H
    AM -- Yes --> AO[Create sysfs entries]
    AO --> AP{Are sysfs entries created successfully?}
    AP -- No --> AQ[Log sysfs creation failure]
    AQ --> H
    AP -- Yes --> AR[Initialize statistics]
    AR --> AS[Log successful probe]
    AS --> AT[Return success]
    H --> AU[End openwifi_dev_probe]
    AT --> AU

Function openwifi_dev_remove(struct platform_device *pdev)

openwifi_dev_remove: The function of openwifi_dev_remove is to cleanly remove an OpenWiFi device from the system.

parameters: The parameters of this Function. · parameter1: struct platform_device *pdev - A pointer to the platform device structure representing the OpenWiFi device to be removed.

Code Description: The openwifi_dev_remove function is responsible for performing cleanup operations when an OpenWiFi device is being removed from the system. It begins by retrieving the ieee80211_hw structure associated with the platform device using the platform_get_drvdata function. This structure contains the device's private data, which is accessed through the priv member of the ieee80211_hw structure.

The function first checks if the dev pointer is valid. If dev is NULL, it logs an informational message indicating that the device is not present and returns -1 to signal an error. This check is crucial to prevent dereferencing a NULL pointer, which would lead to undefined behavior.

If the device is valid, the function proceeds to remove various sysfs entries associated with the device. It calls sysfs_remove_bin_file to remove a binary file associated with the device's private data, and sysfs_remove_group to remove two attribute groups: tx_intf_attribute_group and stat_attribute_group. These operations ensure that the sysfs interface is cleaned up properly, preventing any lingering references to the device.

Next, the function calls openwifi_rfkill_exit to perform any necessary cleanup related to radio frequency kill switch functionality. Following this, ieee80211_unregister_hw is invoked to unregister the hardware from the IEEE 802.11 subsystem, effectively notifying the system that the device is no longer available. Finally, ieee80211_free_hw is called to free the memory allocated for the ieee80211_hw structure, completing the removal process.

The function returns 0 upon successful completion, indicating that the device has been removed cleanly without any errors.

Note: It is important to ensure that the device is properly initialized before calling this function. Additionally, any references to the device in other parts of the code should be handled appropriately to avoid accessing freed memory.

Output Example: If the device is successfully removed, the function will return 0. If the device is not present (dev is NULL), the function will return -1.

graph TD
    A[Start openwifi_dev_remove function] --> B[Get device data from platform]
    B --> C{Check if device data is valid}
    C -->|No| D[Log device data issue]
    D --> E[Return -1]
    C -->|Yes| F[Remove binary file from sysfs]
    F --> G[Remove tx interface attribute group from sysfs]
    G --> H[Remove stat attribute group from sysfs]
    H --> I[Exit RF kill for device]
    I --> J[Unregister hardware]
    J --> K[Free hardware resources]
    K --> L[Return 0]
    E --> L