Wednesday, July 25, 2012

What is softc in the networking driver?

Softc is a misc state maintained in a device driver. You are likely to come across this term when reading some structure definition. For example: ath_softc is used in the ath9k  wireless driver.

Under the NetBSD model and most Linux systems, a softc based structure should contain the first element as the device for which this state is maintained. For example in the ath_softc structure the first element is the
struct ieee80211_hw *hw for which the state is maintained. Some functions which use this structure:

int ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
void ath_flushrecv(struct ath_softc *sc);
u32 ath_calcrxfilter(struct ath_softc *sc);
int ath_rx_init(struct ath_softc *sc, int nbufs);
void ath_rx_cleanup(struct ath_softc *sc);
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp);

The ath_softc structure in the wireless driver defined in the file ath.h looks like this:

struct ath_softc {
    struct ieee80211_hw *hw;
    struct device *dev;

    struct survey_info *cur_survey;
    struct survey_info survey[ATH9K_NUM_CHANNELS];

    struct tasklet_struct intr_tq;
    struct tasklet_struct bcon_tasklet;
    struct ath_hw *sc_ah;
    void __iomem *mem;
    int irq;
    spinlock_t sc_serial_rw;
    spinlock_t sc_pm_lock;
    spinlock_t sc_pcu_lock;
    struct mutex mutex;
    struct work_struct paprd_work;
    struct work_struct hw_check_work;
    struct work_struct hw_reset_work;
    struct completion paprd_complete;

    unsigned int hw_busy_count;

    u32 intrstatus;
    u32 sc_flags; /* SC_OP_* */
    u16 ps_flags; /* PS_* */
    u16 curtxpow;
    bool ps_enabled;
    bool ps_idle;
    short nbcnvifs;
    short nvifs;
    unsigned long ps_usecount;

    struct ath_config config;
    struct ath_rx rx;
    struct ath_tx tx;
    struct ath_beacon beacon;
    struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];

#ifdef CONFIG_MAC80211_LEDS
    bool led_registered;
    char led_name[32];
    struct led_classdev led_cdev;
#endif

    struct ath9k_hw_cal_data caldata;
    int last_rssi;

#ifdef CONFIG_ATH9K_DEBUGFS
    struct ath9k_debug debug;
    spinlock_t nodes_lock;
    struct list_head nodes; /* basically, stations */
    unsigned int tx_complete_poll_work_seen;
#endif
    struct ath_beacon_config cur_beacon_conf;
    struct delayed_work tx_complete_work;
    struct delayed_work hw_pll_work;
    struct timer_list rx_poll_timer;

#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
    struct ath_btcoex btcoex;
    struct ath_mci_coex mci_coex;
#endif

    struct ath_descdma txsdma;

    struct ath_ant_comb ant_comb;
    u8 ant_tx, ant_rx;
    struct dfs_pattern_detector *dfs_detector;
};


One other interesting tidbit:

 - "How exactly is it supposed to be allocated?"

 A - Under new config NetBSD ports (all but hp300), storage
     for the softc is automatically dynamically allocated by
     the MI autoconfiguration code (see subr_autoconf.c) when
     a device is found (probe/match returned non-0).

     Under the NetBSD model, the generic device structure is
     tightly coupled with a device's softc.  Every device on
     the system has a "struct device" associated with it.
     Most devices on the system also have a softc (some drivers
     are so simple, they just don't need any extra state
     information).

0 comments:

Post a Comment