int zd_mac_stop(struct net_device *netdev) { struct zd_mac *mac = zd_netdev_mac(netdev); struct zd_chip *chip = &mac->chip; netif_stop_queue(netdev); /* * The order here deliberately is a little different from the open() * method, since we need to make sure there is no opportunity for RX * frames to be processed by softmac after we have stopped it. */ zd_chip_disable_rx(chip); skb_queue_purge(&mac->rx_queue); tasklet_disable(&mac->rx_tasklet); housekeeping_disable(mac); ieee80211softmac_stop(netdev); /* Ensure no work items are running or queued from this point */ cancel_delayed_work(&mac->set_rts_cts_work); cancel_delayed_work(&mac->set_basic_rates_work); flush_workqueue(zd_workqueue); mac->updating_rts_rate = 0; mac->updating_basic_rates = 0; zd_chip_disable_hwint(chip); zd_chip_switch_radio_off(chip); zd_chip_disable_int(chip); return 0; }
static int zd_op_start(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; struct zd_usb *usb = &chip->usb; int r; if (!usb->initialized) { r = zd_usb_init_hw(usb); if (r) goto out; } r = zd_chip_enable_int(chip); if (r < 0) goto out; r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); if (r < 0) goto disable_int; r = set_rx_filter(mac); if (r) goto disable_int; r = set_mc_hash(mac); if (r) goto disable_int; r = zd_chip_switch_radio_on(chip); if (r < 0) goto disable_int; r = zd_chip_enable_rxtx(chip); if (r < 0) goto disable_radio; r = zd_chip_enable_hwint(chip); if (r < 0) goto disable_rxtx; housekeeping_enable(mac); return 0; disable_rxtx: zd_chip_disable_rxtx(chip); disable_radio: zd_chip_switch_radio_off(chip); disable_int: zd_chip_disable_int(chip); out: return r; }
int zd_mac_open(struct net_device *netdev) { struct zd_mac *mac = zd_netdev_mac(netdev); struct zd_chip *chip = &mac->chip; int r; tasklet_enable(&mac->rx_tasklet); r = zd_chip_enable_int(chip); if (r < 0) goto out; r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G); if (r < 0) goto disable_int; r = reset_mode(mac); if (r) goto disable_int; r = zd_chip_switch_radio_on(chip); if (r < 0) goto disable_int; r = zd_chip_set_channel(chip, mac->requested_channel); if (r < 0) goto disable_radio; r = zd_chip_enable_rx(chip); if (r < 0) goto disable_radio; r = zd_chip_enable_hwint(chip); if (r < 0) goto disable_rx; housekeeping_enable(mac); ieee80211softmac_start(netdev); return 0; disable_rx: zd_chip_disable_rx(chip); disable_radio: zd_chip_switch_radio_off(chip); disable_int: zd_chip_disable_int(chip); out: return r; }
static void zd_op_stop(struct ieee80211_hw *hw) { struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; struct sk_buff *skb; struct sk_buff_head *ack_wait_queue = &mac->ack_wait_queue; /* The order here deliberately is a little different from the open() * method, since we need to make sure there is no opportunity for RX * frames to be processed by mac80211 after we have stopped it. */ zd_chip_disable_rxtx(chip); housekeeping_disable(mac); flush_workqueue(zd_workqueue); zd_chip_disable_hwint(chip); zd_chip_switch_radio_off(chip); zd_chip_disable_int(chip); while ((skb = skb_dequeue(ack_wait_queue))) kfree_tx_skb(skb); }