xref: /linux/drivers/net/wireless/purelifi/plfxlc/chip.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
168d57a07SSrinivasan Raju // SPDX-License-Identifier: GPL-2.0-only
268d57a07SSrinivasan Raju /*
368d57a07SSrinivasan Raju  * Copyright (c) 2021 pureLiFi
468d57a07SSrinivasan Raju  */
568d57a07SSrinivasan Raju 
668d57a07SSrinivasan Raju #include <linux/kernel.h>
768d57a07SSrinivasan Raju #include <linux/errno.h>
868d57a07SSrinivasan Raju 
968d57a07SSrinivasan Raju #include "chip.h"
1068d57a07SSrinivasan Raju #include "mac.h"
1168d57a07SSrinivasan Raju #include "usb.h"
1268d57a07SSrinivasan Raju 
plfxlc_chip_init(struct plfxlc_chip * chip,struct ieee80211_hw * hw,struct usb_interface * intf)1368d57a07SSrinivasan Raju void plfxlc_chip_init(struct plfxlc_chip *chip,
1468d57a07SSrinivasan Raju 		      struct ieee80211_hw *hw,
1568d57a07SSrinivasan Raju 		      struct usb_interface *intf)
1668d57a07SSrinivasan Raju {
1768d57a07SSrinivasan Raju 	memset(chip, 0, sizeof(*chip));
1868d57a07SSrinivasan Raju 	mutex_init(&chip->mutex);
1968d57a07SSrinivasan Raju 	plfxlc_usb_init(&chip->usb, hw, intf);
2068d57a07SSrinivasan Raju }
2168d57a07SSrinivasan Raju 
plfxlc_chip_release(struct plfxlc_chip * chip)2268d57a07SSrinivasan Raju void plfxlc_chip_release(struct plfxlc_chip *chip)
2368d57a07SSrinivasan Raju {
2468d57a07SSrinivasan Raju 	plfxlc_usb_release(&chip->usb);
2568d57a07SSrinivasan Raju 	mutex_destroy(&chip->mutex);
2668d57a07SSrinivasan Raju }
2768d57a07SSrinivasan Raju 
plfxlc_set_beacon_interval(struct plfxlc_chip * chip,u16 interval,u8 dtim_period,int type)2868d57a07SSrinivasan Raju int plfxlc_set_beacon_interval(struct plfxlc_chip *chip, u16 interval,
2968d57a07SSrinivasan Raju 			       u8 dtim_period, int type)
3068d57a07SSrinivasan Raju {
3168d57a07SSrinivasan Raju 	if (!interval ||
32*ccc915e7SSrinivasan Raju 	    (chip->beacon_set && chip->beacon_interval == interval))
3368d57a07SSrinivasan Raju 		return 0;
3468d57a07SSrinivasan Raju 
35*ccc915e7SSrinivasan Raju 	chip->beacon_interval = interval;
3668d57a07SSrinivasan Raju 	chip->beacon_set = true;
3768d57a07SSrinivasan Raju 	return plfxlc_usb_wreq(chip->usb.ez_usb,
3868d57a07SSrinivasan Raju 			       &chip->beacon_interval,
3968d57a07SSrinivasan Raju 			       sizeof(chip->beacon_interval),
4068d57a07SSrinivasan Raju 			       USB_REQ_BEACON_INTERVAL_WR);
4168d57a07SSrinivasan Raju }
4268d57a07SSrinivasan Raju 
plfxlc_chip_init_hw(struct plfxlc_chip * chip)4368d57a07SSrinivasan Raju int plfxlc_chip_init_hw(struct plfxlc_chip *chip)
4468d57a07SSrinivasan Raju {
4568d57a07SSrinivasan Raju 	unsigned char *addr = plfxlc_mac_get_perm_addr(plfxlc_chip_to_mac(chip));
4668d57a07SSrinivasan Raju 	struct usb_device *udev = interface_to_usbdev(chip->usb.intf);
4768d57a07SSrinivasan Raju 
4868d57a07SSrinivasan Raju 	pr_info("plfxlc chip %04x:%04x v%02x %pM %s\n",
4968d57a07SSrinivasan Raju 		le16_to_cpu(udev->descriptor.idVendor),
5068d57a07SSrinivasan Raju 		le16_to_cpu(udev->descriptor.idProduct),
5168d57a07SSrinivasan Raju 		le16_to_cpu(udev->descriptor.bcdDevice),
5268d57a07SSrinivasan Raju 		addr,
5368d57a07SSrinivasan Raju 		plfxlc_speed(udev->speed));
5468d57a07SSrinivasan Raju 
5568d57a07SSrinivasan Raju 	return plfxlc_set_beacon_interval(chip, 100, 0, 0);
5668d57a07SSrinivasan Raju }
5768d57a07SSrinivasan Raju 
plfxlc_chip_switch_radio(struct plfxlc_chip * chip,u16 value)5868d57a07SSrinivasan Raju int plfxlc_chip_switch_radio(struct plfxlc_chip *chip, u16 value)
5968d57a07SSrinivasan Raju {
6068d57a07SSrinivasan Raju 	int r;
6168d57a07SSrinivasan Raju 	__le16 radio_on = cpu_to_le16(value);
6268d57a07SSrinivasan Raju 
6368d57a07SSrinivasan Raju 	r = plfxlc_usb_wreq(chip->usb.ez_usb, &radio_on,
6468d57a07SSrinivasan Raju 			    sizeof(value), USB_REQ_POWER_WR);
6568d57a07SSrinivasan Raju 	if (r)
6668d57a07SSrinivasan Raju 		dev_err(plfxlc_chip_dev(chip), "POWER_WR failed (%d)\n", r);
6768d57a07SSrinivasan Raju 	return r;
6868d57a07SSrinivasan Raju }
6968d57a07SSrinivasan Raju 
plfxlc_chip_enable_rxtx(struct plfxlc_chip * chip)7068d57a07SSrinivasan Raju int plfxlc_chip_enable_rxtx(struct plfxlc_chip *chip)
7168d57a07SSrinivasan Raju {
7268d57a07SSrinivasan Raju 	plfxlc_usb_enable_tx(&chip->usb);
7368d57a07SSrinivasan Raju 	return plfxlc_usb_enable_rx(&chip->usb);
7468d57a07SSrinivasan Raju }
7568d57a07SSrinivasan Raju 
plfxlc_chip_disable_rxtx(struct plfxlc_chip * chip)7668d57a07SSrinivasan Raju void plfxlc_chip_disable_rxtx(struct plfxlc_chip *chip)
7768d57a07SSrinivasan Raju {
7868d57a07SSrinivasan Raju 	u8 value = 0;
7968d57a07SSrinivasan Raju 
8068d57a07SSrinivasan Raju 	plfxlc_usb_wreq(chip->usb.ez_usb,
8168d57a07SSrinivasan Raju 			&value, sizeof(value), USB_REQ_RXTX_WR);
8268d57a07SSrinivasan Raju 	plfxlc_usb_disable_rx(&chip->usb);
8368d57a07SSrinivasan Raju 	plfxlc_usb_disable_tx(&chip->usb);
8468d57a07SSrinivasan Raju }
8568d57a07SSrinivasan Raju 
plfxlc_chip_set_rate(struct plfxlc_chip * chip,u8 rate)8668d57a07SSrinivasan Raju int plfxlc_chip_set_rate(struct plfxlc_chip *chip, u8 rate)
8768d57a07SSrinivasan Raju {
8868d57a07SSrinivasan Raju 	int r;
8968d57a07SSrinivasan Raju 
9068d57a07SSrinivasan Raju 	if (!chip)
9168d57a07SSrinivasan Raju 		return -EINVAL;
9268d57a07SSrinivasan Raju 
9368d57a07SSrinivasan Raju 	r = plfxlc_usb_wreq(chip->usb.ez_usb,
9468d57a07SSrinivasan Raju 			    &rate, sizeof(rate), USB_REQ_RATE_WR);
9568d57a07SSrinivasan Raju 	if (r)
9668d57a07SSrinivasan Raju 		dev_err(plfxlc_chip_dev(chip), "RATE_WR failed (%d)\n", r);
9768d57a07SSrinivasan Raju 	return r;
9868d57a07SSrinivasan Raju }
99