Lines Matching +full:modem +full:- +full:init
1 // SPDX-License-Identifier: GPL-2.0+
3 * cxacru.c - driver for USB ADSL modems based on
32 #define DRIVER_DESC "Conexant AccessRunner ADSL USB modem driver"
40 #define CMD_MAX_CONFIG ((CMD_PACKET_SIZE / 4 - 1) / 2)
57 /* commands for interaction with the modem through the control channel before
69 /* commands for interaction with the modem through the control channel once
215 return -ENODEV; \
217 return cxacru_sysfs_showattr_##_type(instance->card_info[_value], buf); \
247 value = -value; in cxacru_sysfs_showattr_dB()
248 return snprintf(buf, PAGE_SIZE, "-%u.%02u\n", in cxacru_sysfs_showattr_dB()
287 "ITU-T G.992.1 (G.DMT)", in cxacru_sysfs_showattr_MODU()
288 "ITU-T G.992.2 (G.LITE)" in cxacru_sysfs_showattr_MODU()
301 * Where 00-55 are bytes 0-5 of the MAC.
309 if (instance == NULL || instance->usbatm->atm_dev == NULL) in mac_address_show()
310 return -ENODEV; in mac_address_show()
312 return sprintf(buf, "%pM\n", instance->usbatm->atm_dev->esi); in mac_address_show()
324 return -ENODEV; in adsl_state_show()
326 value = instance->card_info[CXINF_LINE_STARTABLE]; in adsl_state_show()
338 int poll = -1; in adsl_state_store()
343 return -EACCES; in adsl_state_store()
347 return -EINVAL; in adsl_state_store()
351 return -ENODEV; in adsl_state_store()
353 if (mutex_lock_interruptible(&instance->adsl_state_serialize)) in adsl_state_store()
354 return -ERESTARTSYS; in adsl_state_store()
359 atm_err(instance->usbatm, "change adsl state:" in adsl_state_store()
362 ret = -EIO; in adsl_state_store()
379 atm_err(instance->usbatm, "change adsl state:" in adsl_state_store()
382 ret = -EIO; in adsl_state_store()
395 ret = -EINVAL; in adsl_state_store()
396 poll = -1; in adsl_state_store()
400 mutex_lock(&instance->poll_state_serialize); in adsl_state_store()
401 switch (instance->poll_state) { in adsl_state_store()
404 instance->poll_state = CXPOLL_POLLING; in adsl_state_store()
409 instance->poll_state = CXPOLL_POLLING; in adsl_state_store()
414 poll = -1; in adsl_state_store()
416 mutex_unlock(&instance->poll_state_serialize); in adsl_state_store()
418 mutex_lock(&instance->poll_state_serialize); in adsl_state_store()
420 if (instance->poll_state == CXPOLL_POLLING) in adsl_state_store()
421 instance->poll_state = CXPOLL_STOPPING; in adsl_state_store()
422 mutex_unlock(&instance->poll_state_serialize); in adsl_state_store()
425 mutex_unlock(&instance->adsl_state_serialize); in adsl_state_store()
428 cxacru_poll_status(&instance->poll_work.work); in adsl_state_store()
445 return -EACCES; in adsl_config_store()
448 return -ENODEV; in adsl_config_store()
459 return -EINVAL; in adsl_config_store()
461 return -EINVAL; in adsl_config_store()
462 if (tmp < 0 || tmp > len - pos) in adsl_config_store()
463 return -EINVAL; in adsl_config_store()
467 if (buf[pos] == '\n' && pos == len-1) in adsl_config_store()
484 atm_err(instance->usbatm, in adsl_config_store()
486 return -EIO; in adsl_config_store()
493 atm_info(instance->usbatm, "config%s\n", log); in adsl_config_store()
504 * INIT (define the device attributes)
539 CXACRU_ALL_FILES(INIT);
575 complete(urb->context); in cxacru_blocking_completion()
587 usb_unlink_urb(timer->urb); in cxacru_timeout_kill()
604 *actual_length = urb->actual_length; in cxacru_start_wait_urb()
605 return urb->status; /* must read status after completion */ in cxacru_start_wait_urb()
613 const int stride = CMD_PACKET_SIZE - 4; in cxacru_cm()
614 u8 *wbuf = instance->snd_buf; in cxacru_cm()
615 u8 *rbuf = instance->rcv_buf; in cxacru_cm()
616 int wbuflen = ((wsize - 1) / stride + 1) * CMD_PACKET_SIZE; in cxacru_cm()
617 int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; in cxacru_cm()
621 usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", in cxacru_cm()
623 ret = -ENOMEM; in cxacru_cm()
627 mutex_lock(&instance->cm_serialize); in cxacru_cm()
630 init_completion(&instance->rcv_done); in cxacru_cm()
631 ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); in cxacru_cm()
634 usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n", in cxacru_cm()
644 memcpy(wbuf + offb + 4, wdata + offd, min_t(int, stride, wsize - offd)); in cxacru_cm()
647 instance->snd_urb->transfer_buffer_length = wbuflen; in cxacru_cm()
648 init_completion(&instance->snd_done); in cxacru_cm()
649 ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); in cxacru_cm()
652 usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n", in cxacru_cm()
657 ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); in cxacru_cm()
660 usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret); in cxacru_cm()
664 ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); in cxacru_cm()
667 usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret); in cxacru_cm()
672 usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n", in cxacru_cm()
674 ret = -EIO; in cxacru_cm()
682 usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n", in cxacru_cm()
684 ret = -EIO; in cxacru_cm()
689 usb_err(instance->usbatm, "response to cm %#x failed: %#x\n", in cxacru_cm()
691 ret = -EIO; in cxacru_cm()
696 memcpy(rdata + offd, rbuf + offb + 4, min_t(int, stride, rsize - offd)); in cxacru_cm()
701 usb_dbg(instance->usbatm, "cm %#x\n", cm); in cxacru_cm()
703 mutex_unlock(&instance->cm_serialize); in cxacru_cm()
715 const int stride = CMD_PACKET_SIZE / (4 * 2) - 1; in cxacru_cm_get_array()
716 int buflen = ((size - 1) / stride + 1 + size * 2) * 4; in cxacru_cm_get_array()
720 return -ENOMEM; in cxacru_cm_get_array()
731 if (l < 0 || l > stride || l > (len - offb) / 2) { in cxacru_cm_get_array()
733 usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", in cxacru_cm_get_array()
735 ret = -EIO; in cxacru_cm_get_array()
738 while (l--) { in cxacru_cm_get_array()
742 usb_err(instance->usbatm, "wrong index %#x in response to cm %#x\n", in cxacru_cm_get_array()
744 ret = -EIO; in cxacru_cm_get_array()
763 usb_dbg(instance->usbatm, "cxacru_adsl_start: CARD_GET_STATUS returned %d\n", ret); in cxacru_card_status()
772 struct cxacru_data *instance = usbatm_instance->driver_data; in cxacru_atm_start()
773 struct usb_interface *intf = usbatm_instance->usb_intf; in cxacru_atm_start()
777 dev_dbg(&intf->dev, "%s\n", __func__); in cxacru_atm_start()
781 atm_dev->esi, sizeof(atm_dev->esi)); in cxacru_atm_start()
788 mutex_lock(&instance->adsl_state_serialize); in cxacru_atm_start()
794 mutex_lock(&instance->poll_state_serialize); in cxacru_atm_start()
795 switch (instance->poll_state) { in cxacru_atm_start()
798 instance->poll_state = CXPOLL_POLLING; in cxacru_atm_start()
803 instance->poll_state = CXPOLL_POLLING; in cxacru_atm_start()
810 mutex_unlock(&instance->poll_state_serialize); in cxacru_atm_start()
811 mutex_unlock(&instance->adsl_state_serialize); in cxacru_atm_start()
814 cxacru_poll_status(&instance->poll_work.work); in cxacru_atm_start()
823 struct usbatm_data *usbatm = instance->usbatm; in cxacru_poll_status()
824 struct atm_dev *atm_dev = usbatm->atm_dev; in cxacru_poll_status()
830 if (ret != -ESHUTDOWN) in cxacru_poll_status()
833 mutex_lock(&instance->poll_state_serialize); in cxacru_poll_status()
834 if (instance->poll_state != CXPOLL_SHUTDOWN) { in cxacru_poll_status()
835 instance->poll_state = CXPOLL_STOPPED; in cxacru_poll_status()
837 if (ret != -ESHUTDOWN) in cxacru_poll_status()
841 mutex_unlock(&instance->poll_state_serialize); in cxacru_poll_status()
845 memcpy(instance->card_info, buf, sizeof(instance->card_info)); in cxacru_poll_status()
847 if (instance->adsl_status != buf[CXINF_LINE_STARTABLE]) { in cxacru_poll_status()
848 instance->adsl_status = buf[CXINF_LINE_STARTABLE]; in cxacru_poll_status()
850 switch (instance->adsl_status) { in cxacru_poll_status()
860 atm_info(usbatm, "Unknown adsl status %02x\n", instance->adsl_status); in cxacru_poll_status()
865 if (instance->line_status == buf[CXINF_LINE_STATUS]) in cxacru_poll_status()
868 instance->line_status = buf[CXINF_LINE_STATUS]; in cxacru_poll_status()
869 switch (instance->line_status) { in cxacru_poll_status()
896 atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; in cxacru_poll_status()
915 atm_info(usbatm, "Unknown line state %02x\n", instance->line_status); in cxacru_poll_status()
920 mutex_lock(&instance->poll_state_serialize); in cxacru_poll_status()
921 if (instance->poll_state == CXPOLL_STOPPING && in cxacru_poll_status()
922 instance->adsl_status == 1 && /* stopped */ in cxacru_poll_status()
923 instance->line_status == 0) /* down */ in cxacru_poll_status()
924 instance->poll_state = CXPOLL_STOPPED; in cxacru_poll_status()
926 if (instance->poll_state == CXPOLL_STOPPED) in cxacru_poll_status()
928 mutex_unlock(&instance->poll_state_serialize); in cxacru_poll_status()
931 schedule_delayed_work(&instance->poll_work, in cxacru_poll_status()
941 const int stride = CMD_PACKET_SIZE - 8; in cxacru_fw()
945 return -ENOMEM; in cxacru_fw()
949 int l = min_t(int, stride, size - offd); in cxacru_fw()
961 memset(buf + offb + l, 0, stride - l); in cxacru_fw()
968 dev_dbg(&usb_dev->dev, "sending fw %#x failed\n", fw); in cxacru_fw()
974 dev_dbg(&usb_dev->dev, "sent fw %#x\n", fw); in cxacru_fw()
988 struct usbatm_data *usbatm = instance->usbatm; in cxacru_upload_firmware()
989 struct usb_device *usb_dev = usbatm->usb_dev; in cxacru_upload_firmware()
990 __le16 signature[] = { usb_dev->descriptor.idVendor, in cxacru_upload_firmware()
991 usb_dev->descriptor.idProduct }; in cxacru_upload_firmware()
997 val = cpu_to_le32(instance->modem_type->pll_f_clk); in cxacru_upload_firmware()
1005 val = cpu_to_le32(instance->modem_type->pll_b_clk); in cxacru_upload_firmware()
1022 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size); in cxacru_upload_firmware()
1029 if (instance->modem_type->boot_rom_patch) { in cxacru_upload_firmware()
1031 ret = cxacru_fw(usb_dev, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, bp->data, bp->size); in cxacru_upload_firmware()
1046 if (instance->modem_type->boot_rom_patch) { in cxacru_upload_firmware()
1067 usb_err(usbatm, "modem failed to initialize: %d\n", ret); in cxacru_upload_firmware()
1075 struct usbatm_data *usbatm = instance->usbatm; in cxacru_find_firmware()
1076 struct device *dev = &usbatm->usb_intf->dev; in cxacru_find_firmware()
1079 sprintf(buf, "cxacru-%s.bin", phase); in cxacru_find_firmware()
1084 return -ENOENT; in cxacru_find_firmware()
1096 struct cxacru_data *instance = usbatm_instance->driver_data; in cxacru_heavy_init()
1100 usb_warn(usbatm_instance, "firmware (cxacru-fw.bin) unavailable (system misconfigured?)\n"); in cxacru_heavy_init()
1104 if (instance->modem_type->boot_rom_patch) { in cxacru_heavy_init()
1107 … usb_warn(usbatm_instance, "boot ROM patch (cxacru-bp.bin) unavailable (system misconfigured?)\n"); in cxacru_heavy_init()
1115 if (instance->modem_type->boot_rom_patch) in cxacru_heavy_init()
1121 usb_dbg(usbatm_instance, "modem initialisation failed\n"); in cxacru_heavy_init()
1123 usb_dbg(usbatm_instance, "done setting up the modem\n"); in cxacru_heavy_init()
1133 struct usb_host_endpoint *cmd_ep = usb_dev->ep_in[CXACRU_EP_CMD]; in cxacru_bind()
1136 /* instance init */ in cxacru_bind()
1139 return -ENOMEM; in cxacru_bind()
1141 instance->usbatm = usbatm_instance; in cxacru_bind()
1142 instance->modem_type = (struct cxacru_modem_type *) id->driver_info; in cxacru_bind()
1144 mutex_init(&instance->poll_state_serialize); in cxacru_bind()
1145 instance->poll_state = CXPOLL_STOPPED; in cxacru_bind()
1146 instance->line_status = -1; in cxacru_bind()
1147 instance->adsl_status = -1; in cxacru_bind()
1149 mutex_init(&instance->adsl_state_serialize); in cxacru_bind()
1151 instance->rcv_buf = (u8 *) __get_free_page(GFP_KERNEL); in cxacru_bind()
1152 if (!instance->rcv_buf) { in cxacru_bind()
1154 ret = -ENOMEM; in cxacru_bind()
1157 instance->snd_buf = (u8 *) __get_free_page(GFP_KERNEL); in cxacru_bind()
1158 if (!instance->snd_buf) { in cxacru_bind()
1160 ret = -ENOMEM; in cxacru_bind()
1163 instance->rcv_urb = usb_alloc_urb(0, GFP_KERNEL); in cxacru_bind()
1164 if (!instance->rcv_urb) { in cxacru_bind()
1165 ret = -ENOMEM; in cxacru_bind()
1168 instance->snd_urb = usb_alloc_urb(0, GFP_KERNEL); in cxacru_bind()
1169 if (!instance->snd_urb) { in cxacru_bind()
1170 ret = -ENOMEM; in cxacru_bind()
1176 ret = -ENODEV; in cxacru_bind()
1180 if ((cmd_ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) in cxacru_bind()
1182 usb_fill_int_urb(instance->rcv_urb, in cxacru_bind()
1184 instance->rcv_buf, PAGE_SIZE, in cxacru_bind()
1185 cxacru_blocking_completion, &instance->rcv_done, 1); in cxacru_bind()
1187 usb_fill_int_urb(instance->snd_urb, in cxacru_bind()
1189 instance->snd_buf, PAGE_SIZE, in cxacru_bind()
1190 cxacru_blocking_completion, &instance->snd_done, 4); in cxacru_bind()
1192 usb_fill_bulk_urb(instance->rcv_urb, in cxacru_bind()
1194 instance->rcv_buf, PAGE_SIZE, in cxacru_bind()
1195 cxacru_blocking_completion, &instance->rcv_done); in cxacru_bind()
1197 usb_fill_bulk_urb(instance->snd_urb, in cxacru_bind()
1199 instance->snd_buf, PAGE_SIZE, in cxacru_bind()
1200 cxacru_blocking_completion, &instance->snd_done); in cxacru_bind()
1203 mutex_init(&instance->cm_serialize); in cxacru_bind()
1205 INIT_DELAYED_WORK(&instance->poll_work, cxacru_poll_status); in cxacru_bind()
1207 usbatm_instance->driver_data = instance; in cxacru_bind()
1209 usbatm_instance->flags = (cxacru_card_status(instance) ? 0 : UDSL_SKIP_HEAVY_INIT); in cxacru_bind()
1214 free_page((unsigned long) instance->snd_buf); in cxacru_bind()
1215 free_page((unsigned long) instance->rcv_buf); in cxacru_bind()
1216 usb_free_urb(instance->snd_urb); in cxacru_bind()
1217 usb_free_urb(instance->rcv_urb); in cxacru_bind()
1226 struct cxacru_data *instance = usbatm_instance->driver_data; in cxacru_unbind()
1236 mutex_lock(&instance->poll_state_serialize); in cxacru_unbind()
1237 BUG_ON(instance->poll_state == CXPOLL_SHUTDOWN); in cxacru_unbind()
1241 if (instance->poll_state == CXPOLL_STOPPED) in cxacru_unbind()
1245 instance->poll_state = CXPOLL_SHUTDOWN; in cxacru_unbind()
1246 mutex_unlock(&instance->poll_state_serialize); in cxacru_unbind()
1249 cancel_delayed_work_sync(&instance->poll_work); in cxacru_unbind()
1251 usb_kill_urb(instance->snd_urb); in cxacru_unbind()
1252 usb_kill_urb(instance->rcv_urb); in cxacru_unbind()
1253 usb_free_urb(instance->snd_urb); in cxacru_unbind()
1254 usb_free_urb(instance->rcv_urb); in cxacru_unbind()
1256 free_page((unsigned long) instance->snd_buf); in cxacru_unbind()
1257 free_page((unsigned long) instance->rcv_buf); in cxacru_unbind()
1261 usbatm_instance->driver_data = NULL; in cxacru_unbind()
1277 { /* V = Conexant P = ADSL modem (Euphrates project) */
1280 { /* V = Conexant P = ADSL modem (Hasbani project) */
1283 { /* V = Conexant P = ADSL modem */
1286 { /* V = Conexant P = ADSL modem (Well PTI-800) */
1289 { /* V = Conexant P = ADSL modem */
1292 { /* V = Conexant P = ADSL modem (ZTE ZXDSL 852) */
1295 { /* V = Olitec P = ADSL modem version 2 */
1298 { /* V = Olitec P = ADSL modem version 3 */
1301 { /* V = Trust/Amigo Technology Co. P = AMX-CA86U */
1310 { /* V = Zyxel P = 630-C1 aka OMNI ADSL USB (Annex A) */
1313 { /* V = Zyxel P = 630-C3 aka OMNI ADSL USB (Annex B) */
1319 { /* V = Aztech Systems P = ? AKA Pirelli AUA-010 */
1354 if (usb_dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC in cxacru_usb_probe()
1355 && usb_string(usb_dev, usb_dev->descriptor.iProduct, in cxacru_usb_probe()
1358 dev_info(&intf->dev, "ignoring cx82310_eth device\n"); in cxacru_usb_probe()
1359 return -ENODEV; in cxacru_usb_probe()