|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* |
| 3 | + * Copyright (c) 2021 pureLiFi |
| 4 | + */ |
| 5 | + |
| 6 | +#include <linux/kernel.h> |
| 7 | +#include <linux/errno.h> |
| 8 | + |
| 9 | +#include "chip.h" |
| 10 | +#include "mac.h" |
| 11 | +#include "usb.h" |
| 12 | + |
| 13 | +void plfxlc_chip_init(struct plfxlc_chip *chip, |
| 14 | + struct ieee80211_hw *hw, |
| 15 | + struct usb_interface *intf) |
| 16 | +{ |
| 17 | + memset(chip, 0, sizeof(*chip)); |
| 18 | + mutex_init(&chip->mutex); |
| 19 | + plfxlc_usb_init(&chip->usb, hw, intf); |
| 20 | +} |
| 21 | + |
| 22 | +void plfxlc_chip_release(struct plfxlc_chip *chip) |
| 23 | +{ |
| 24 | + plfxlc_usb_release(&chip->usb); |
| 25 | + mutex_destroy(&chip->mutex); |
| 26 | +} |
| 27 | + |
| 28 | +int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval, |
| 29 | + u8 dtim_period, int type) |
| 30 | +{ |
| 31 | + if (!interval || |
| 32 | + (chip->beacon_set && |
| 33 | + le16_to_cpu(chip->beacon_interval) == interval)) |
| 34 | + return 0; |
| 35 | + |
| 36 | + chip->beacon_interval = cpu_to_le16(interval); |
| 37 | + chip->beacon_set = true; |
| 38 | + return plfxlc_usb_wreq(chip->usb.ez_usb, |
| 39 | + &chip->beacon_interval, |
| 40 | + sizeof(chip->beacon_interval), |
| 41 | + USB_REQ_BEACON_INTERVAL_WR); |
| 42 | +} |
| 43 | + |
| 44 | +int plfxlc_chip_init_hw(struct plfxlc_chip *chip) |
| 45 | +{ |
| 46 | + unsigned char *addr = plfxlc_mac_get_perm_addr(plfxlc_chip_to_mac(chip)); |
| 47 | + struct usb_device *udev = interface_to_usbdev(chip->usb.intf); |
| 48 | + |
| 49 | + pr_info("plfxlc chip %04x:%04x v%02x %pM %s\n", |
| 50 | + le16_to_cpu(udev->descriptor.idVendor), |
| 51 | + le16_to_cpu(udev->descriptor.idProduct), |
| 52 | + le16_to_cpu(udev->descriptor.bcdDevice), |
| 53 | + addr, |
| 54 | + plfxlc_speed(udev->speed)); |
| 55 | + |
| 56 | + return plfxlc_set_beacon_interval(chip, 100, 0, 0); |
| 57 | +} |
| 58 | + |
| 59 | +int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value) |
| 60 | +{ |
| 61 | + int r; |
| 62 | + __le16 radio_on = cpu_to_le16(value); |
| 63 | + |
| 64 | + r = plfxlc_usb_wreq(chip->usb.ez_usb, &radio_on, |
| 65 | + sizeof(value), USB_REQ_POWER_WR); |
| 66 | + if (r) |
| 67 | + dev_err(plfxlc_chip_dev(chip), "POWER_WR failed (%d)\n", r); |
| 68 | + return r; |
| 69 | +} |
| 70 | + |
| 71 | +int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip) |
| 72 | +{ |
| 73 | + plfxlc_usb_enable_tx(&chip->usb); |
| 74 | + return plfxlc_usb_enable_rx(&chip->usb); |
| 75 | +} |
| 76 | + |
| 77 | +void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip) |
| 78 | +{ |
| 79 | + u8 value = 0; |
| 80 | + |
| 81 | + plfxlc_usb_wreq(chip->usb.ez_usb, |
| 82 | + &value, sizeof(value), USB_REQ_RXTX_WR); |
| 83 | + plfxlc_usb_disable_rx(&chip->usb); |
| 84 | + plfxlc_usb_disable_tx(&chip->usb); |
| 85 | +} |
| 86 | + |
| 87 | +int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate) |
| 88 | +{ |
| 89 | + int r; |
| 90 | + |
| 91 | + if (!chip) |
| 92 | + return -EINVAL; |
| 93 | + |
| 94 | + r = plfxlc_usb_wreq(chip->usb.ez_usb, |
| 95 | + &rate, sizeof(rate), USB_REQ_RATE_WR); |
| 96 | + if (r) |
| 97 | + dev_err(plfxlc_chip_dev(chip), "RATE_WR failed (%d)\n", r); |
| 98 | + return r; |
| 99 | +} |
0 commit comments