162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (c) 2021 pureLiFi 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include <linux/kernel.h> 762306a36Sopenharmony_ci#include <linux/errno.h> 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include "chip.h" 1062306a36Sopenharmony_ci#include "mac.h" 1162306a36Sopenharmony_ci#include "usb.h" 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_civoid plfxlc_chip_init(struct plfxlc_chip *chip, 1462306a36Sopenharmony_ci struct ieee80211_hw *hw, 1562306a36Sopenharmony_ci struct usb_interface *intf) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci memset(chip, 0, sizeof(*chip)); 1862306a36Sopenharmony_ci mutex_init(&chip->mutex); 1962306a36Sopenharmony_ci plfxlc_usb_init(&chip->usb, hw, intf); 2062306a36Sopenharmony_ci} 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_civoid plfxlc_chip_release(struct plfxlc_chip *chip) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci plfxlc_usb_release(&chip->usb); 2562306a36Sopenharmony_ci mutex_destroy(&chip->mutex); 2662306a36Sopenharmony_ci} 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ciint plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval, 2962306a36Sopenharmony_ci u8 dtim_period, int type) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci if (!interval || 3262306a36Sopenharmony_ci (chip->beacon_set && chip->beacon_interval == interval)) 3362306a36Sopenharmony_ci return 0; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci chip->beacon_interval = interval; 3662306a36Sopenharmony_ci chip->beacon_set = true; 3762306a36Sopenharmony_ci return plfxlc_usb_wreq(chip->usb.ez_usb, 3862306a36Sopenharmony_ci &chip->beacon_interval, 3962306a36Sopenharmony_ci sizeof(chip->beacon_interval), 4062306a36Sopenharmony_ci USB_REQ_BEACON_INTERVAL_WR); 4162306a36Sopenharmony_ci} 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ciint plfxlc_chip_init_hw(struct plfxlc_chip *chip) 4462306a36Sopenharmony_ci{ 4562306a36Sopenharmony_ci unsigned char *addr = plfxlc_mac_get_perm_addr(plfxlc_chip_to_mac(chip)); 4662306a36Sopenharmony_ci struct usb_device *udev = interface_to_usbdev(chip->usb.intf); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci pr_info("plfxlc chip %04x:%04x v%02x %pM %s\n", 4962306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.idVendor), 5062306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.idProduct), 5162306a36Sopenharmony_ci le16_to_cpu(udev->descriptor.bcdDevice), 5262306a36Sopenharmony_ci addr, 5362306a36Sopenharmony_ci plfxlc_speed(udev->speed)); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return plfxlc_set_beacon_interval(chip, 100, 0, 0); 5662306a36Sopenharmony_ci} 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ciint plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value) 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci int r; 6162306a36Sopenharmony_ci __le16 radio_on = cpu_to_le16(value); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci r = plfxlc_usb_wreq(chip->usb.ez_usb, &radio_on, 6462306a36Sopenharmony_ci sizeof(value), USB_REQ_POWER_WR); 6562306a36Sopenharmony_ci if (r) 6662306a36Sopenharmony_ci dev_err(plfxlc_chip_dev(chip), "POWER_WR failed (%d)\n", r); 6762306a36Sopenharmony_ci return r; 6862306a36Sopenharmony_ci} 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ciint plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip) 7162306a36Sopenharmony_ci{ 7262306a36Sopenharmony_ci plfxlc_usb_enable_tx(&chip->usb); 7362306a36Sopenharmony_ci return plfxlc_usb_enable_rx(&chip->usb); 7462306a36Sopenharmony_ci} 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_civoid plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip) 7762306a36Sopenharmony_ci{ 7862306a36Sopenharmony_ci u8 value = 0; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci plfxlc_usb_wreq(chip->usb.ez_usb, 8162306a36Sopenharmony_ci &value, sizeof(value), USB_REQ_RXTX_WR); 8262306a36Sopenharmony_ci plfxlc_usb_disable_rx(&chip->usb); 8362306a36Sopenharmony_ci plfxlc_usb_disable_tx(&chip->usb); 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ciint plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci int r; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci if (!chip) 9162306a36Sopenharmony_ci return -EINVAL; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci r = plfxlc_usb_wreq(chip->usb.ez_usb, 9462306a36Sopenharmony_ci &rate, sizeof(rate), USB_REQ_RATE_WR); 9562306a36Sopenharmony_ci if (r) 9662306a36Sopenharmony_ci dev_err(plfxlc_chip_dev(chip), "RATE_WR failed (%d)\n", r); 9762306a36Sopenharmony_ci return r; 9862306a36Sopenharmony_ci} 99