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; }
int zd_mac_init_hw(struct zd_mac *mac, u8 device_type) { int r; struct zd_chip *chip = &mac->chip; u8 addr[ETH_ALEN]; u8 default_regdomain; r = zd_chip_enable_int(chip); if (r) goto out; r = zd_chip_init_hw(chip, device_type); if (r) goto disable_int; zd_get_e2p_mac_addr(chip, addr); r = zd_write_mac_addr(chip, addr); if (r) goto disable_int; ZD_ASSERT(!irqs_disabled()); spin_lock_irq(&mac->lock); memcpy(mac->netdev->dev_addr, addr, ETH_ALEN); spin_unlock_irq(&mac->lock); r = zd_read_regdomain(chip, &default_regdomain); if (r) goto disable_int; if (!zd_regdomain_supported(default_regdomain)) { dev_dbg_f(zd_mac_dev(mac), "Regulatory Domain %#04x is not supported.\n", default_regdomain); r = -EINVAL; goto disable_int; } spin_lock_irq(&mac->lock); mac->regdomain = mac->default_regdomain = default_regdomain; spin_unlock_irq(&mac->lock); r = reset_channel(mac); if (r) goto disable_int; /* We must inform the device that we are doing encryption/decryption in * software at the moment. */ r = zd_set_encryption_type(chip, ENC_SNIFFER); if (r) goto disable_int; r = zd_geo_init(zd_mac_to_ieee80211(mac), mac->regdomain); if (r) goto disable_int; r = 0; disable_int: zd_chip_disable_int(chip); out: return r; }
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; }
int zd_mac_init_hw(struct ieee80211_hw *hw) { int r; struct zd_mac *mac = zd_hw_mac(hw); struct zd_chip *chip = &mac->chip; u8 default_regdomain; r = zd_chip_enable_int(chip); if (r) goto out; r = zd_chip_init_hw(chip); if (r) goto disable_int; ZD_ASSERT(!irqs_disabled()); r = zd_read_regdomain(chip, &default_regdomain); if (r) goto disable_int; spin_lock_irq(&mac->lock); mac->regdomain = mac->default_regdomain = default_regdomain; spin_unlock_irq(&mac->lock); /* We must inform the device that we are doing encryption/decryption in * software at the moment. */ r = zd_set_encryption_type(chip, ENC_SNIFFER); if (r) goto disable_int; zd_geo_init(hw, mac->regdomain); r = 0; 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); }