Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef LINUX_B43_PHY_COMMON_H_
0003 #define LINUX_B43_PHY_COMMON_H_
0004 
0005 #include <linux/types.h>
0006 #include <linux/nl80211.h>
0007 
0008 struct b43_wldev;
0009 
0010 /* PHY register routing bits */
0011 #define B43_PHYROUTE            0x0C00 /* PHY register routing bits mask */
0012 #define  B43_PHYROUTE_BASE      0x0000 /* Base registers */
0013 #define  B43_PHYROUTE_OFDM_GPHY     0x0400 /* OFDM register routing for G-PHYs */
0014 #define  B43_PHYROUTE_EXT_GPHY      0x0800 /* Extended G-PHY registers */
0015 #define  B43_PHYROUTE_N_BMODE       0x0C00 /* N-PHY BMODE registers */
0016 
0017 /* CCK (B-PHY) registers. */
0018 #define B43_PHY_CCK(reg)        ((reg) | B43_PHYROUTE_BASE)
0019 /* N-PHY registers. */
0020 #define B43_PHY_N(reg)          ((reg) | B43_PHYROUTE_BASE)
0021 /* N-PHY BMODE registers. */
0022 #define B43_PHY_N_BMODE(reg)        ((reg) | B43_PHYROUTE_N_BMODE)
0023 /* OFDM (A-PHY) registers. */
0024 #define B43_PHY_OFDM(reg)       ((reg) | B43_PHYROUTE_OFDM_GPHY)
0025 /* Extended G-PHY registers. */
0026 #define B43_PHY_EXTG(reg)       ((reg) | B43_PHYROUTE_EXT_GPHY)
0027 
0028 
0029 /* Masks for the PHY versioning registers. */
0030 #define B43_PHYVER_ANALOG       0xF000
0031 #define B43_PHYVER_ANALOG_SHIFT     12
0032 #define B43_PHYVER_TYPE         0x0F00
0033 #define B43_PHYVER_TYPE_SHIFT       8
0034 #define B43_PHYVER_VERSION      0x00FF
0035 
0036 /* PHY writes need to be flushed if we reach limit */
0037 #define B43_MAX_WRITES_IN_ROW       24
0038 
0039 /**
0040  * enum b43_interference_mitigation - Interference Mitigation mode
0041  *
0042  * @B43_INTERFMODE_NONE:    Disabled
0043  * @B43_INTERFMODE_NONWLAN: Non-WLAN Interference Mitigation
0044  * @B43_INTERFMODE_MANUALWLAN:  WLAN Interference Mitigation
0045  * @B43_INTERFMODE_AUTOWLAN:    Automatic WLAN Interference Mitigation
0046  */
0047 enum b43_interference_mitigation {
0048     B43_INTERFMODE_NONE,
0049     B43_INTERFMODE_NONWLAN,
0050     B43_INTERFMODE_MANUALWLAN,
0051     B43_INTERFMODE_AUTOWLAN,
0052 };
0053 
0054 /* Antenna identifiers */
0055 enum {
0056     B43_ANTENNA0 = 0,   /* Antenna 0 */
0057     B43_ANTENNA1 = 1,   /* Antenna 1 */
0058     B43_ANTENNA_AUTO0 = 2,  /* Automatic, starting with antenna 0 */
0059     B43_ANTENNA_AUTO1 = 3,  /* Automatic, starting with antenna 1 */
0060     B43_ANTENNA2 = 4,
0061     B43_ANTENNA3 = 8,
0062 
0063     B43_ANTENNA_AUTO = B43_ANTENNA_AUTO0,
0064     B43_ANTENNA_DEFAULT = B43_ANTENNA_AUTO,
0065 };
0066 
0067 /**
0068  * enum b43_txpwr_result - Return value for the recalc_txpower PHY op.
0069  *
0070  * @B43_TXPWR_RES_NEED_ADJUST:  Values changed. Hardware adjustment is needed.
0071  * @B43_TXPWR_RES_DONE:     No more work to do. Everything is done.
0072  */
0073 enum b43_txpwr_result {
0074     B43_TXPWR_RES_NEED_ADJUST,
0075     B43_TXPWR_RES_DONE,
0076 };
0077 
0078 /**
0079  * struct b43_phy_operations - Function pointers for PHY ops.
0080  *
0081  * @allocate:       Allocate and initialise the PHY data structures.
0082  *          Must not be NULL.
0083  * @free:       Destroy and free the PHY data structures.
0084  *          Must not be NULL.
0085  *
0086  * @prepare_structs:    Prepare the PHY data structures.
0087  *          The data structures allocated in @allocate are
0088  *          initialized here.
0089  *          Must not be NULL.
0090  * @prepare_hardware:   Prepare the PHY. This is called before b43_chip_init to
0091  *          do some early PHY hardware init.
0092  *          Can be NULL, if not required.
0093  * @init:       Initialize the PHY.
0094  *          Must not be NULL.
0095  * @exit:       Shutdown the PHY.
0096  *          Can be NULL, if not required.
0097  *
0098  * @phy_read:       Read from a PHY register.
0099  *          Must not be NULL.
0100  * @phy_write:      Write to a PHY register.
0101  *          Must not be NULL.
0102  * @phy_maskset:    Maskset a PHY register, taking shortcuts.
0103  *          If it is NULL, a generic algorithm is used.
0104  * @radio_read:     Read from a Radio register.
0105  *          Must not be NULL.
0106  * @radio_write:    Write to a Radio register.
0107  *          Must not be NULL.
0108  *
0109  * @supports_hwpctl:    Returns a boolean whether Hardware Power Control
0110  *          is supported or not.
0111  *          If NULL, hwpctl is assumed to be never supported.
0112  * @software_rfkill:    Turn the radio ON or OFF.
0113  *          Possible state values are
0114  *          RFKILL_STATE_SOFT_BLOCKED or
0115  *          RFKILL_STATE_UNBLOCKED
0116  *          Must not be NULL.
0117  * @switch_analog:  Turn the Analog on/off.
0118  *          Must not be NULL.
0119  * @switch_channel: Switch the radio to another channel.
0120  *          Must not be NULL.
0121  * @get_default_chan:   Just returns the default channel number.
0122  *          Must not be NULL.
0123  * @set_rx_antenna: Set the antenna used for RX.
0124  *          Can be NULL, if not supported.
0125  * @interf_mitigation:  Switch the Interference Mitigation mode.
0126  *          Can be NULL, if not supported.
0127  *
0128  * @recalc_txpower: Recalculate the transmission power parameters.
0129  *          This callback has to recalculate the TX power settings,
0130  *          but does not need to write them to the hardware, yet.
0131  *          Returns enum b43_txpwr_result to indicate whether the hardware
0132  *          needs to be adjusted.
0133  *          If B43_TXPWR_NEED_ADJUST is returned, @adjust_txpower
0134  *          will be called later.
0135  *          If the parameter "ignore_tssi" is true, the TSSI values should
0136  *          be ignored and a recalculation of the power settings should be
0137  *          done even if the TSSI values did not change.
0138  *          This function may sleep, but should not.
0139  *          Must not be NULL.
0140  * @adjust_txpower: Write the previously calculated TX power settings
0141  *          (from @recalc_txpower) to the hardware.
0142  *          This function may sleep.
0143  *          Can be NULL, if (and ONLY if) @recalc_txpower _always_
0144  *          returns B43_TXPWR_RES_DONE.
0145  *
0146  * @pwork_15sec:    Periodic work. Called every 15 seconds.
0147  *          Can be NULL, if not required.
0148  * @pwork_60sec:    Periodic work. Called every 60 seconds.
0149  *          Can be NULL, if not required.
0150  */
0151 struct b43_phy_operations {
0152     /* Initialisation */
0153     int (*allocate)(struct b43_wldev *dev);
0154     void (*free)(struct b43_wldev *dev);
0155     void (*prepare_structs)(struct b43_wldev *dev);
0156     int (*prepare_hardware)(struct b43_wldev *dev);
0157     int (*init)(struct b43_wldev *dev);
0158     void (*exit)(struct b43_wldev *dev);
0159 
0160     /* Register access */
0161     u16 (*phy_read)(struct b43_wldev *dev, u16 reg);
0162     void (*phy_write)(struct b43_wldev *dev, u16 reg, u16 value);
0163     void (*phy_maskset)(struct b43_wldev *dev, u16 reg, u16 mask, u16 set);
0164     u16 (*radio_read)(struct b43_wldev *dev, u16 reg);
0165     void (*radio_write)(struct b43_wldev *dev, u16 reg, u16 value);
0166 
0167     /* Radio */
0168     bool (*supports_hwpctl)(struct b43_wldev *dev);
0169     void (*software_rfkill)(struct b43_wldev *dev, bool blocked);
0170     void (*switch_analog)(struct b43_wldev *dev, bool on);
0171     int (*switch_channel)(struct b43_wldev *dev, unsigned int new_channel);
0172     unsigned int (*get_default_chan)(struct b43_wldev *dev);
0173     void (*set_rx_antenna)(struct b43_wldev *dev, int antenna);
0174     int (*interf_mitigation)(struct b43_wldev *dev,
0175                  enum b43_interference_mitigation new_mode);
0176 
0177     /* Transmission power adjustment */
0178     enum b43_txpwr_result (*recalc_txpower)(struct b43_wldev *dev,
0179                         bool ignore_tssi);
0180     void (*adjust_txpower)(struct b43_wldev *dev);
0181 
0182     /* Misc */
0183     void (*pwork_15sec)(struct b43_wldev *dev);
0184     void (*pwork_60sec)(struct b43_wldev *dev);
0185 };
0186 
0187 struct b43_phy_g;
0188 struct b43_phy_n;
0189 struct b43_phy_lp;
0190 struct b43_phy_ht;
0191 struct b43_phy_lcn;
0192 
0193 struct b43_phy {
0194     /* Hardware operation callbacks. */
0195     const struct b43_phy_operations *ops;
0196 
0197     /* Most hardware context information is stored in the standard-
0198      * specific data structures pointed to by the pointers below.
0199      * Only one of them is valid (the currently enabled PHY). */
0200 #ifdef CONFIG_B43_DEBUG
0201     /* No union for debug build to force NULL derefs in buggy code. */
0202     struct {
0203 #else
0204     union {
0205 #endif
0206         /* G-PHY specific information */
0207         struct b43_phy_g *g;
0208         /* N-PHY specific information */
0209         struct b43_phy_n *n;
0210         /* LP-PHY specific information */
0211         struct b43_phy_lp *lp;
0212         /* HT-PHY specific information */
0213         struct b43_phy_ht *ht;
0214         /* LCN-PHY specific information */
0215         struct b43_phy_lcn *lcn;
0216         /* AC-PHY specific information */
0217         struct b43_phy_ac *ac;
0218     };
0219 
0220     /* Band support flags. */
0221     bool supports_2ghz;
0222     bool supports_5ghz;
0223 
0224     /* Is GMODE (2 GHz mode) bit enabled? */
0225     bool gmode;
0226 
0227     /* After power reset full init has to be performed */
0228     bool do_full_init;
0229 
0230     /* Analog Type */
0231     u8 analog;
0232     /* B43_PHYTYPE_ */
0233     u8 type;
0234     /* PHY revision number. */
0235     u8 rev;
0236 
0237     /* Count writes since last read */
0238     u8 writes_counter;
0239 
0240     /* Radio versioning */
0241     u16 radio_manuf;    /* Radio manufacturer */
0242     u16 radio_ver;      /* Radio version */
0243     u8 radio_rev;       /* Radio revision */
0244 
0245     /* Software state of the radio */
0246     bool radio_on;
0247 
0248     /* Desired TX power level (in dBm).
0249      * This is set by the user and adjusted in b43_phy_xmitpower(). */
0250     int desired_txpower;
0251 
0252     /* Hardware Power Control enabled? */
0253     bool hardware_power_control;
0254 
0255     /* The time (in absolute jiffies) when the next TX power output
0256      * check is needed. */
0257     unsigned long next_txpwr_check_time;
0258 
0259     /* Current channel */
0260     struct cfg80211_chan_def *chandef;
0261     unsigned int channel;
0262 
0263     /* PHY TX errors counter. */
0264     atomic_t txerr_cnt;
0265 
0266 #ifdef CONFIG_B43_DEBUG
0267     /* PHY registers locked (w.r.t. firmware) */
0268     bool phy_locked;
0269     /* Radio registers locked (w.r.t. firmware) */
0270     bool radio_locked;
0271 #endif /* B43_DEBUG */
0272 };
0273 
0274 
0275 /**
0276  * b43_phy_allocate - Allocate PHY structs
0277  * Allocate the PHY data structures, based on the current dev->phy.type
0278  */
0279 int b43_phy_allocate(struct b43_wldev *dev);
0280 
0281 /**
0282  * b43_phy_free - Free PHY structs
0283  */
0284 void b43_phy_free(struct b43_wldev *dev);
0285 
0286 /**
0287  * b43_phy_init - Initialise the PHY
0288  */
0289 int b43_phy_init(struct b43_wldev *dev);
0290 
0291 /**
0292  * b43_phy_exit - Cleanup PHY
0293  */
0294 void b43_phy_exit(struct b43_wldev *dev);
0295 
0296 /**
0297  * b43_has_hardware_pctl - Hardware Power Control supported?
0298  * Returns a boolean, whether hardware power control is supported.
0299  */
0300 bool b43_has_hardware_pctl(struct b43_wldev *dev);
0301 
0302 /**
0303  * b43_phy_read - 16bit PHY register read access
0304  */
0305 u16 b43_phy_read(struct b43_wldev *dev, u16 reg);
0306 
0307 /**
0308  * b43_phy_write - 16bit PHY register write access
0309  */
0310 void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value);
0311 
0312 /**
0313  * b43_phy_copy - copy contents of 16bit PHY register to another
0314  */
0315 void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg);
0316 
0317 /**
0318  * b43_phy_mask - Mask a PHY register with a mask
0319  */
0320 void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
0321 
0322 /**
0323  * b43_phy_set - OR a PHY register with a bitmap
0324  */
0325 void b43_phy_set(struct b43_wldev *dev, u16 offset, u16 set);
0326 
0327 /**
0328  * b43_phy_maskset - Mask and OR a PHY register with a mask and bitmap
0329  */
0330 void b43_phy_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
0331 
0332 /**
0333  * b43_radio_read - 16bit Radio register read access
0334  */
0335 u16 b43_radio_read(struct b43_wldev *dev, u16 reg);
0336 #define b43_radio_read16    b43_radio_read /* DEPRECATED */
0337 
0338 /**
0339  * b43_radio_write - 16bit Radio register write access
0340  */
0341 void b43_radio_write(struct b43_wldev *dev, u16 reg, u16 value);
0342 #define b43_radio_write16   b43_radio_write /* DEPRECATED */
0343 
0344 /**
0345  * b43_radio_mask - Mask a 16bit radio register with a mask
0346  */
0347 void b43_radio_mask(struct b43_wldev *dev, u16 offset, u16 mask);
0348 
0349 /**
0350  * b43_radio_set - OR a 16bit radio register with a bitmap
0351  */
0352 void b43_radio_set(struct b43_wldev *dev, u16 offset, u16 set);
0353 
0354 /**
0355  * b43_radio_maskset - Mask and OR a radio register with a mask and bitmap
0356  */
0357 void b43_radio_maskset(struct b43_wldev *dev, u16 offset, u16 mask, u16 set);
0358 
0359 /**
0360  * b43_radio_wait_value - Waits for a given value in masked register read
0361  */
0362 bool b43_radio_wait_value(struct b43_wldev *dev, u16 offset, u16 mask,
0363               u16 value, int delay, int timeout);
0364 
0365 /**
0366  * b43_radio_lock - Lock firmware radio register access
0367  */
0368 void b43_radio_lock(struct b43_wldev *dev);
0369 
0370 /**
0371  * b43_radio_unlock - Unlock firmware radio register access
0372  */
0373 void b43_radio_unlock(struct b43_wldev *dev);
0374 
0375 /**
0376  * b43_phy_lock - Lock firmware PHY register access
0377  */
0378 void b43_phy_lock(struct b43_wldev *dev);
0379 
0380 /**
0381  * b43_phy_unlock - Unlock firmware PHY register access
0382  */
0383 void b43_phy_unlock(struct b43_wldev *dev);
0384 
0385 void b43_phy_put_into_reset(struct b43_wldev *dev);
0386 void b43_phy_take_out_of_reset(struct b43_wldev *dev);
0387 
0388 /**
0389  * b43_switch_channel - Switch to another channel
0390  */
0391 int b43_switch_channel(struct b43_wldev *dev, unsigned int new_channel);
0392 
0393 /**
0394  * b43_software_rfkill - Turn the radio ON or OFF in software.
0395  */
0396 void b43_software_rfkill(struct b43_wldev *dev, bool blocked);
0397 
0398 /**
0399  * b43_phy_txpower_check - Check TX power output.
0400  *
0401  * Compare the current TX power output to the desired power emission
0402  * and schedule an adjustment in case it mismatches.
0403  *
0404  * @flags:  OR'ed enum b43_phy_txpower_check_flags flags.
0405  *      See the docs below.
0406  */
0407 void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags);
0408 /**
0409  * enum b43_phy_txpower_check_flags - Flags for b43_phy_txpower_check()
0410  *
0411  * @B43_TXPWR_IGNORE_TIME: Ignore the schedule time and force-redo
0412  *                         the check now.
0413  * @B43_TXPWR_IGNORE_TSSI: Redo the recalculation, even if the average
0414  *                         TSSI did not change.
0415  */
0416 enum b43_phy_txpower_check_flags {
0417     B43_TXPWR_IGNORE_TIME       = (1 << 0),
0418     B43_TXPWR_IGNORE_TSSI       = (1 << 1),
0419 };
0420 
0421 struct work_struct;
0422 void b43_phy_txpower_adjust_work(struct work_struct *work);
0423 
0424 /**
0425  * b43_phy_shm_tssi_read - Read the average of the last 4 TSSI from SHM.
0426  *
0427  * @shm_offset:     The SHM address to read the values from.
0428  *
0429  * Returns the average of the 4 TSSI values, or a negative error code.
0430  */
0431 int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset);
0432 
0433 /**
0434  * b43_phy_switch_analog_generic - Generic PHY operation for switching the Analog.
0435  *
0436  * It does the switching based on the PHY0 core register.
0437  * Do _not_ call this directly. Only use it as a switch_analog callback
0438  * for struct b43_phy_operations.
0439  */
0440 void b43_phyop_switch_analog_generic(struct b43_wldev *dev, bool on);
0441 
0442 bool b43_is_40mhz(struct b43_wldev *dev);
0443 
0444 void b43_phy_force_clock(struct b43_wldev *dev, bool force);
0445 
0446 #endif /* LINUX_B43_PHY_COMMON_H_ */