From f7519d8c8290765a9408a52db4ba4a368ff72ca5 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 22:54:18 +0100 Subject: ARM: OMAP1: ams-delta: register latch dependent devices later In preparation to converting Amstrad Delta on-board latches to basic_mmio_gpio devices, registration of platform devices which depend on latches and will require initialization of their GPIO pins first, should be moved out of .machine_init down to late_initcall level, as the gpio-generic driver is not available until device_initcall time. The latch reset operation, which will be replaced with GPIO initialization, must also be moved to late_initcall for the same reason. Since there was already another, separate arch_initcall function for setting up one of those latch dependent devices, the on-board modem device, reuse that function, i.e., rename it to a name that matches the new purpose, extend with other device setup relocated from .machine_init, and move down to the late_initcall level. While being at it, add missing gpio_free() in case the modem platform device registration fails. Thanks to Tony Lindgren who suggested this approach instead of shifting up the gpio-generic driver initialization. In addition, defer registration of the Amstrad Delta ASoC and serio devices, done from their device driver files, until late_initcall time, as those drivers will depend on their GPIO pins already requested from the board late_init() function until updated to register their GPIO pins themselves. Signed-off-by: Janusz Krzysztofik Acked-by: Mark Brown Signed-off-by: Tony Lindgren --- drivers/input/serio/ams_delta_serio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index d4d08bd9205..835d37abe62 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -165,7 +165,7 @@ serio: kfree(ams_delta_serio); return err; } -module_init(ams_delta_serio_init); +late_initcall(ams_delta_serio_init); static void __exit ams_delta_serio_exit(void) { -- cgit v1.2.3-70-g09d2 From ea9da1c79eb9a28176550d0b8ba9166e6e5f42b8 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:44 -0800 Subject: UAS: Re-add workqueue items if submission fails. If the original submission (or allocation) of the URBs for a SCSI command fails, the UAS driver sticks the command structure in a workqueue and schedules uas_do_work() to run. That function removes the entire queue before walking across it and attempting to resubmit. Unfortunately, if the second submission fails, we will leak memory (because an allocated URB was not submitted) and possibly leave the SCSI command partially enqueued on some of the stream rings. Fix this by checking whether the second submission failed and re-queueing the command to the UAS workqueue and scheduling it. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 1d10d5b8204..4bbaf6e150e 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -125,29 +125,38 @@ struct uas_cmd_info { /* I hate forward declarations, but I actually have a loop */ static int uas_submit_urbs(struct scsi_cmnd *cmnd, struct uas_dev_info *devinfo, gfp_t gfp); +static void uas_do_work(struct work_struct *work); +static DECLARE_WORK(uas_work, uas_do_work); static DEFINE_SPINLOCK(uas_work_lock); static LIST_HEAD(uas_work_list); static void uas_do_work(struct work_struct *work) { struct uas_cmd_info *cmdinfo; + struct uas_cmd_info *temp; struct list_head list; + int err; spin_lock_irq(&uas_work_lock); list_replace_init(&uas_work_list, &list); spin_unlock_irq(&uas_work_lock); - list_for_each_entry(cmdinfo, &list, list) { + list_for_each_entry_safe(cmdinfo, temp, &list, list) { struct scsi_pointer *scp = (void *)cmdinfo; struct scsi_cmnd *cmnd = container_of(scp, struct scsi_cmnd, SCp); - uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); + err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO); + if (err) { + list_del(&cmdinfo->list); + spin_lock_irq(&uas_work_lock); + list_add_tail(&cmdinfo->list, &uas_work_list); + spin_unlock_irq(&uas_work_lock); + schedule_work(&uas_work); + } } } -static DECLARE_WORK(uas_work, uas_do_work); - static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; -- cgit v1.2.3-70-g09d2 From 9eb445410db99e5f5f660e97a2165a0567bd909e Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:46 -0800 Subject: UAS: Use unique tags on non-streams devices. UAS can work with either USB 3.0 devices that support bulk streams, or USB 2.0 devices that do not support bulk streams. When we're working with a non-streams device, we need to be able to uniquely identify a SCSI command with a tag in the IU. Devices will barf and abort all queued commands if they find a duplicate tag. uas_queuecommand_lck() sets cmdinfo->stream to zero if the device doesn't support streams, which is later passed into uas_alloc_cmd_urb() as the variable stream. This means the UAS driver was setting the tag in all commands to zero for non-stream devices. So the UAS driver won't currently work with USB 2.0 devices. Use the SCSI command tag instead of the stream ID for the command IU tag. We have to add one to the SCSI command tag because SCSI tags are zero-based, but stream IDs are one-based, and the command tag must match the stream ID that we're queueing the data IUs for. Untagged SCSI commands use stream ID 1. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 4bbaf6e150e..28d9b190938 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -343,7 +343,10 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; iu->iu_id = IU_ID_COMMAND; - iu->tag = cpu_to_be16(stream_id); + if (blk_rq_tagged(cmnd->request)) + iu->tag = cpu_to_be16(cmnd->request->tag + 1); + else + iu->tag = cpu_to_be16(1); iu->prio_attr = UAS_SIMPLE_TAG; iu->len = len; int_to_scsilun(sdev->lun, &iu->lun); -- cgit v1.2.3-70-g09d2 From 96c1eb9873caffc507a1951c36b43fdcf3ddeff3 Mon Sep 17 00:00:00 2001 From: Sarah Sharp Date: Fri, 2 Dec 2011 11:55:48 -0800 Subject: UAS: Free status URB when we can't find the SCSI tag. In the UAS status URB completion handler, we need to free the URB, no matter what happens. Fix a bug where we would leak the URB (and its buffer) if we couldn't find a SCSI command that is associated with this status phase. Signed-off-by: Sarah Sharp Cc: Matthew Wilcox Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 28d9b190938..9dd4aaee85c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -246,8 +246,10 @@ static void uas_stat_cmplt(struct urb *urb) cmnd = sdev->current_cmnd; else cmnd = scsi_find_tag(sdev, tag); - if (!cmnd) + if (!cmnd) { + usb_free_urb(urb); return; + } switch (iu->iu_id) { case IU_ID_STATUS: -- cgit v1.2.3-70-g09d2 From dae51546b6564b06cbae4191d4f2dee7136be3c1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 19 Dec 2011 17:06:08 +0100 Subject: usb/uas: use unique tags for all LUNs I observed that on a device with multiple LUNs UAS was re-using the same tag number for requests which were issued at the same time to both LUNs. This patch uses scsi_init_shared_tag_map() to use unique tags for all LUNs. With this patch I haven't seen the same tag number during the init sequence anymore. Tag 1 is used for devices which do not adverise command queueing. This patch initilizes the queue before adding the scsi host like the other two user in tree. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 9dd4aaee85c..6974f4bed2f 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -684,6 +684,17 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } +static void uas_free_streams(struct uas_dev_info *devinfo) +{ + struct usb_device *udev = devinfo->udev; + struct usb_host_endpoint *eps[3]; + + eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); + eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); + eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); + usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL); +} + /* * XXX: What I'd like to do here is register a SCSI host for each USB host in * the system. Follow usb-storage's design of registering a SCSI host for @@ -713,18 +724,26 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->max_id = 1; shost->sg_tablesize = udev->bus->sg_tablesize; - result = scsi_add_host(shost, &intf->dev); - if (result) - goto free; - shost->hostdata[0] = (unsigned long)devinfo; - devinfo->intf = intf; devinfo->udev = udev; uas_configure_endpoints(devinfo); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); + if (result) + goto free; + + result = scsi_add_host(shost, &intf->dev); + if (result) + goto deconfig_eps; + + shost->hostdata[0] = (unsigned long)devinfo; + scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; + +deconfig_eps: + uas_free_streams(devinfo); free: kfree(devinfo); if (shost) @@ -746,18 +765,11 @@ static int uas_post_reset(struct usb_interface *intf) static void uas_disconnect(struct usb_interface *intf) { - struct usb_device *udev = interface_to_usbdev(intf); - struct usb_host_endpoint *eps[3]; struct Scsi_Host *shost = usb_get_intfdata(intf); struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); - - eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe); - eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe); - eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe); - usb_free_streams(intf, eps, 3, GFP_KERNEL); - + uas_free_streams(devinfo); kfree(devinfo); } -- cgit v1.2.3-70-g09d2 From 22188f4a933c6e86ac67f52028895c795896492e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 19 Dec 2011 20:22:39 +0100 Subject: usb/uas: use scsi_host_find_tag() to find command from a tag In "usb/uas: use unique tags for all LUNs" we make sure to create unique tags across all LUNs. This patch uses scsi_host_find_tag() to obtain the correct command which is associated with the tag. The following changes are required: - don't use sdev->current_cmnd anymore Since we can have devices which don't support command queueing we must ensure that we can tell the two commands apart. Even if a device supports comand queuing we send the INQUIRY command "untagged" for LUN1 while we can send a tagged command to LUN0 at the same time. devinfo->cmnd is used for stashing the one "untagged" command. - tag number is altered. If stream support is used then the tag number must match the stream number. Therefore we can't use tag 0 and must start at tag 1. In case we have untagged commands (at least the first command) we must be able to distinguish between command tag 0 (which becomes 1) and untagged command (which becomes curently also 1). The following tag numbers are used: 0: never 1: for untagged commands (devinfo->cmnd) 2+: tagged commands. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 6974f4bed2f..e2386e8c767 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -98,6 +98,7 @@ struct uas_dev_info { unsigned cmd_pipe, status_pipe, data_in_pipe, data_out_pipe; unsigned use_streams:1; unsigned uas_sense_old:1; + struct scsi_cmnd *cmnd; }; enum { @@ -178,8 +179,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (sdev->current_cmnd) - sdev->current_cmnd = NULL; cmnd->scsi_done(cmnd); usb_free_urb(urb); } @@ -205,8 +204,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - if (sdev->current_cmnd) - sdev->current_cmnd = NULL; cmnd->scsi_done(cmnd); usb_free_urb(urb); } @@ -230,8 +227,8 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, static void uas_stat_cmplt(struct urb *urb) { struct iu *iu = urb->transfer_buffer; - struct scsi_device *sdev = urb->context; - struct uas_dev_info *devinfo = sdev->hostdata; + struct Scsi_Host *shost = urb->context; + struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; u16 tag; @@ -242,10 +239,10 @@ static void uas_stat_cmplt(struct urb *urb) } tag = be16_to_cpup(&iu->tag) - 1; - if (sdev->current_cmnd) - cmnd = sdev->current_cmnd; + if (tag == 0) + cmnd = devinfo->cmnd; else - cmnd = scsi_find_tag(sdev, tag); + cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { usb_free_urb(urb); return; @@ -253,6 +250,9 @@ static void uas_stat_cmplt(struct urb *urb) switch (iu->iu_id) { case IU_ID_STATUS: + if (devinfo->cmnd == cmnd) + devinfo->cmnd = NULL; + if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -314,7 +314,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, cmnd->device); + uas_stat_cmplt, cmnd->device->host); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -346,7 +346,7 @@ static struct urb *uas_alloc_cmd_urb(struct uas_dev_info *devinfo, gfp_t gfp, iu->iu_id = IU_ID_COMMAND; if (blk_rq_tagged(cmnd->request)) - iu->tag = cpu_to_be16(cmnd->request->tag + 1); + iu->tag = cpu_to_be16(cmnd->request->tag + 2); else iu->tag = cpu_to_be16(1); iu->prio_attr = UAS_SIMPLE_TAG; @@ -458,13 +458,13 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, BUILD_BUG_ON(sizeof(struct uas_cmd_info) > sizeof(struct scsi_pointer)); - if (!cmdinfo->status_urb && sdev->current_cmnd) + if (devinfo->cmnd) return SCSI_MLQUEUE_DEVICE_BUSY; if (blk_rq_tagged(cmnd->request)) { - cmdinfo->stream = cmnd->request->tag + 1; + cmdinfo->stream = cmnd->request->tag + 2; } else { - sdev->current_cmnd = cmnd; + devinfo->cmnd = cmnd; cmdinfo->stream = 1; } @@ -565,7 +565,7 @@ static int uas_slave_configure(struct scsi_device *sdev) { struct uas_dev_info *devinfo = sdev->hostdata; scsi_set_tag_type(sdev, MSG_ORDERED_TAG); - scsi_activate_tcq(sdev, devinfo->qdepth - 1); + scsi_activate_tcq(sdev, devinfo->qdepth - 2); return 0; } @@ -633,6 +633,7 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) unsigned i, n_endpoints = intf->cur_altsetting->desc.bNumEndpoints; devinfo->uas_sense_old = 0; + devinfo->cmnd = NULL; for (i = 0; i < n_endpoints; i++) { unsigned char *extra = endpoint[i].extra; @@ -728,7 +729,7 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) devinfo->udev = udev; uas_configure_endpoints(devinfo); - result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 1); + result = scsi_init_shared_tag_map(shost, devinfo->qdepth - 2); if (result) goto free; -- cgit v1.2.3-70-g09d2 From ceb3f91fd53c9fbd7b292fc2754ba4efffeeeedb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Tue, 20 Dec 2011 14:50:26 +0100 Subject: usb/uas: one only one status URB/host on stream-less connection The status/sense URB is allocated on per-command basis. A read/write looks the following way on a stream-less connection: - send cmd tag X, queue status - receive status, oh it is a read for tag X. queue status & read - receive read - receive status, oh I'm done for tag X. Cool call complete and free status urb. This block repeats itself 1:1 for further commands and looks great so far. Lets take a look now what happens if we do allow multiple commands: - send cmd tag X, queue statusX (belongs to the command with the X tag) - send cmd tag Y, queue statusY (belongs to the command with the Y tag) - receive statusX, oh it is a read for tag X. queue statusX & a read - receive read - receive statusY, oh I'm done for tag X. Cool call complete and free statusY. - receive statusX, oh it is a read for tag Y. queue statusY & before we queue the read the the following message can be observed: |sd 0:0:0:0: [sda] sense urb submission failure followed by a second attempt with the same result. In order to address this problem we will use only one status URB for each scsi host in case we don't have stream support (as suggested by Matthew). This URB is requeued until the device removed. Nothing changes on stream based endpoints. Signed-off-by: Sebastian Andrzej Siewior --- drivers/usb/storage/uas.c | 70 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e2386e8c767..036e9690095 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -99,6 +99,7 @@ struct uas_dev_info { unsigned use_streams:1; unsigned uas_sense_old:1; struct scsi_cmnd *cmnd; + struct urb *status_urb; /* used only if stream support is available */ }; enum { @@ -117,6 +118,7 @@ struct uas_cmd_info { unsigned int state; unsigned int stream; struct urb *cmd_urb; + /* status_urb is used only if stream support isn't available */ struct urb *status_urb; struct urb *data_in_urb; struct urb *data_out_urb; @@ -180,7 +182,6 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) @@ -205,7 +206,6 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) cmnd->result = sense_iu->status; cmnd->scsi_done(cmnd); - usb_free_urb(urb); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -214,7 +214,7 @@ static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; int err; - cmdinfo->state = direction | SUBMIT_STATUS_URB; + cmdinfo->state = direction; err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC); if (err) { spin_lock(&uas_work_lock); @@ -231,10 +231,12 @@ static void uas_stat_cmplt(struct urb *urb) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; u16 tag; + int ret; if (urb->status) { dev_err(&urb->dev->dev, "URB BAD STATUS %d\n", urb->status); - usb_free_urb(urb); + if (devinfo->use_streams) + usb_free_urb(urb); return; } @@ -244,7 +246,13 @@ static void uas_stat_cmplt(struct urb *urb) else cmnd = scsi_host_find_tag(shost, tag - 1); if (!cmnd) { - usb_free_urb(urb); + if (devinfo->use_streams) { + usb_free_urb(urb); + return; + } + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } @@ -270,6 +278,15 @@ static void uas_stat_cmplt(struct urb *urb) scmd_printk(KERN_ERR, cmnd, "Bogus IU (%d) received on status pipe\n", iu->iu_id); } + + if (devinfo->use_streams) { + usb_free_urb(urb); + return; + } + + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret) + dev_err(&urb->dev->dev, "failed submit status urb\n"); } static void uas_data_cmplt(struct urb *urb) @@ -300,7 +317,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, } static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, - struct scsi_cmnd *cmnd, u16 stream_id) + struct Scsi_Host *shost, u16 stream_id) { struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); @@ -314,7 +331,7 @@ static struct urb *uas_alloc_sense_urb(struct uas_dev_info *devinfo, gfp_t gfp, goto free; usb_fill_bulk_urb(urb, udev, devinfo->status_pipe, iu, sizeof(*iu), - uas_stat_cmplt, cmnd->device->host); + uas_stat_cmplt, shost); urb->stream_id = stream_id; urb->transfer_flags |= URB_FREE_BUFFER; out: @@ -376,8 +393,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (cmdinfo->state & ALLOC_STATUS_URB) { - cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, cmnd, - cmdinfo->stream); + cmdinfo->status_urb = uas_alloc_sense_urb(devinfo, gfp, + cmnd->device->host, cmdinfo->stream); if (!cmdinfo->status_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_STATUS_URB; @@ -486,7 +503,8 @@ static int uas_queuecommand_lck(struct scsi_cmnd *cmnd, } if (!devinfo->use_streams) { - cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB); + cmdinfo->state &= ~(SUBMIT_DATA_IN_URB | SUBMIT_DATA_OUT_URB | + ALLOC_STATUS_URB | SUBMIT_STATUS_URB); cmdinfo->stream = 0; } @@ -685,6 +703,29 @@ static void uas_configure_endpoints(struct uas_dev_info *devinfo) } } +static int uas_alloc_status_urb(struct uas_dev_info *devinfo, + struct Scsi_Host *shost) +{ + if (devinfo->use_streams) { + devinfo->status_urb = NULL; + return 0; + } + + devinfo->status_urb = uas_alloc_sense_urb(devinfo, GFP_KERNEL, + shost, 0); + if (!devinfo->status_urb) + goto err_s_urb; + + if (usb_submit_urb(devinfo->status_urb, GFP_KERNEL)) + goto err_submit_urb; + + return 0; +err_submit_urb: + usb_free_urb(devinfo->status_urb); +err_s_urb: + return -ENOMEM; +} + static void uas_free_streams(struct uas_dev_info *devinfo) { struct usb_device *udev = devinfo->udev; @@ -739,10 +780,17 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id) shost->hostdata[0] = (unsigned long)devinfo; + result = uas_alloc_status_urb(devinfo, shost); + if (result) + goto err_alloc_status; + scsi_scan_host(shost); usb_set_intfdata(intf, shost); return result; +err_alloc_status: + scsi_remove_host(shost); + shost = NULL; deconfig_eps: uas_free_streams(devinfo); free: @@ -770,6 +818,8 @@ static void uas_disconnect(struct usb_interface *intf) struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; scsi_remove_host(shost); + usb_kill_urb(devinfo->status_urb); + usb_free_urb(devinfo->status_urb); uas_free_streams(devinfo); kfree(devinfo); } -- cgit v1.2.3-70-g09d2 From f6fc8a6a1a08e520ae58b9abd54152aa101af14a Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 00:08:54 +0100 Subject: LED: drop leds-ams-delta driver This driver is no longer needed after the Amstrad Delta on-board LED devices have been converted to leds-gpio compatible. Signed-off-by: Janusz Krzysztofik Cc: Richard Purdie Signed-off-by: Tony Lindgren --- drivers/leds/Kconfig | 7 --- drivers/leds/Makefile | 1 - drivers/leds/leds-ams-delta.c | 137 ------------------------------------------ 3 files changed, 145 deletions(-) delete mode 100644 drivers/leds/leds-ams-delta.c (limited to 'drivers') diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index ff203a42186..352374630c1 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -74,13 +74,6 @@ config LEDS_S3C24XX This option enables support for LEDs connected to GPIO lines on Samsung S3C24XX series CPUs, such as the S3C2410 and S3C2440. -config LEDS_AMS_DELTA - tristate "LED Support for the Amstrad Delta (E3)" - depends on LEDS_CLASS - depends on MACH_AMS_DELTA - help - This option enables support for the LEDs on Amstrad Delta (E3). - config LEDS_NET48XX tristate "LED Support for Soekris net48xx series Error LED" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index e4f6bf56888..f2b75b2c2ee 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_LEDS_LOCOMO) += leds-locomo.o obj-$(CONFIG_LEDS_LM3530) += leds-lm3530.o obj-$(CONFIG_LEDS_MIKROTIK_RB532) += leds-rb532.o obj-$(CONFIG_LEDS_S3C24XX) += leds-s3c24xx.o -obj-$(CONFIG_LEDS_AMS_DELTA) += leds-ams-delta.o obj-$(CONFIG_LEDS_NET48XX) += leds-net48xx.o obj-$(CONFIG_LEDS_NET5501) += leds-net5501.o obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o diff --git a/drivers/leds/leds-ams-delta.c b/drivers/leds/leds-ams-delta.c deleted file mode 100644 index 8c00937bf7e..00000000000 --- a/drivers/leds/leds-ams-delta.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * LEDs driver for Amstrad Delta (E3) - * - * Copyright (C) 2006 Jonathan McDowell - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -/* - * Our context - */ -struct ams_delta_led { - struct led_classdev cdev; - u8 bitmask; -}; - -static void ams_delta_led_set(struct led_classdev *led_cdev, - enum led_brightness value) -{ - struct ams_delta_led *led_dev = - container_of(led_cdev, struct ams_delta_led, cdev); - - if (value) - ams_delta_latch1_write(led_dev->bitmask, led_dev->bitmask); - else - ams_delta_latch1_write(led_dev->bitmask, 0); -} - -static struct ams_delta_led ams_delta_leds[] = { - { - .cdev = { - .name = "ams-delta::camera", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_CAMERA, - }, - { - .cdev = { - .name = "ams-delta::advert", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_ADVERT, - }, - { - .cdev = { - .name = "ams-delta::email", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_EMAIL, - }, - { - .cdev = { - .name = "ams-delta::handsfree", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_HANDSFREE, - }, - { - .cdev = { - .name = "ams-delta::voicemail", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_VOICEMAIL, - }, - { - .cdev = { - .name = "ams-delta::voice", - .brightness_set = ams_delta_led_set, - }, - .bitmask = AMS_DELTA_LATCH1_LED_VOICE, - }, -}; - -static int ams_delta_led_probe(struct platform_device *pdev) -{ - int i, ret; - - for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) { - ams_delta_leds[i].cdev.flags |= LED_CORE_SUSPENDRESUME; - ret = led_classdev_register(&pdev->dev, - &ams_delta_leds[i].cdev); - if (ret < 0) - goto fail; - } - - return 0; -fail: - while (--i >= 0) - led_classdev_unregister(&ams_delta_leds[i].cdev); - return ret; -} - -static int ams_delta_led_remove(struct platform_device *pdev) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(ams_delta_leds); i++) - led_classdev_unregister(&ams_delta_leds[i].cdev); - - return 0; -} - -static struct platform_driver ams_delta_led_driver = { - .probe = ams_delta_led_probe, - .remove = ams_delta_led_remove, - .driver = { - .name = "ams-delta-led", - .owner = THIS_MODULE, - }, -}; - -static int __init ams_delta_led_init(void) -{ - return platform_driver_register(&ams_delta_led_driver); -} - -static void __exit ams_delta_led_exit(void) -{ - platform_driver_unregister(&ams_delta_led_driver); -} - -module_init(ams_delta_led_init); -module_exit(ams_delta_led_exit); - -MODULE_AUTHOR("Jonathan McDowell "); -MODULE_DESCRIPTION("Amstrad Delta LED driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ams-delta-led"); -- cgit v1.2.3-70-g09d2 From 68f0676699fb0e0b18feb8459c35ecdfe3127b3d Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 00:08:55 +0100 Subject: MTD: NAND: ams-delta: use GPIO instead of custom I/O Don't use Amstrad Delta custom I/O functions for controlling the device, use GPIO API instead. While being at it, add missing gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB). Signed-off-by: Janusz Krzysztofik Cc: David Woodhouse Reviewed-by: Artem Bityutskiy Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 30 --------- arch/arm/plat-omap/include/plat/board-ams-delta.h | 6 -- drivers/mtd/nand/ams-delta.c | 74 ++++++++++++++++------- 3 files changed, 52 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 034d0094e93..cc6f96249e7 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -236,36 +236,6 @@ static struct gpio latch_gpios[] __initconst = { .flags = GPIOF_OUT_INIT_LOW, .label = "lcd_ndisp", }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_NCE, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_nce", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_NRE, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_nre", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_NWP, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_nwp", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_NWE, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_nwe", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_ALE, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_ale", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_NAND_CLE, - .flags = GPIOF_OUT_INIT_LOW, - .label = "nand_cle", - }, { .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR, .flags = GPIOF_OUT_INIT_LOW, diff --git a/arch/arm/plat-omap/include/plat/board-ams-delta.h b/arch/arm/plat-omap/include/plat/board-ams-delta.h index a0f86ca75dd..3e578339fe8 100644 --- a/arch/arm/plat-omap/include/plat/board-ams-delta.h +++ b/arch/arm/plat-omap/include/plat/board-ams-delta.h @@ -30,12 +30,6 @@ #define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001 #define AMS_DELTA_LATCH2_LCD_NDISP 0x0002 -#define AMS_DELTA_LATCH2_NAND_NCE 0x0004 -#define AMS_DELTA_LATCH2_NAND_NRE 0x0008 -#define AMS_DELTA_LATCH2_NAND_NWP 0x0010 -#define AMS_DELTA_LATCH2_NAND_NWE 0x0020 -#define AMS_DELTA_LATCH2_NAND_ALE 0x0040 -#define AMS_DELTA_LATCH2_NAND_CLE 0x0080 #define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100 #define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200 #define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400 diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 9e6b498c9be..5769bd23428 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include /* @@ -34,8 +34,6 @@ */ static struct mtd_info *ams_delta_mtd = NULL; -#define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) - /* * Define partitions for flash devices */ @@ -68,10 +66,9 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) writew(0, io_base + OMAP_MPUIO_IO_CNTL); writew(byte, this->IO_ADDR_W); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 0); ndelay(40); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NWE, - AMS_DELTA_LATCH2_NAND_NWE); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NWE, 1); } static u_char ams_delta_read_byte(struct mtd_info *mtd) @@ -80,12 +77,11 @@ static u_char ams_delta_read_byte(struct mtd_info *mtd) struct nand_chip *this = mtd->priv; void __iomem *io_base = this->priv; - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); ndelay(40); writew(~0, io_base + OMAP_MPUIO_IO_CNTL); res = readw(this->IO_ADDR_R); - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NRE, - AMS_DELTA_LATCH2_NAND_NRE); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 1); return res; } @@ -132,15 +128,12 @@ static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd, { if (ctrl & NAND_CTRL_CHANGE) { - unsigned long bits; - - bits = (~ctrl & NAND_NCE) ? AMS_DELTA_LATCH2_NAND_NCE : 0; - bits |= (ctrl & NAND_CLE) ? AMS_DELTA_LATCH2_NAND_CLE : 0; - bits |= (ctrl & NAND_ALE) ? AMS_DELTA_LATCH2_NAND_ALE : 0; - - ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE | - AMS_DELTA_LATCH2_NAND_ALE | - AMS_DELTA_LATCH2_NAND_NCE, bits); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NCE, + (ctrl & NAND_NCE) == 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_CLE, + (ctrl & NAND_CLE) != 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_ALE, + (ctrl & NAND_ALE) != 0); } if (cmd != NAND_CMD_NONE) @@ -152,6 +145,39 @@ static int ams_delta_nand_ready(struct mtd_info *mtd) return gpio_get_value(AMS_DELTA_GPIO_PIN_NAND_RB); } +static struct gpio _mandatory_gpio[] __initconst_or_module = { + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_NCE, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "nand_nce", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_NRE, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "nand_nre", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_NWP, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "nand_nwp", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_NWE, + .flags = GPIOF_OUT_INIT_HIGH, + .label = "nand_nwe", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_ALE, + .flags = GPIOF_OUT_INIT_LOW, + .label = "nand_ale", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_NAND_CLE, + .flags = GPIOF_OUT_INIT_LOW, + .label = "nand_cle", + }, +}; + /* * Main initialization routine */ @@ -223,10 +249,9 @@ static int __devinit ams_delta_init(struct platform_device *pdev) platform_set_drvdata(pdev, io_base); /* Set chip enabled, but */ - ams_delta_latch2_write(NAND_MASK, AMS_DELTA_LATCH2_NAND_NRE | - AMS_DELTA_LATCH2_NAND_NWE | - AMS_DELTA_LATCH2_NAND_NCE | - AMS_DELTA_LATCH2_NAND_NWP); + err = gpio_request_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); + if (err) + goto out_gpio; /* Scan to find existence of the device */ if (nand_scan(ams_delta_mtd, 1)) { @@ -241,7 +266,10 @@ static int __devinit ams_delta_init(struct platform_device *pdev) goto out; out_mtd: + gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); +out_gpio: platform_set_drvdata(pdev, NULL); + gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); out_release_io: release_mem_region(res->start, resource_size(res)); @@ -262,6 +290,8 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev) /* Release resources, unregister device */ nand_release(ams_delta_mtd); + gpio_free_array(_mandatory_gpio, ARRAY_SIZE(_mandatory_gpio)); + gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); iounmap(io_base); release_mem_region(res->start, resource_size(res)); -- cgit v1.2.3-70-g09d2 From a218d19f6a91c076c7ed8a7c0082f777248c5394 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 00:08:56 +0100 Subject: omapfb: lcd_ams_delta: drive control lines over GPIO Don't use Amstrad Delta custom I/O functions any longer, use GPIO API instead. Signed-off-by: Janusz Krzysztofik Acked-by: Tomi Valkeinen Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 10 --------- arch/arm/plat-omap/include/plat/board-ams-delta.h | 2 -- drivers/video/omap/lcd_ams_delta.c | 27 +++++++++++++++++------ 3 files changed, 20 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index cc6f96249e7..3aba8f99cc7 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -226,16 +226,6 @@ static struct gpio latch_gpios[] __initconst = { .flags = GPIOF_OUT_INIT_LOW, .label = "dockit2", }, - { - .gpio = AMS_DELTA_GPIO_PIN_LCD_VBLEN, - .flags = GPIOF_OUT_INIT_LOW, - .label = "lcd_vblen", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_LCD_NDISP, - .flags = GPIOF_OUT_INIT_LOW, - .label = "lcd_ndisp", - }, { .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR, .flags = GPIOF_OUT_INIT_LOW, diff --git a/arch/arm/plat-omap/include/plat/board-ams-delta.h b/arch/arm/plat-omap/include/plat/board-ams-delta.h index 3e578339fe8..e9ad673be32 100644 --- a/arch/arm/plat-omap/include/plat/board-ams-delta.h +++ b/arch/arm/plat-omap/include/plat/board-ams-delta.h @@ -28,8 +28,6 @@ #if defined (CONFIG_MACH_AMS_DELTA) -#define AMS_DELTA_LATCH2_LCD_VBLEN 0x0001 -#define AMS_DELTA_LATCH2_LCD_NDISP 0x0002 #define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100 #define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200 #define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400 diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index 6978ae4ef83..73b211b92a3 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -98,29 +99,41 @@ static struct lcd_ops ams_delta_lcd_ops = { /* omapfb panel section */ +static struct gpio _gpios[] __initconst_or_module = { + { + .gpio = AMS_DELTA_GPIO_PIN_LCD_VBLEN, + .flags = GPIOF_OUT_INIT_LOW, + .label = "lcd_vblen", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_LCD_NDISP, + .flags = GPIOF_OUT_INIT_LOW, + .label = "lcd_ndisp", + }, +}; + static int ams_delta_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) { - return 0; + return gpio_request_array(_gpios, ARRAY_SIZE(_gpios)); } static void ams_delta_panel_cleanup(struct lcd_panel *panel) { + gpio_free_array(_gpios, ARRAY_SIZE(_gpios)); } static int ams_delta_panel_enable(struct lcd_panel *panel) { - ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, - AMS_DELTA_LATCH2_LCD_NDISP); - ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, - AMS_DELTA_LATCH2_LCD_VBLEN); + gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 1); + gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 1); return 0; } static void ams_delta_panel_disable(struct lcd_panel *panel) { - ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_VBLEN, 0); - ams_delta_latch2_write(AMS_DELTA_LATCH2_LCD_NDISP, 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_VBLEN, 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_LCD_NDISP, 0); } static unsigned long ams_delta_panel_get_caps(struct lcd_panel *panel) -- cgit v1.2.3-70-g09d2 From 8d09a1bb3147ddbcf0a9483021ca699c54c54732 Mon Sep 17 00:00:00 2001 From: Janusz Krzysztofik Date: Tue, 20 Dec 2011 23:10:34 +0100 Subject: input: serio: ams-delta: toggle keyboard power over GPIO Don't use Amstrad Delta custom I/O functions once GPIO interface is available for the underlying hardware. While requesting and initializing GPIO pins used, also take care of one extra pin KEYBRD_DATAOUT which, even if not used by the driver, belongs to the device and affects its functioning. Once done, move the driver initialization back to the device_initcall level, reverting the temporary chane introduced with patch 1/7 "ARM: OMAP1: ams-delta: register latch dependent devices later". That change is no longer required once the driver takes care of registering used GPIO pins, and it's better to initialize the device before others using the latch2 based GPIO pins, otherwise a garbage is reported on boot, perhaps due to random data already captured by the FIQ handler while the keyboard related latch bits are written with random values during initialization of those other latch2 dependent devices. Signed-off-by: Janusz Krzysztofik Acked-by: Dmitry Torokhov [tony@atomide.com: renamed _gpios to ams_delta_gpios] Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/board-ams-delta.c | 10 ---- arch/arm/plat-omap/include/plat/board-ams-delta.h | 2 - drivers/input/serio/ams_delta_serio.c | 56 ++++++++++++++--------- 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index 3aba8f99cc7..673cf21a90f 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c @@ -226,16 +226,6 @@ static struct gpio latch_gpios[] __initconst = { .flags = GPIOF_OUT_INIT_LOW, .label = "dockit2", }, - { - .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR, - .flags = GPIOF_OUT_INIT_LOW, - .label = "keybrd_pwr", - }, - { - .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT, - .flags = GPIOF_OUT_INIT_LOW, - .label = "keybrd_dataout", - }, { .gpio = AMS_DELTA_GPIO_PIN_SCARD_RSTIN, .flags = GPIOF_OUT_INIT_LOW, diff --git a/arch/arm/plat-omap/include/plat/board-ams-delta.h b/arch/arm/plat-omap/include/plat/board-ams-delta.h index e9ad673be32..027e79eead5 100644 --- a/arch/arm/plat-omap/include/plat/board-ams-delta.h +++ b/arch/arm/plat-omap/include/plat/board-ams-delta.h @@ -28,8 +28,6 @@ #if defined (CONFIG_MACH_AMS_DELTA) -#define AMD_DELTA_LATCH2_KEYBRD_PWR 0x0100 -#define AMD_DELTA_LATCH2_KEYBRD_DATA 0x0200 #define AMD_DELTA_LATCH2_SCARD_RSTIN 0x0400 #define AMD_DELTA_LATCH2_SCARD_CMDVCC 0x0800 #define AMS_DELTA_LATCH2_MODEM_NRESET 0x1000 diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c index 835d37abe62..0571e2ec358 100644 --- a/drivers/input/serio/ams_delta_serio.c +++ b/drivers/input/serio/ams_delta_serio.c @@ -92,8 +92,7 @@ static irqreturn_t ams_delta_serio_interrupt(int irq, void *dev_id) static int ams_delta_serio_open(struct serio *serio) { /* enable keyboard */ - ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR, - AMD_DELTA_LATCH2_KEYBRD_PWR); + gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 1); return 0; } @@ -101,9 +100,32 @@ static int ams_delta_serio_open(struct serio *serio) static void ams_delta_serio_close(struct serio *serio) { /* disable keyboard */ - ams_delta_latch2_write(AMD_DELTA_LATCH2_KEYBRD_PWR, 0); + gpio_set_value(AMS_DELTA_GPIO_PIN_KEYBRD_PWR, 0); } +static struct gpio ams_delta_gpios[] __initconst_or_module = { + { + .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATA, + .flags = GPIOF_DIR_IN, + .label = "serio-data", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_CLK, + .flags = GPIOF_DIR_IN, + .label = "serio-clock", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_PWR, + .flags = GPIOF_OUT_INIT_LOW, + .label = "serio-power", + }, + { + .gpio = AMS_DELTA_GPIO_PIN_KEYBRD_DATAOUT, + .flags = GPIOF_OUT_INIT_LOW, + .label = "serio-dataout", + }, +}; + static int __init ams_delta_serio_init(void) { int err; @@ -123,19 +145,12 @@ static int __init ams_delta_serio_init(void) strlcpy(ams_delta_serio->phys, "GPIO/serio0", sizeof(ams_delta_serio->phys)); - err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_DATA, "serio-data"); + err = gpio_request_array(ams_delta_gpios, + ARRAY_SIZE(ams_delta_gpios)); if (err) { - pr_err("ams_delta_serio: Couldn't request gpio pin for data\n"); + pr_err("ams_delta_serio: Couldn't request gpio pins\n"); goto serio; } - gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); - - err = gpio_request(AMS_DELTA_GPIO_PIN_KEYBRD_CLK, "serio-clock"); - if (err) { - pr_err("ams_delta_serio: couldn't request gpio pin for clock\n"); - goto gpio_data; - } - gpio_direction_input(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); err = request_irq(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), ams_delta_serio_interrupt, IRQ_TYPE_EDGE_RISING, @@ -143,7 +158,7 @@ static int __init ams_delta_serio_init(void) if (err < 0) { pr_err("ams_delta_serio: couldn't request gpio interrupt %d\n", gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK)); - goto gpio_clk; + goto gpio; } /* * Since GPIO register handling for keyboard clock pin is performed @@ -157,21 +172,20 @@ static int __init ams_delta_serio_init(void) dev_info(&ams_delta_serio->dev, "%s\n", ams_delta_serio->name); return 0; -gpio_clk: - gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); -gpio_data: - gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); +gpio: + gpio_free_array(ams_delta_gpios, + ARRAY_SIZE(ams_delta_gpios)); serio: kfree(ams_delta_serio); return err; } -late_initcall(ams_delta_serio_init); +module_init(ams_delta_serio_init); static void __exit ams_delta_serio_exit(void) { serio_unregister_port(ams_delta_serio); free_irq(OMAP_GPIO_IRQ(AMS_DELTA_GPIO_PIN_KEYBRD_CLK), 0); - gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_CLK); - gpio_free(AMS_DELTA_GPIO_PIN_KEYBRD_DATA); + gpio_free_array(ams_delta_gpios, + ARRAY_SIZE(ams_delta_gpios)); } module_exit(ams_delta_serio_exit); -- cgit v1.2.3-70-g09d2 From 5e13fd354a39d637df9b25edcb2964edf4a7c534 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 13 Dec 2011 17:19:57 +0530 Subject: ath6kl: Use cfg80211_roamed_bss() to report roaming event This is to avoid the scenario where the bss entry of the AP got expired when reporting roaming event to current AP. As the bss entry for the current bss is available in driver, pass this bss to cfg80211. This fixes WARNING: at net/wireless/sme.c:586. This patch depends on the following patch in cfg80211 "cfg80211: Fix race in bss timeout". Reported-by: Kalle Valo Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 37 +++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 6c59a217b1a..85c24dd0156 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -605,11 +605,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, return 0; } -static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, - enum network_type nw_type, - const u8 *bssid, - struct ieee80211_channel *chan, - const u8 *beacon_ie, size_t beacon_ie_len) +static struct cfg80211_bss * +ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, + enum network_type nw_type, + const u8 *bssid, + struct ieee80211_channel *chan, + const u8 *beacon_ie, + size_t beacon_ie_len) { struct ath6kl *ar = vif->ar; struct cfg80211_bss *bss; @@ -638,7 +640,7 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, */ ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL); if (ie == NULL) - return -ENOMEM; + return NULL; ie[0] = WLAN_EID_SSID; ie[1] = vif->ssid_len; memcpy(ie + 2, vif->ssid, vif->ssid_len); @@ -652,15 +654,9 @@ static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif, "cfg80211\n", bssid); kfree(ie); } else - ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss " - "entry\n"); - - if (bss == NULL) - return -ENOMEM; + ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n"); - cfg80211_put_bss(bss); - - return 0; + return bss; } void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -672,6 +668,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, { struct ieee80211_channel *chan; struct ath6kl *ar = vif->ar; + struct cfg80211_bss *bss; /* capinfo + listen interval */ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16); @@ -712,8 +709,9 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, chan = ieee80211_get_channel(ar->wiphy, (int) channel); - if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info, - beacon_ie_len) < 0) { + bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, + assoc_info, beacon_ie_len); + if (!bss) { ath6kl_err("could not add cfg80211 bss entry\n"); return; } @@ -722,6 +720,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n", nw_type & ADHOC_CREATOR ? "creator" : "joiner"); cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL); + cfg80211_put_bss(bss); return; } @@ -732,11 +731,11 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, assoc_req_ie, assoc_req_len, assoc_resp_ie, assoc_resp_len, WLAN_STATUS_SUCCESS, GFP_KERNEL); + cfg80211_put_bss(bss); } else if (vif->sme_state == SME_CONNECTED) { /* inform roam event to cfg80211 */ - cfg80211_roamed(vif->ndev, chan, bssid, - assoc_req_ie, assoc_req_len, - assoc_resp_ie, assoc_resp_len, GFP_KERNEL); + cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len, + assoc_resp_ie, assoc_resp_len, GFP_KERNEL); } } -- cgit v1.2.3-70-g09d2 From 6e786cb1e514dc87647beccaa96bd8a255d97a0c Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 15 Dec 2011 14:16:00 +0200 Subject: ath6kl: Fix connect command to clear previously used IEs Empty IE buffer means that the new association is not supposed to include extra IEs. Make sure any previously configured (Re)Association Request frame IEs get cleared in such a case. This is based on a patch from Shuibing. Cc: Dai Shuibing Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 85c24dd0156..1a06a04c510 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -461,13 +461,13 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, } } - if (sme->ie && (sme->ie_len > 0)) { - status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); - if (status) { - up(&ar->sem); - return status; - } - } else + status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len); + if (status) { + up(&ar->sem); + return status; + } + + if (sme->ie == NULL || sme->ie_len == 0) ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG; if (test_bit(CONNECTED, &vif->flags) && -- cgit v1.2.3-70-g09d2 From ca1d16a08fc2c26b693e65ad92fa37a4c778e60d Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Fri, 16 Dec 2011 14:24:23 +0530 Subject: ath6kl: Avoid taking struct as argument in ath6kl_wmi_set_ip_cmd In this way, caller is free to pass only the value of IP addr to configure. In addition to this, * 'ips' variable data type in struct wmi_set_ip_cmd is changed from __le32 to __be32 in order to match network byte order. * ipv4_is_multicast() is used to validate multicast ip addr. * New argument if_idx is added to supply correct vif index to ath6kl_wmi_cmd_send(). This will be used in the next patch. Signed-off-by: Raja Mani Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/wmi.c | 12 +++++++----- drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++-- 2 files changed, 10 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index f6f2aa27fc2..1e31c38abb4 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2479,15 +2479,16 @@ int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 if_idx, u8 traffic_class, return ret; } -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1) { struct sk_buff *skb; struct wmi_set_ip_cmd *cmd; int ret; /* Multicast address are not valid */ - if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) || - (*((u8 *) &ip_cmd->ips[1]) >= 0xE0)) + if (ipv4_is_multicast(ips0) || + ipv4_is_multicast(ips1)) return -EINVAL; skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd)); @@ -2495,9 +2496,10 @@ int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd) return -ENOMEM; cmd = (struct wmi_set_ip_cmd *) skb->data; - memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd)); + cmd->ips[0] = ips0; + cmd->ips[1] = ips1; - ret = ath6kl_wmi_cmd_send(wmi, 0, skb, WMI_SET_IP_CMDID, + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG); return ret; } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 42ac311eda4..96e3cc10cab 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1903,7 +1903,7 @@ struct wow_filter { struct wmi_set_ip_cmd { /* IP in network byte order */ - __le32 ips[MAX_IP_ADDRS]; + __be32 ips[MAX_IP_ADDRS]; } __packed; enum ath6kl_wow_filters { @@ -2417,7 +2417,8 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len); s32 ath6kl_wmi_get_rate(s8 rate_index); -int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd); +int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, u8 if_idx, + __be32 ips0, __be32 ips1); int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_host_mode host_mode); int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, -- cgit v1.2.3-70-g09d2 From c08631c6e43e7ce91bca6b2d3466bb22a85fe724 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Fri, 16 Dec 2011 14:24:24 +0530 Subject: ath6kl: Send own IP addr to the firmware during WOW suspend Firmware ARP module requires own IP addr in order to respond to the outside world when the target is in WOW suspend state. At present, firmware ARP module has capability to hold 2 IP addr. So, WOW mode will be disabled if the total IP addr configured in net_dev for our device is greater than firmware limit (MAX_IP_ADDRS) which is 2 at this moment. Signed-off-by: Raja Mani Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 33 +++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1a06a04c510..45b0d974e4f 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -15,6 +15,7 @@ */ #include +#include #include "core.h" #include "cfg80211.h" @@ -1729,11 +1730,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) { + struct in_device *in_dev; + struct in_ifaddr *ifa; struct ath6kl_vif *vif; int ret, pos, left; u32 filter = 0; u16 i; - u8 mask[WOW_MASK_SIZE]; + u8 mask[WOW_MASK_SIZE], index = 0; + __be32 ips[MAX_IP_ADDRS]; vif = ath6kl_vif_first(ar); if (!vif) @@ -1780,6 +1784,33 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) return ret; } + /* Setup own IP addr for ARP agent. */ + in_dev = __in_dev_get_rtnl(vif->ndev); + if (!in_dev) + goto skip_arp; + + ifa = in_dev->ifa_list; + memset(&ips, 0, sizeof(ips)); + + /* Configure IP addr only if IP address count < MAX_IP_ADDRS */ + while (index < MAX_IP_ADDRS && ifa) { + ips[index] = ifa->ifa_local; + ifa = ifa->ifa_next; + index++; + } + + if (ifa) { + ath6kl_err("total IP addr count is exceeding fw limit\n"); + return -EINVAL; + } + + ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]); + if (ret) { + ath6kl_err("fail to setup ip for arp agent\n"); + return ret; + } + +skip_arp: if (wow->disconnect) filter |= WOW_FILTER_OPTION_NWK_DISASSOC; -- cgit v1.2.3-70-g09d2 From c0038972b1253ad7f3ab7cc35ed57a830f5c8568 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Fri, 16 Dec 2011 20:53:31 +0200 Subject: ath6kl: handle firmware names more dynamically Currently ath6kl has just hardcoded paths to each firmware file. Change this more dynamic by separating the the directory and file name from each other. That way it's easier to dynamically create full paths to firmware and code looks better. And now it's possible to remove a function needed by devicetree code. While at it add a structure inside struct ath6kl_hw to contain all firmware names. I deliberately omitted board file support as those will be handled later. This is needed for firmware API 3. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 45 +++++++++------- drivers/net/wireless/ath/ath6kl/init.c | 95 ++++++++++++++++++---------------- drivers/net/wireless/ath/ath6kl/sdio.c | 16 +++--- drivers/net/wireless/ath/ath6kl/usb.c | 5 +- 4 files changed, 87 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c863a28f2e0..26795771256 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -97,45 +97,46 @@ struct ath6kl_fw_ie { u8 data[0]; }; +#define ATH6KL_FW_API2_FILE "fw-2.bin" + /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba /* AR6003 2.0 definitions */ #define AR6003_HW_2_0_VERSION 0x30000384 #define AR6003_HW_2_0_PATCH_DOWNLOAD_ADDRESS 0x57e910 -#define AR6003_HW_2_0_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" -#define AR6003_HW_2_0_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" -#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" -#define AR6003_HW_2_0_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" -#define AR6003_HW_2_0_FIRMWARE_2_FILE "ath6k/AR6003/hw2.0/fw-2.bin" +#define AR6003_HW_2_0_FW_DIR "ath6k/AR6003/hw2.0" +#define AR6003_HW_2_0_OTP_FILE "otp.bin.z77" +#define AR6003_HW_2_0_FIRMWARE_FILE "athwlan.bin.z77" +#define AR6003_HW_2_0_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_0_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_0_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin" #define AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.0/bdata.SD31.bin" /* AR6003 3.0 definitions */ #define AR6003_HW_2_1_1_VERSION 0x30000582 -#define AR6003_HW_2_1_1_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" -#define AR6003_HW_2_1_1_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" -#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE \ - "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" -#define AR6003_HW_2_1_1_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" -#define AR6003_HW_2_1_1_FIRMWARE_2_FILE "ath6k/AR6003/hw2.1.1/fw-2.bin" +#define AR6003_HW_2_1_1_FW_DIR "ath6k/AR6003/hw2.1.1" +#define AR6003_HW_2_1_1_OTP_FILE "otp.bin" +#define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin" +#define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" /* AR6004 1.0 definitions */ #define AR6004_HW_1_0_VERSION 0x30000623 -#define AR6004_HW_1_0_FIRMWARE_2_FILE "ath6k/AR6004/hw1.0/fw-2.bin" -#define AR6004_HW_1_0_FIRMWARE_FILE "ath6k/AR6004/hw1.0/fw.ram.bin" +#define AR6004_HW_1_0_FW_DIR "ath6k/AR6004/hw1.0" +#define AR6004_HW_1_0_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_0_BOARD_DATA_FILE "ath6k/AR6004/hw1.0/bdata.bin" #define AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.0/bdata.DB132.bin" /* AR6004 1.1 definitions */ #define AR6004_HW_1_1_VERSION 0x30000001 -#define AR6004_HW_1_1_FIRMWARE_2_FILE "ath6k/AR6004/hw1.1/fw-2.bin" -#define AR6004_HW_1_1_FIRMWARE_FILE "ath6k/AR6004/hw1.1/fw.ram.bin" +#define AR6004_HW_1_1_FW_DIR "ath6k/AR6004/hw1.1" +#define AR6004_HW_1_1_FIRMWARE_FILE "fw.ram.bin" #define AR6004_HW_1_1_BOARD_DATA_FILE "ath6k/AR6004/hw1.1/bdata.bin" #define AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE \ "ath6k/AR6004/hw1.1/bdata.DB132.bin" @@ -575,11 +576,15 @@ struct ath6kl { u32 refclk_hz; u32 uarttx_pin; - const char *fw_otp; - const char *fw; - const char *fw_tcmd; - const char *fw_patch; - const char *fw_api2; + struct ath6kl_hw_fw { + const char *dir; + const char *otp; + const char *fw; + const char *tcmd; + const char *patch; + const char *api2; + } fw; + const char *fw_board; const char *fw_default_board; } hw; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 368ecbd172a..7b802e99851 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -47,11 +47,15 @@ static const struct ath6kl_hw hw_list[] = { /* hw2.0 needs override address hardcoded */ .app_start_override_addr = 0x944C00, - .fw_otp = AR6003_HW_2_0_OTP_FILE, - .fw = AR6003_HW_2_0_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_0_PATCH_FILE, - .fw_api2 = AR6003_HW_2_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6003_HW_2_0_FW_DIR, + .otp = AR6003_HW_2_0_OTP_FILE, + .fw = AR6003_HW_2_0_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_0_PATCH_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, .fw_default_board = AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE, }, @@ -65,11 +69,15 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 8, - .fw_otp = AR6003_HW_2_1_1_OTP_FILE, - .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, - .fw_tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, - .fw_patch = AR6003_HW_2_1_1_PATCH_FILE, - .fw_api2 = AR6003_HW_2_1_1_FIRMWARE_2_FILE, + .fw = { + .dir = AR6003_HW_2_1_1_FW_DIR, + .otp = AR6003_HW_2_1_1_OTP_FILE, + .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, + .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, + .patch = AR6003_HW_2_1_1_PATCH_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, .fw_default_board = AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE, }, @@ -84,8 +92,12 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 26000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_0_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_0_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_0_FW_DIR, + .fw = AR6004_HW_1_0_FIRMWARE_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE, }, @@ -100,8 +112,12 @@ static const struct ath6kl_hw hw_list[] = { .refclk_hz = 40000000, .uarttx_pin = 11, - .fw = AR6004_HW_1_1_FIRMWARE_FILE, - .fw_api2 = AR6004_HW_1_1_FIRMWARE_2_FILE, + .fw = { + .dir = AR6004_HW_1_1_FW_DIR, + .fw = AR6004_HW_1_1_FIRMWARE_FILE, + .api2 = ATH6KL_FW_API2_FILE, + }, + .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, .fw_default_board = AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE, }, @@ -626,21 +642,6 @@ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, } #ifdef CONFIG_OF -static const char *get_target_ver_dir(const struct ath6kl *ar) -{ - switch (ar->version.target_ver) { - case AR6003_HW_1_0_VERSION: - return "ath6k/AR6003/hw1.0"; - case AR6003_HW_2_0_VERSION: - return "ath6k/AR6003/hw2.0"; - case AR6003_HW_2_1_1_VERSION: - return "ath6k/AR6003/hw2.1.1"; - } - ath6kl_warn("%s: unsupported target version 0x%x.\n", __func__, - ar->version.target_ver); - return NULL; -} - /* * Check the device tree for a board-id and use it to construct * the pathname to the firmware file. Used (for now) to find a @@ -663,7 +664,7 @@ static bool check_device_tree(struct ath6kl *ar) continue; } snprintf(board_filename, sizeof(board_filename), - "%s/bdata.%s.bin", get_target_ver_dir(ar), board_id); + "%s/bdata.%s.bin", ar->hw.fw.dir, board_id); ret = ath6kl_get_fw(ar, board_filename, &ar->fw_board, &ar->fw_board_len); @@ -730,19 +731,20 @@ static int ath6kl_fetch_board_file(struct ath6kl *ar) static int ath6kl_fetch_otp_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_otp != NULL) return 0; - if (ar->hw.fw_otp == NULL) { + if (ar->hw.fw.otp == NULL) { ath6kl_dbg(ATH6KL_DBG_BOOT, "no OTP file configured for this hw\n"); return 0; } - filename = ar->hw.fw_otp; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.otp); ret = ath6kl_get_fw(ar, filename, &ar->fw_otp, &ar->fw_otp_len); @@ -757,29 +759,32 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) static int ath6kl_fetch_fw_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw != NULL) return 0; if (testmode) { - if (ar->hw.fw_tcmd == NULL) { + if (ar->hw.fw.tcmd == NULL) { ath6kl_warn("testmode not supported\n"); return -EOPNOTSUPP; } - filename = ar->hw.fw_tcmd; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); set_bit(TESTMODE, &ar->flag); goto get_fw; } - if (WARN_ON(ar->hw.fw == NULL)) + /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */ + if (WARN_ON(ar->hw.fw.fw == NULL)) return -EINVAL; - filename = ar->hw.fw; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.fw); get_fw: ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); @@ -794,16 +799,17 @@ get_fw: static int ath6kl_fetch_patch_file(struct ath6kl *ar) { - const char *filename; + char filename[100]; int ret; if (ar->fw_patch != NULL) return 0; - if (ar->hw.fw_patch == NULL) + if (ar->hw.fw.patch == NULL) return 0; - filename = ar->hw.fw_patch; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.patch); ret = ath6kl_get_fw(ar, filename, &ar->fw_patch, &ar->fw_patch_len); @@ -840,15 +846,16 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) size_t magic_len, len, ie_len; const struct firmware *fw; struct ath6kl_fw_ie *hdr; - const char *filename; + char filename[100]; const u8 *data; int ret, ie_id, i, index, bit; __le32 *val; - if (ar->hw.fw_api2 == NULL) + if (ar->hw.fw.api2 == NULL) return -EOPNOTSUPP; - filename = ar->hw.fw_api2; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.api2); ret = request_firmware(&fw, filename, ar->dev); if (ret) diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 15c3f56caf4..278a9f30795 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1362,19 +1362,19 @@ MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6003_HW_2_0_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_0_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_0_FW_DIR "/" AR6003_HW_2_0_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_OTP_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_FIRMWARE_FILE); -MODULE_FIRMWARE(AR6003_HW_2_1_1_PATCH_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_OTP_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6003_HW_2_1_1_FW_DIR "/" AR6003_HW_2_1_1_PATCH_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c index e3cf397fcaf..bb341796dc8 100644 --- a/drivers/net/wireless/ath/ath6kl/usb.c +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -423,9 +423,10 @@ module_exit(ath6kl_usb_exit); MODULE_AUTHOR("Atheros Communications, Inc."); MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); + +MODULE_FIRMWARE(AR6004_HW_1_0_FW_DIR "/" AR6004_HW_1_0_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); -MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FW_DIR "/" AR6004_HW_1_1_FIRMWARE_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -- cgit v1.2.3-70-g09d2 From 65a8b4cc511b68712799e91137324f2abece7d3e Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Fri, 16 Dec 2011 20:53:41 +0200 Subject: ath6kl: add support for FW API 3 As firmware starting from 3.2.0.12 has some API changes and doesn't work with older versions of ath6kl we need to bump up the API version. This way we don't break anything. Also store which version of API is used and print that during boot: ath6kl: ar6003 hw 2.1.1 sdio fw 3.2.0.13 api 3 Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 ++- drivers/net/wireless/ath/ath6kl/init.c | 32 +++++++++++++++++--------------- 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 26795771256..c095fafa278 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -98,6 +98,7 @@ struct ath6kl_fw_ie { }; #define ATH6KL_FW_API2_FILE "fw-2.bin" +#define ATH6KL_FW_API3_FILE "fw-3.bin" /* AR6003 1.0 definitions */ #define AR6003_HW_1_0_VERSION 0x300002ba @@ -582,7 +583,6 @@ struct ath6kl { const char *fw; const char *tcmd; const char *patch; - const char *api2; } fw; const char *fw_board; @@ -608,6 +608,7 @@ struct ath6kl { u8 *fw_patch; size_t fw_patch_len; + unsigned int fw_api; unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; struct workqueue_struct *ath6kl_wq; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7b802e99851..57e0312c4cb 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -53,7 +53,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_0_FIRMWARE_FILE, .tcmd = AR6003_HW_2_0_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_0_PATCH_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6003_HW_2_0_BOARD_DATA_FILE, @@ -75,7 +74,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_1_1_PATCH_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, @@ -95,7 +93,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = { .dir = AR6004_HW_1_0_FW_DIR, .fw = AR6004_HW_1_0_FIRMWARE_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6004_HW_1_0_BOARD_DATA_FILE, @@ -115,7 +112,6 @@ static const struct ath6kl_hw hw_list[] = { .fw = { .dir = AR6004_HW_1_1_FW_DIR, .fw = AR6004_HW_1_1_FIRMWARE_FILE, - .api2 = ATH6KL_FW_API2_FILE, }, .fw_board = AR6004_HW_1_1_BOARD_DATA_FILE, @@ -841,7 +837,7 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar) return 0; } -static int ath6kl_fetch_fw_api2(struct ath6kl *ar) +static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) { size_t magic_len, len, ie_len; const struct firmware *fw; @@ -851,11 +847,7 @@ static int ath6kl_fetch_fw_api2(struct ath6kl *ar) int ret, ie_id, i, index, bit; __le32 *val; - if (ar->hw.fw.api2 == NULL) - return -EOPNOTSUPP; - - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.api2); + snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, name); ret = request_firmware(&fw, filename, ar->dev); if (ret) @@ -1025,17 +1017,26 @@ static int ath6kl_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; - ret = ath6kl_fetch_fw_api2(ar); + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 2\n"); - return 0; + ar->fw_api = 3; + goto out; + } + + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API2_FILE); + if (ret == 0) { + ar->fw_api = 2; + goto out; } ret = ath6kl_fetch_fw_api1(ar); if (ret) return ret; - ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api 1\n"); + ar->fw_api = 1; + +out: + ath6kl_dbg(ATH6KL_DBG_BOOT, "using fw api %d\n", ar->fw_api); return 0; } @@ -1488,10 +1489,11 @@ int ath6kl_init_hw_start(struct ath6kl *ar) if (test_and_clear_bit(FIRST_BOOT, &ar->flag)) { - ath6kl_info("%s %s fw %s%s\n", + ath6kl_info("%s %s fw %s api %d%s\n", ar->hw.name, ath6kl_init_get_hif_name(ar->hif_type), ar->wiphy->fw_version, + ar->fw_api, test_bit(TESTMODE, &ar->flag) ? " testmode" : ""); } -- cgit v1.2.3-70-g09d2 From e68f67509d92114c55938898643600c23f88b4c1 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Thu, 22 Dec 2011 12:15:27 +0530 Subject: ath6kl: Fix panic when setting a channel cfg80211 could pass a NULL net_device to the driver via the set_channel() callback, when it receives a request to set the device's channel. Not handling this case properly results in this panic: BUG: unable to handle kernel NULL pointer dereference at 0000000000000cb0 IP: [] ath6kl_cfg80211_ready+0x9/0x70 [ath6kl_sdio] Call Trace: [] ath6kl_set_channel+0x27/0x90 [ath6kl_sdio] [] cfg80211_set_freq+0xff/0x1d0 [cfg80211] [] ? nl80211_set_wiphy+0x85/0x660 [cfg80211] [] __nl80211_set_channel.isra.39+0x118/0x140 [cfg80211] [] nl80211_set_wiphy+0x303/0x660 [cfg80211] [] ? rtnl_lock+0x17/0x20 [] ? nl80211_pre_doit+0xb5/0x150 [cfg80211] [] genl_rcv_msg+0x1d5/0x250 [] ? genl_rcv+0x40/0x40 [] netlink_rcv_skb+0xa9/0xd0 [] genl_rcv+0x25/0x40 [] ? might_fault+0x40/0x90 [] netlink_unicast+0x2d9/0x320 [] netlink_sendmsg+0x2c6/0x320 [] ? sock_update_classid+0xb0/0x110 [] sock_sendmsg+0x10e/0x130 [] ? mem_cgroup_update_page_stat+0x193/0x250 [] ? might_fault+0x40/0x90 [] ? might_fault+0x40/0x90 [] ? might_fault+0x89/0x90 [] ? might_fault+0x40/0x90 [] ? verify_iovec+0x56/0xd0 [] __sys_sendmsg+0x396/0x3b0 [] ? up_read+0x23/0x40 [] ? do_page_fault+0x208/0x4e0 [] ? vfsmount_lock_local_unlock+0x21/0x60 [] ? mntput_no_expire+0x30/0xe0 [] ? mntput+0x1f/0x30 [] sys_sendmsg+0x49/0x90 [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 45b0d974e4f..d6806be5895 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2044,7 +2044,18 @@ static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl_vif *vif; + + /* + * 'dev' could be NULL if a channel change is required for the hardware + * device itself, instead of a particular VIF. + * + * FIXME: To be handled properly when monitor mode is supported. + */ + if (!dev) + return -EBUSY; + + vif = netdev_priv(dev); if (!ath6kl_cfg80211_ready(vif)) return -EIO; -- cgit v1.2.3-70-g09d2 From 33e5308d8a0fb857a57c38def36ccf7b14ebf1c1 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 27 Dec 2011 11:02:56 +0200 Subject: ath6kl: Add del_station cfg80211_ops hostapd/wpa_supplicant AP mode uses this operation to flush the station entries. Implement this in ath6kl to avoid unnecessary warnings from NL80211_CMD_DEL_STATION failing. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index d6806be5895..f74762ed619 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2300,6 +2300,19 @@ static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev) return 0; } +static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, + u8 *mac) +{ + struct ath6kl *ar = ath6kl_priv(dev); + struct ath6kl_vif *vif = netdev_priv(dev); + const u8 *addr = mac ? mac : bcast_addr; + + return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, + addr, WLAN_REASON_PREV_AUTH_NOT_VALID); +} + static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev, u8 *mac, struct station_parameters *params) { @@ -2603,6 +2616,7 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = { .add_beacon = ath6kl_add_beacon, .set_beacon = ath6kl_set_beacon, .del_beacon = ath6kl_del_beacon, + .del_station = ath6kl_del_station, .change_station = ath6kl_change_station, .remain_on_channel = ath6kl_remain_on_channel, .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel, -- cgit v1.2.3-70-g09d2 From ba1f6fe393c329230d2589ea508cbf90ff3cc9ce Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 27 Dec 2011 11:03:53 +0200 Subject: ath6kl: Advertise TX/RX support for frames in AP mode This is needed to fix current hostapd/wpa_supplicant AP operations for frame registration. P2P GO mode already advertised these, but AP mode was forgotten and could not be used after the hostapd/wpa_supplicant frame registration changes. Signed-off-by: Jouni Malinen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index f74762ed619..c756425abf7 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2572,6 +2572,12 @@ ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = { .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_REQ >> 4) }, + [NL80211_IFTYPE_AP] = { + .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_RESP >> 4), + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) + }, [NL80211_IFTYPE_P2P_CLIENT] = { .tx = BIT(IEEE80211_STYPE_ACTION >> 4) | BIT(IEEE80211_STYPE_PROBE_RESP >> 4), -- cgit v1.2.3-70-g09d2 From bc48ad31c5814feb4ff8faca9a8d422279593cb1 Mon Sep 17 00:00:00 2001 From: Rishi Panjwani Date: Tue, 27 Dec 2011 14:28:00 -0800 Subject: ath6kl: Support for TCP checksum offload to firmware The change enables offloading TCP checksum calculation to firmware. There are still some issues with the checksum offload so better to disable it by default until the issues are resolved. To enable TCP checksum offload for tx and rx paths, use the ethtool as follows: ethtool -K tx on ethtool -K rx on To disable TCP checksum offload, for tx and rx paths, use the ethtool as follows: ethtool -K tx off ethtool -K rx off kvalo: indentation changes Signed-off-by: Rishi Panjwani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 2 ++ drivers/net/wireless/ath/ath6kl/main.c | 33 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/txrx.c | 38 ++++++++++++++++++++++++++++++---- drivers/net/wireless/ath/ath6kl/wmi.h | 3 +++ 4 files changed, 72 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 57e0312c4cb..e74279372ef 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1686,6 +1686,8 @@ int ath6kl_core_init(struct ath6kl *ar) set_bit(FIRST_BOOT, &ar->flag); + ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + ret = ath6kl_init_hw_start(ar); if (ret) { ath6kl_err("Failed to start hardware: %d\n", ret); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index eea3c747653..f3d0184a5ce 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1020,11 +1020,44 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) return &vif->net_stats; } +static int ath6kl_set_features(struct net_device *dev, u32 features) +{ + struct ath6kl_vif *vif = netdev_priv(dev); + struct ath6kl *ar = vif->ar; + int err = 0; + + if ((features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver != WMI_META_VERSION_2)) { + ar->rx_meta_ver = WMI_META_VERSION_2; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features & ~NETIF_F_RXCSUM; + return err; + } + } else if (!(features & NETIF_F_RXCSUM) && + (ar->rx_meta_ver == WMI_META_VERSION_2)) { + ar->rx_meta_ver = 0; + err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi, + vif->fw_vif_idx, + ar->rx_meta_ver, 0, 0); + if (err) { + dev->features = features | NETIF_F_RXCSUM; + return err; + } + + } + + return err; +} + static struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, .ndo_get_stats = ath6kl_get_stats, + .ndo_set_features = ath6kl_set_features, }; void init_netdev(struct net_device *dev) diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 506a3031a88..78bd57306f7 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -244,6 +244,10 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) u8 ac = 99 ; /* initialize to unmapped ac */ bool chk_adhoc_ps_mapping = false, more_data = false; int ret; + struct wmi_tx_meta_v2 meta_v2; + void *meta; + u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed; + u8 meta_ver = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, @@ -265,6 +269,14 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } if (test_bit(WMI_ENABLED, &ar->flag)) { + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + csum_start = skb->csum_start - + (skb_network_header(skb) - skb->head) + + sizeof(struct ath6kl_llc_snap_hdr); + csum_dest = skb->csum_offset + csum_start; + } + if (skb_headroom(skb) < dev->needed_headroom) { struct sk_buff *tmp_skb = skb; @@ -281,10 +293,28 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) goto fail_tx; } - if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE, - more_data, 0, 0, NULL, - vif->fw_vif_idx)) { - ath6kl_err("wmi_data_hdr_add failed\n"); + if ((dev->features & NETIF_F_IP_CSUM) && + (csum == CHECKSUM_PARTIAL)) { + meta_v2.csum_start = csum_start; + meta_v2.csum_dest = csum_dest; + + /* instruct target to calculate checksum */ + meta_v2.csum_flags = WMI_META_V2_FLAG_CSUM_OFFLOAD; + meta_ver = WMI_META_VERSION_2; + meta = &meta_v2; + } else { + meta_ver = 0; + meta = NULL; + } + + ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb, + DATA_MSGTYPE, more_data, 0, + meta_ver, + meta, vif->fw_vif_idx); + + if (ret) { + ath6kl_warn("failed to add wmi data header:%d\n" + , ret); goto fail_tx; } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 96e3cc10cab..9f8425b97db 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -257,6 +257,9 @@ static inline u8 wmi_data_hdr_get_if_idx(struct wmi_data_hdr *dhdr) #define WMI_META_VERSION_1 0x01 #define WMI_META_VERSION_2 0x02 +/* Flag to signal to FW to calculate TCP checksum */ +#define WMI_META_V2_FLAG_CSUM_OFFLOAD 0x01 + struct wmi_tx_meta_v1 { /* packet ID to identify the tx request */ u8 pkt_id; -- cgit v1.2.3-70-g09d2 From 351de2835d6429548feb8cca9a17497ec3474f41 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 29 Dec 2011 16:05:37 +0530 Subject: ath6kl: Remove few unnecessary spin_locks around set_bit() Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 78bd57306f7..fcea82479cd 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -479,9 +479,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, * WMI queue with too many commands the only exception to * this is during testing using endpointping. */ - spin_lock_bh(&ar->lock); set_bit(WMI_CTRL_EP_FULL, &ar->flag); - spin_unlock_bh(&ar->lock); ath6kl_err("wmi ctrl ep is full\n"); return action; } @@ -509,9 +507,7 @@ enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target, action != HTC_SEND_FULL_DROP) { spin_unlock_bh(&ar->list_lock); - spin_lock_bh(&vif->if_lock); set_bit(NETQ_STOPPED, &vif->flags); - spin_unlock_bh(&vif->if_lock); netif_stop_queue(vif->ndev); return action; -- cgit v1.2.3-70-g09d2 From a10e2f2f6db8f86eaca1cf3d00269463da4d6434 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 29 Dec 2011 16:05:38 +0530 Subject: ath6kl: Add a module parameter to enable uart debug To enable firmware debug messages through uart interface, modprobe ath6kl_sdio uart_debug=1. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index e74279372ef..a481b6a1715 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -28,10 +28,12 @@ unsigned int debug_mask; static unsigned int testmode; static bool suspend_cutpower; +static unsigned int uart_debug; module_param(debug_mask, uint, 0644); module_param(testmode, uint, 0644); module_param(suspend_cutpower, bool, 0444); +module_param(uart_debug, uint, 0644); static const struct ath6kl_hw hw_list[] = { { @@ -464,6 +466,13 @@ int ath6kl_configure_target(struct ath6kl *ar) u8 fw_iftype, fw_mode = 0, fw_submode = 0; int i, status; + param = uart_debug; + if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { + ath6kl_err("bmi_write_memory for uart debug failed\n"); + return -EIO; + } + /* * Note: Even though the firmware interface type is * chosen as BSS_STA for all three interfaces, can -- cgit v1.2.3-70-g09d2 From 792ecb33080f4e315695e0fe21cf3a3c2a514dd0 Mon Sep 17 00:00:00 2001 From: Vivek Natarajan Date: Thu, 29 Dec 2011 16:18:39 +0530 Subject: ath6kl: Remove redundant key_index check. Less-than-zero comparison of an unsigned value is never true. kvalo: remove WMI_MIN_KEY_INDEX altogether, it's useless Signed-off-by: Vivek Natarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 11 +++++------ drivers/net/wireless/ath/ath6kl/main.c | 2 +- drivers/net/wireless/ath/ath6kl/wmi.h | 1 - 3 files changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index c756425abf7..2a166cc7cc3 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -524,8 +524,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, (vif->prwise_crypto == WEP_CRYPT)) { struct ath6kl_key *key = NULL; - if (sme->key_idx < WMI_MIN_KEY_INDEX || - sme->key_idx > WMI_MAX_KEY_INDEX) { + if (sme->key_idx > WMI_MAX_KEY_INDEX) { ath6kl_err("key index %d out of bounds\n", sme->key_idx); up(&ar->sem); @@ -997,7 +996,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, params->key); } - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1115,7 +1114,7 @@ static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1148,7 +1147,7 @@ static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); @@ -1184,7 +1183,7 @@ static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy, if (!ath6kl_cfg80211_ready(vif)) return -EIO; - if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { + if (key_index > WMI_MAX_KEY_INDEX) { ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: key index %d out of bounds\n", __func__, key_index); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index f3d0184a5ce..f74986d6209 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -363,7 +363,7 @@ static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif) u8 index; u8 keyusage; - for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { + for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) { if (vif->wep_key_list[index].key_len) { keyusage = GROUP_USAGE; if (index == vif->def_txkey_index) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 9f8425b97db..2b435994b01 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -649,7 +649,6 @@ enum auth_mode { WPA2_AUTH_CCKM = 0x40, }; -#define WMI_MIN_KEY_INDEX 0 #define WMI_MAX_KEY_INDEX 3 #define WMI_MAX_KEY_LEN 32 -- cgit v1.2.3-70-g09d2 From 4f34dacea117029dbad1f0f50d68207b97546d1e Mon Sep 17 00:00:00 2001 From: Thomas Pedersen Date: Fri, 30 Dec 2011 01:57:00 -0800 Subject: ath6kl: send TCMD response through testmode events ath6kl no longer knows what it is transmitting through cfg80211_testmode, and simply passes opaque buffers between userspace and the firmware. Leave the CONT_RX enum for backwards compatibility. kvalo: change ATH6KL_TM_CMD_RX_REPORT to return -EOPNOTSUPP Signed-off-by: Thomas Pedersen Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/testmode.c | 102 +++++------------------------ drivers/net/wireless/ath/ath6kl/testmode.h | 6 +- drivers/net/wireless/ath/ath6kl/wmi.c | 6 +- 3 files changed, 23 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c index 381eb66a605..f0cd61d6188 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.c +++ b/drivers/net/wireless/ath/ath6kl/testmode.c @@ -15,6 +15,7 @@ */ #include "testmode.h" +#include "debug.h" #include @@ -30,7 +31,7 @@ enum ath6kl_tm_attr { enum ath6kl_tm_cmd { ATH6KL_TM_CMD_TCMD = 0, - ATH6KL_TM_CMD_RX_REPORT = 1, + ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */ }; #define ATH6KL_TM_DATA_MAX_LEN 5000 @@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = { .len = ATH6KL_TM_DATA_MAX_LEN }, }; -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len) { - if (down_interruptible(&ar->sem)) - return; - - kfree(ar->tm.rx_report); - - ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL); - ar->tm.rx_report_len = buf_len; - - up(&ar->sem); - - wake_up(&ar->event_wq); -} - -static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len, - struct sk_buff *skb) -{ - int ret = 0; - long left; - - if (down_interruptible(&ar->sem)) - return -ERESTARTSYS; - - if (!test_bit(WMI_READY, &ar->flag)) { - ret = -EIO; - goto out; - } - - if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) { - ret = -EBUSY; - goto out; - } - - if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) { - up(&ar->sem); - return -EIO; - } - - left = wait_event_interruptible_timeout(ar->event_wq, - ar->tm.rx_report != NULL, - WMI_TIMEOUT); + struct sk_buff *skb; - if (left == 0) { - ret = -ETIMEDOUT; - goto out; - } else if (left < 0) { - ret = left; - goto out; - } + if (!buf || buf_len == 0) + return; - if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) { - ret = -EINVAL; - goto out; + skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL); + if (!skb) { + ath6kl_warn("failed to allocate testmode rx skb!\n"); + return; } - - NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len, - ar->tm.rx_report); - - kfree(ar->tm.rx_report); - ar->tm.rx_report = NULL; - -out: - up(&ar->sem); - - return ret; + NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD); + NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf); + cfg80211_testmode_event(skb, GFP_KERNEL); + return; nla_put_failure: - ret = -ENOBUFS; - goto out; + kfree_skb(skb); + ath6kl_warn("nla_put failed on testmode rx skb!\n"); } int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) { struct ath6kl *ar = wiphy_priv(wiphy); struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; - int err, buf_len, reply_len; - struct sk_buff *skb; + int err, buf_len; void *buf; err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, @@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) break; case ATH6KL_TM_CMD_RX_REPORT: - if (!tb[ATH6KL_TM_ATTR_DATA]) - return -EINVAL; - - buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]); - buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]); - - reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN); - skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len); - if (!skb) - return -ENOMEM; - - err = ath6kl_tm_rx_report(ar, buf, buf_len, skb); - if (err < 0) { - kfree_skb(skb); - return err; - } - - return cfg80211_testmode_reply(skb); default: return -EOPNOTSUPP; } diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h index 43dffcc11fb..7fd47a62d07 100644 --- a/drivers/net/wireless/ath/ath6kl/testmode.h +++ b/drivers/net/wireless/ath/ath6kl/testmode.h @@ -18,13 +18,13 @@ #ifdef CONFIG_NL80211_TESTMODE -void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); +void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); #else -static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, - size_t buf_len) +static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, + size_t buf_len) { } diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 1e31c38abb4..c6ca660d270 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -1145,9 +1145,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len) return 0; } -static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) +static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len) { - ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len); + ath6kl_tm_rx_event(wmi->parent_dev, datap, len); return 0; } @@ -3402,7 +3402,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) break; case WMI_TEST_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n"); - ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len); + ret = ath6kl_wmi_test_rx(wmi, datap, len); break; case WMI_GET_FIXRATES_CMDID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); -- cgit v1.2.3-70-g09d2 From cd42f4a3b2b1c4cbd997363dc57821953d73fd87 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Thu, 15 Dec 2011 10:48:12 -0800 Subject: HWPOISON: Clean up memory_failure() vs. __memory_failure() There is only one caller of memory_failure(), all other users call __memory_failure() and pass in the flags argument explicitly. The lone user of memory_failure() will soon need to pass flags too. Add flags argument to the callsite in mce.c. Delete the old memory_failure() function, and then rename __memory_failure() without the leading "__". Provide clearer message when action optional memory errors are ignored. Acked-by: Borislav Petkov Signed-off-by: Tony Luck --- arch/x86/kernel/cpu/mcheck/mce.c | 12 +++++++---- drivers/base/memory.c | 2 +- include/linux/mm.h | 3 +-- mm/hwpoison-inject.c | 4 ++-- mm/madvise.c | 2 +- mm/memory-failure.c | 46 ++++++++++++++++++---------------------- 6 files changed, 34 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 2af127d4c3d..1a08ce5f345 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c @@ -1046,11 +1046,15 @@ out: } EXPORT_SYMBOL_GPL(do_machine_check); -/* dummy to break dependency. actual code is in mm/memory-failure.c */ -void __attribute__((weak)) memory_failure(unsigned long pfn, int vector) +#ifndef CONFIG_MEMORY_FAILURE +int memory_failure(unsigned long pfn, int vector, int flags) { - printk(KERN_ERR "Action optional memory failure at %lx ignored\n", pfn); + printk(KERN_ERR "Uncorrected memory error in page 0x%lx ignored\n" + "Rebuild kernel with CONFIG_MEMORY_FAILURE=y for smarter handling\n", pfn); + + return 0; } +#endif /* * Called after mce notification in process context. This code @@ -1068,7 +1072,7 @@ void mce_notify_process(void) unsigned long pfn; mce_notify_irq(); while (mce_ring_get(&pfn)) - memory_failure(pfn, MCE_VECTOR); + memory_failure(pfn, MCE_VECTOR, 0); } static void mce_process_work(struct work_struct *dummy) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 8272d92d22c..9a924440053 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -474,7 +474,7 @@ store_hard_offline_page(struct class *class, if (strict_strtoull(buf, 0, &pfn) < 0) return -EINVAL; pfn >>= PAGE_SHIFT; - ret = __memory_failure(pfn, 0, 0); + ret = memory_failure(pfn, 0, 0); return ret ? ret : count; } diff --git a/include/linux/mm.h b/include/linux/mm.h index 4baadd18f4a..bcc52347472 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1607,8 +1607,7 @@ void vmemmap_populate_print_last(void); enum mf_flags { MF_COUNT_INCREASED = 1 << 0, }; -extern void memory_failure(unsigned long pfn, int trapno); -extern int __memory_failure(unsigned long pfn, int trapno, int flags); +extern int memory_failure(unsigned long pfn, int trapno, int flags); extern void memory_failure_queue(unsigned long pfn, int trapno, int flags); extern int unpoison_memory(unsigned long pfn); extern int sysctl_memory_failure_early_kill; diff --git a/mm/hwpoison-inject.c b/mm/hwpoison-inject.c index c7fc7fd00e3..cc448bb983b 100644 --- a/mm/hwpoison-inject.c +++ b/mm/hwpoison-inject.c @@ -45,7 +45,7 @@ static int hwpoison_inject(void *data, u64 val) * do a racy check with elevated page count, to make sure PG_hwpoison * will only be set for the targeted owner (or on a free page). * We temporarily take page lock for try_get_mem_cgroup_from_page(). - * __memory_failure() will redo the check reliably inside page lock. + * memory_failure() will redo the check reliably inside page lock. */ lock_page(hpage); err = hwpoison_filter(hpage); @@ -55,7 +55,7 @@ static int hwpoison_inject(void *data, u64 val) inject: printk(KERN_INFO "Injecting memory failure at pfn %lx\n", pfn); - return __memory_failure(pfn, 18, MF_COUNT_INCREASED); + return memory_failure(pfn, 18, MF_COUNT_INCREASED); } static int hwpoison_unpoison(void *data, u64 val) diff --git a/mm/madvise.c b/mm/madvise.c index 74bf193eff0..f5ab745672b 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -251,7 +251,7 @@ static int madvise_hwpoison(int bhv, unsigned long start, unsigned long end) printk(KERN_INFO "Injecting memory failure for page %lx at %lx\n", page_to_pfn(p), start); /* Ignore return value for now */ - __memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED); + memory_failure(page_to_pfn(p), 0, MF_COUNT_INCREASED); } return ret; } diff --git a/mm/memory-failure.c b/mm/memory-failure.c index 06d3479513a..ab259bb0adc 100644 --- a/mm/memory-failure.c +++ b/mm/memory-failure.c @@ -984,7 +984,25 @@ static void clear_page_hwpoison_huge_page(struct page *hpage) ClearPageHWPoison(hpage + i); } -int __memory_failure(unsigned long pfn, int trapno, int flags) +/** + * memory_failure - Handle memory failure of a page. + * @pfn: Page Number of the corrupted page + * @trapno: Trap number reported in the signal to user space. + * @flags: fine tune action taken + * + * This function is called by the low level machine check code + * of an architecture when it detects hardware memory corruption + * of a page. It tries its best to recover, which includes + * dropping pages, killing processes etc. + * + * The function is primarily of use for corruptions that + * happen outside the current execution context (e.g. when + * detected by a background scrubber) + * + * Must run in process context (e.g. a work queue) with interrupts + * enabled and no spinlocks hold. + */ +int memory_failure(unsigned long pfn, int trapno, int flags) { struct page_state *ps; struct page *p; @@ -1156,29 +1174,7 @@ out: unlock_page(hpage); return res; } -EXPORT_SYMBOL_GPL(__memory_failure); - -/** - * memory_failure - Handle memory failure of a page. - * @pfn: Page Number of the corrupted page - * @trapno: Trap number reported in the signal to user space. - * - * This function is called by the low level machine check code - * of an architecture when it detects hardware memory corruption - * of a page. It tries its best to recover, which includes - * dropping pages, killing processes etc. - * - * The function is primarily of use for corruptions that - * happen outside the current execution context (e.g. when - * detected by a background scrubber) - * - * Must run in process context (e.g. a work queue) with interrupts - * enabled and no spinlocks hold. - */ -void memory_failure(unsigned long pfn, int trapno) -{ - __memory_failure(pfn, trapno, 0); -} +EXPORT_SYMBOL_GPL(memory_failure); #define MEMORY_FAILURE_FIFO_ORDER 4 #define MEMORY_FAILURE_FIFO_SIZE (1 << MEMORY_FAILURE_FIFO_ORDER) @@ -1251,7 +1247,7 @@ static void memory_failure_work_func(struct work_struct *work) spin_unlock_irqrestore(&mf_cpu->lock, proc_flags); if (!gotten) break; - __memory_failure(entry.pfn, entry.trapno, entry.flags); + memory_failure(entry.pfn, entry.trapno, entry.flags); } } -- cgit v1.2.3-70-g09d2 From 9c636baf8518d0f986004b40669b75506459beac Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 17:19:45 +0000 Subject: sfc: Fix some formatting errors reported by checkpatch Fix the following errors and warnings: ERROR: trailing whitespace ERROR: spaces required around that '=' (ctx:VxV) WARNING: please, no space before tabs Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/bitfield.h | 18 +++++++++--------- drivers/net/ethernet/sfc/efx.c | 16 ++++++++-------- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon_xmac.c | 2 +- drivers/net/ethernet/sfc/mcdi_mac.c | 2 +- drivers/net/ethernet/sfc/mcdi_phy.c | 2 +- drivers/net/ethernet/sfc/mdio_10g.c | 2 +- drivers/net/ethernet/sfc/nic.c | 2 +- drivers/net/ethernet/sfc/qt202x_phy.c | 6 +++--- drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/spi.h | 2 +- drivers/net/ethernet/sfc/tenxpress.c | 2 +- 12 files changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/bitfield.h b/drivers/net/ethernet/sfc/bitfield.h index 098ac2ad757..a2a9f40b90c 100644 --- a/drivers/net/ethernet/sfc/bitfield.h +++ b/drivers/net/ethernet/sfc/bitfield.h @@ -448,40 +448,40 @@ typedef union efx_oword { EFX_INSERT32(min, max, low, high, EFX_MASK32(high + 1 - low)) #define EFX_SET_OWORD64(oword, low, high, value) do { \ - (oword).u64[0] = (((oword).u64[0] \ + (oword).u64[0] = (((oword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ - (oword).u64[1] = (((oword).u64[1] \ + (oword).u64[1] = (((oword).u64[1] \ & ~EFX_INPLACE_MASK64(64, 127, low, high)) \ | EFX_INSERT64(64, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD64(qword, low, high, value) do { \ - (qword).u64[0] = (((qword).u64[0] \ + (qword).u64[0] = (((qword).u64[0] \ & ~EFX_INPLACE_MASK64(0, 63, low, high)) \ | EFX_INSERT64(0, 63, low, high, value)); \ } while (0) #define EFX_SET_OWORD32(oword, low, high, value) do { \ - (oword).u32[0] = (((oword).u32[0] \ + (oword).u32[0] = (((oword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (oword).u32[1] = (((oword).u32[1] \ + (oword).u32[1] = (((oword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ - (oword).u32[2] = (((oword).u32[2] \ + (oword).u32[2] = (((oword).u32[2] \ & ~EFX_INPLACE_MASK32(64, 95, low, high)) \ | EFX_INSERT32(64, 95, low, high, value)); \ - (oword).u32[3] = (((oword).u32[3] \ + (oword).u32[3] = (((oword).u32[3] \ & ~EFX_INPLACE_MASK32(96, 127, low, high)) \ | EFX_INSERT32(96, 127, low, high, value)); \ } while (0) #define EFX_SET_QWORD32(qword, low, high, value) do { \ - (qword).u32[0] = (((qword).u32[0] \ + (qword).u32[0] = (((qword).u32[0] \ & ~EFX_INPLACE_MASK32(0, 31, low, high)) \ | EFX_INSERT32(0, 31, low, high, value)); \ - (qword).u32[1] = (((qword).u32[1] \ + (qword).u32[1] = (((qword).u32[1] \ & ~EFX_INPLACE_MASK32(32, 63, low, high)) \ | EFX_INSERT32(32, 63, low, high, value)); \ } while (0) diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index e43702f33b6..11cc585c36a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -44,9 +44,9 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_GMAC] = "GMAC", [LOOPBACK_XGMII] = "XGMII", [LOOPBACK_XGXS] = "XGXS", - [LOOPBACK_XAUI] = "XAUI", - [LOOPBACK_GMII] = "GMII", - [LOOPBACK_SGMII] = "SGMII", + [LOOPBACK_XAUI] = "XAUI", + [LOOPBACK_GMII] = "GMII", + [LOOPBACK_SGMII] = "SGMII", [LOOPBACK_XGBR] = "XGBR", [LOOPBACK_XFI] = "XFI", [LOOPBACK_XAUI_FAR] = "XAUI_FAR", @@ -55,17 +55,17 @@ const char *efx_loopback_mode_names[] = { [LOOPBACK_XFI_FAR] = "XFI_FAR", [LOOPBACK_GPHY] = "GPHY", [LOOPBACK_PHYXS] = "PHYXS", - [LOOPBACK_PCS] = "PCS", - [LOOPBACK_PMAPMD] = "PMA/PMD", + [LOOPBACK_PCS] = "PCS", + [LOOPBACK_PMAPMD] = "PMA/PMD", [LOOPBACK_XPORT] = "XPORT", [LOOPBACK_XGMII_WS] = "XGMII_WS", - [LOOPBACK_XAUI_WS] = "XAUI_WS", + [LOOPBACK_XAUI_WS] = "XAUI_WS", [LOOPBACK_XAUI_WS_FAR] = "XAUI_WS_FAR", [LOOPBACK_XAUI_WS_NEAR] = "XAUI_WS_NEAR", - [LOOPBACK_GMII_WS] = "GMII_WS", + [LOOPBACK_GMII_WS] = "GMII_WS", [LOOPBACK_XFI_WS] = "XFI_WS", [LOOPBACK_XFI_WS_FAR] = "XFI_WS_FAR", - [LOOPBACK_PHYXS_WS] = "PHYXS_WS", + [LOOPBACK_PHYXS_WS] = "PHYXS_WS", }; const unsigned int efx_reset_type_max = RESET_TYPE_MAX; diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 29b2ebfef19..c090de4e66c 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -68,11 +68,11 @@ static u64 efx_get_atomic_stat(void *field) } #define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ + EFX_ETHTOOL_STAT(field, mac_stats, field, \ unsigned long, efx_get_ulong_stat) #define EFX_ETHTOOL_U64_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ + EFX_ETHTOOL_STAT(field, mac_stats, field, \ u64, efx_get_u64_stat) #define EFX_ETHTOOL_UINT_NIC_STAT(name) \ diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c index 9516452c079..57434593f07 100644 --- a/drivers/net/ethernet/sfc/falcon_xmac.c +++ b/drivers/net/ethernet/sfc/falcon_xmac.c @@ -139,7 +139,7 @@ static bool falcon_xmac_link_ok(struct efx_nic *efx) return (efx->loopback_mode == LOOPBACK_XGMII || falcon_xgxs_link_ok(efx)) && (!(efx->mdio.mmds & (1 << MDIO_MMD_PHYXS)) || - LOOPBACK_INTERNAL(efx) || + LOOPBACK_INTERNAL(efx) || efx_mdio_phyxgxs_lane_sync(efx)); } diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 50c20777a56..aa4052c500f 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -141,5 +141,5 @@ static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) const struct efx_mac_operations efx_mcdi_mac_operations = { .reconfigure = efx_mcdi_mac_reconfigure, .update_stats = efx_port_dummy_op_void, - .check_fault = efx_mcdi_mac_check_fault, + .check_fault = efx_mcdi_mac_check_fault, }; diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c index 6c63ab0710a..3077bf1e7df 100644 --- a/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/drivers/net/ethernet/sfc/mcdi_phy.c @@ -741,7 +741,7 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, const struct efx_phy_operations efx_mcdi_phy_ops = { .probe = efx_mcdi_phy_probe, - .init = efx_port_dummy_op_int, + .init = efx_port_dummy_op_int, .reconfigure = efx_mcdi_phy_reconfigure, .poll = efx_mcdi_phy_poll, .fini = efx_port_dummy_op_void, diff --git a/drivers/net/ethernet/sfc/mdio_10g.c b/drivers/net/ethernet/sfc/mdio_10g.c index 7ab385c8136..9acfd6696ff 100644 --- a/drivers/net/ethernet/sfc/mdio_10g.c +++ b/drivers/net/ethernet/sfc/mdio_10g.c @@ -228,7 +228,7 @@ void efx_mdio_set_mmds_lpower(struct efx_nic *efx, /** * efx_mdio_set_settings - Set (some of) the PHY settings over MDIO. * @efx: Efx NIC - * @ecmd: New settings + * @ecmd: New settings */ int efx_mdio_set_settings(struct efx_nic *efx, struct ethtool_cmd *ecmd) { diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 3edfbaf5f02..b1df2f39c8f 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -1837,7 +1837,7 @@ struct efx_nic_reg_table { REGISTER_REVISION_ ## min_rev, REGISTER_REVISION_ ## max_rev, \ step, rows \ } -#define REGISTER_TABLE(name, min_rev, max_rev) \ +#define REGISTER_TABLE(name, min_rev, max_rev) \ REGISTER_TABLE_DIMENSIONS( \ name, FR_ ## min_rev ## max_rev ## _ ## name, \ min_rev, max_rev, \ diff --git a/drivers/net/ethernet/sfc/qt202x_phy.c b/drivers/net/ethernet/sfc/qt202x_phy.c index 7ad97e39740..8a7caf88ffb 100644 --- a/drivers/net/ethernet/sfc/qt202x_phy.c +++ b/drivers/net/ethernet/sfc/qt202x_phy.c @@ -47,7 +47,7 @@ #define PMA_PMD_FTX_STATIC_LBN 13 #define PMA_PMD_VEND1_REG 0xc001 #define PMA_PMD_VEND1_LBTXD_LBN 15 -#define PCS_VEND1_REG 0xc000 +#define PCS_VEND1_REG 0xc000 #define PCS_VEND1_LBTXD_LBN 5 void falcon_qt202x_set_led(struct efx_nic *p, int led, int mode) @@ -453,9 +453,9 @@ const struct efx_phy_operations falcon_qt202x_phy_ops = { .probe = qt202x_phy_probe, .init = qt202x_phy_init, .reconfigure = qt202x_phy_reconfigure, - .poll = qt202x_phy_poll, + .poll = qt202x_phy_poll, .fini = efx_port_dummy_op_void, - .remove = qt202x_phy_remove, + .remove = qt202x_phy_remove, .get_settings = qt202x_phy_get_settings, .set_settings = efx_mdio_set_settings, .test_alive = efx_mdio_test_alive, diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 52edd24fcde..fc62fe2f766 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -445,7 +445,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, /* Count the number of tx completions, and decrement the refcnt. Any * skbs not already completed will be free'd when the queue is flushed */ - for (i=0; i < state->packet_count; i++) { + for (i = 0; i < state->packet_count; i++) { skb = state->skbs[i]; if (skb && !skb_shared(skb)) ++tx_done; diff --git a/drivers/net/ethernet/sfc/spi.h b/drivers/net/ethernet/sfc/spi.h index 71f2e3ebe1c..5431a1bbff5 100644 --- a/drivers/net/ethernet/sfc/spi.h +++ b/drivers/net/ethernet/sfc/spi.h @@ -68,7 +68,7 @@ static inline bool efx_spi_present(const struct efx_spi_device *spi) int falcon_spi_cmd(struct efx_nic *efx, const struct efx_spi_device *spi, unsigned int command, - int address, const void* in, void *out, size_t len); + int address, const void *in, void *out, size_t len); int falcon_spi_wait_write(struct efx_nic *efx, const struct efx_spi_device *spi); int falcon_spi_read(struct efx_nic *efx, diff --git a/drivers/net/ethernet/sfc/tenxpress.c b/drivers/net/ethernet/sfc/tenxpress.c index 7b0fd89e7b8..d37cb501712 100644 --- a/drivers/net/ethernet/sfc/tenxpress.c +++ b/drivers/net/ethernet/sfc/tenxpress.c @@ -121,7 +121,7 @@ #define GPHY_XCONTROL_REG 49152 #define GPHY_ISOLATE_LBN 10 #define GPHY_ISOLATE_WIDTH 1 -#define GPHY_DUPLEX_LBN 8 +#define GPHY_DUPLEX_LBN 8 #define GPHY_DUPLEX_WIDTH 1 #define GPHY_LOOPBACK_NEAR_LBN 14 #define GPHY_LOOPBACK_NEAR_WIDTH 1 -- cgit v1.2.3-70-g09d2 From e9e01846c7e18a3b5682b54e50f1005949737bd9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 18:50:29 +0000 Subject: sfc: Avoid assignment in an if-statement, reported by checkpatch Fix the following error: ERROR: do not use assignment in if condition Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 11cc585c36a..0539a8d88a2 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1069,9 +1069,11 @@ static int efx_init_io(struct efx_nic *efx) * masks event though they reject 46 bit masks. */ while (dma_mask > 0x7fffffffUL) { - if (pci_dma_supported(pci_dev, dma_mask) && - ((rc = pci_set_dma_mask(pci_dev, dma_mask)) == 0)) - break; + if (pci_dma_supported(pci_dev, dma_mask)) { + rc = pci_set_dma_mask(pci_dev, dma_mask); + if (rc == 0) + break; + } dma_mask >>= 1; } if (rc) { -- cgit v1.2.3-70-g09d2 From 0beaca2ca0b3c12dabab046f1541b09179ec449c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 18:54:04 +0000 Subject: sfc: Remove parentheses around return expressions, reported by checkpatch Fix the following error: ERROR: return is not a function, parentheses are not required Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index aca34986176..3572c34a79f 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -98,8 +98,8 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, /* Offset is always within one page, so we don't need to consider * the page order. */ - return (((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + - efx->type->rx_buffer_hash_size); + return ((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -111,8 +111,7 @@ static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) if (buf->is_page) return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); else - return ((u8 *)buf->u.skb->data + - efx->type->rx_buffer_hash_size); + return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size; } static inline u32 efx_rx_buf_hash(const u8 *eh) @@ -122,10 +121,10 @@ static inline u32 efx_rx_buf_hash(const u8 *eh) return __le32_to_cpup((const __le32 *)(eh - 4)); #else const u8 *data = eh - 4; - return ((u32)data[0] | - (u32)data[1] << 8 | - (u32)data[2] << 16 | - (u32)data[3] << 24); + return (u32)data[0] | + (u32)data[1] << 8 | + (u32)data[2] << 16 | + (u32)data[3] << 24; #endif } -- cgit v1.2.3-70-g09d2 From 3f3c4ee735ff0957a53b9dccae66c8e5ead25b17 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:41:59 +0530 Subject: ath6kl: Add a function in wmi to send WMI_MCAST_FILTER_CMDID This will be used to disable/enable multicast receive. Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/wmi.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c6ca660d270..d3eec0761ea 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2855,6 +2855,23 @@ int ath6kl_wmi_test_cmd(struct wmi *wmi, void *buf, size_t len) return ret; } +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_cmd *cmd; + int ret; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_cmd *) skb->data; + cmd->mcast_all_enable = mc_all_on; + + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + return ret; +} s32 ath6kl_wmi_get_rate(s8 rate_index) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 2b435994b01..dc704571155 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1239,6 +1239,10 @@ enum target_event_report_config { NO_DISCONN_EVT_IN_RECONN }; +struct wmi_mcast_filter_cmd { + u8 mcast_all_enable; +} __packed; + /* Command Replies */ /* WMI_GET_CHANNEL_LIST_CMDID reply */ @@ -2434,6 +2438,7 @@ int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); +int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, -- cgit v1.2.3-70-g09d2 From f914edd38920369d8926261f9ab72da6756c3e0c Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:42:00 +0530 Subject: ath6kl: Add a function in wmi.c to add/delete a multicast filter Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/wmi.c | 28 ++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 7 +++++++ 2 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index d3eec0761ea..08fbd9a9be4 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2873,6 +2873,34 @@ int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on) return ret; } +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter) +{ + struct sk_buff *skb; + struct wmi_mcast_filter_add_del_cmd *cmd; + int ret; + + if ((filter[0] != 0x33 || filter[1] != 0x33) && + (filter[0] != 0x01 || filter[1] != 0x00 || + filter[2] != 0x5e || filter[3] > 0x7f)) { + ath6kl_warn("invalid multicast filter address\n"); + return -EINVAL; + } + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_mcast_filter_add_del_cmd *) skb->data; + memcpy(cmd->mcast_mac, filter, ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + ret = ath6kl_wmi_cmd_send(wmi, if_idx, skb, + add_filter ? WMI_SET_MCAST_FILTER_CMDID : + WMI_DEL_MCAST_FILTER_CMDID, + NO_SYNC_WMIFLAG); + + return ret; +} + s32 ath6kl_wmi_get_rate(s8 rate_index) { if (rate_index == RATE_AUTO) diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index dc704571155..eae0e4e065c 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1243,6 +1243,11 @@ struct wmi_mcast_filter_cmd { u8 mcast_all_enable; } __packed; +#define ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE 6 +struct wmi_mcast_filter_add_del_cmd { + u8 mcast_mac[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +} __packed; + /* Command Replies */ /* WMI_GET_CHANNEL_LIST_CMDID reply */ @@ -2439,6 +2444,8 @@ int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); int ath6kl_wmi_force_roam_cmd(struct wmi *wmi, const u8 *bssid); int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); +int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, + u8 *filter, bool add_filter); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, -- cgit v1.2.3-70-g09d2 From 80abaf9b4c920cab044e185ed4327f801c1ff99d Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 14:42:01 +0530 Subject: ath6kl: Implement ndo_set_rx_mode() There are maximum of seven multicast filter are supported by hw. When the requested number of filters exceeds the maximum supported one, multicast filtering is completely disabled, the requested filters will be configured in firmware and the only multicast frames that host is interested in will be passed to host for further processing otherwise. Signed-off-by: Vasanthakumar Thiagarajan --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 8 +++ drivers/net/wireless/ath/ath6kl/core.h | 9 +++ drivers/net/wireless/ath/ath6kl/main.c | 110 +++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 2a166cc7cc3..14f180eac48 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2818,12 +2818,15 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) set_bit(WMM_ENABLED, &vif->flags); spin_lock_init(&vif->if_lock); + INIT_LIST_HEAD(&vif->mc_filter); + return 0; } void ath6kl_deinit_if_data(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; + struct ath6kl_mc_filter *mc_filter, *tmp; aggr_module_destroy(vif->aggr_cntxt); @@ -2832,6 +2835,11 @@ void ath6kl_deinit_if_data(struct ath6kl_vif *vif) if (vif->nw_type == ADHOC_NETWORK) ar->ibss_if_active = false; + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + list_del(&mc_filter->list); + kfree(mc_filter); + } + unregister_netdevice(vif->ndev); ar->num_vif--; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index c095fafa278..793c6a58f0f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -410,6 +410,13 @@ enum ath6kl_hif_type { ATH6KL_HIF_TYPE_USB, }; +/* Max number of filters that hw supports */ +#define ATH6K_MAX_MC_FILTERS_PER_LIST 7 +struct ath6kl_mc_filter { + struct list_head list; + char hw_addr[ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE]; +}; + /* * Driver's maximum limit, note that some firmwares support only one vif * and the runtime (current) limit must be checked from ar->vif_max. @@ -473,6 +480,8 @@ struct ath6kl_vif { u8 assoc_bss_dtim_period; struct net_device_stats net_stats; struct target_stats target_stats; + + struct list_head mc_filter; }; #define WOW_LIST_ID 0 diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index f74986d6209..cffbc62ee79 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1052,12 +1052,122 @@ static int ath6kl_set_features(struct net_device *dev, u32 features) return err; } +static void ath6kl_set_multicast_list(struct net_device *ndev) +{ + struct ath6kl_vif *vif = netdev_priv(ndev); + bool mc_all_on = false, mc_all_off = false; + int mc_count = netdev_mc_count(ndev); + struct netdev_hw_addr *ha; + bool found; + struct ath6kl_mc_filter *mc_filter, *tmp; + struct list_head mc_filter_new; + int ret; + + if (!test_bit(WMI_READY, &vif->ar->flag) || + !test_bit(WLAN_ENABLED, &vif->flags)) + return; + + mc_all_on = !!(ndev->flags & IFF_PROMISC) || + !!(ndev->flags & IFF_ALLMULTI) || + !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST); + + mc_all_off = !(ndev->flags & IFF_MULTICAST) || mc_count == 0; + + if (mc_all_on || mc_all_off) { + /* Enable/disable all multicast */ + ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast filter\n", + mc_all_on ? "enabling" : "disabling"); + ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx, + mc_all_on); + if (ret) + ath6kl_warn("Failed to %s multicast receive\n", + mc_all_on ? "enable" : "disable"); + return; + } + + list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) { + found = false; + netdev_for_each_mc_addr(ha, ndev) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + /* + * Delete the filter which was previously set + * but not in the new request. + */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Removing %pM from multicast filter\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + false); + if (ret) { + ath6kl_warn("Failed to remove multicast filter:%pM\n", + mc_filter->hw_addr); + return; + } + + list_del(&mc_filter->list); + kfree(mc_filter); + } + } + + INIT_LIST_HEAD(&mc_filter_new); + + netdev_for_each_mc_addr(ha, ndev) { + found = false; + list_for_each_entry(mc_filter, &vif->mc_filter, list) { + if (memcmp(ha->addr, mc_filter->hw_addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) { + found = true; + break; + } + } + + if (!found) { + mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter), + GFP_ATOMIC); + if (!mc_filter) { + WARN_ON(1); + goto out; + } + + memcpy(mc_filter->hw_addr, ha->addr, + ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE); + /* Set the multicast filter */ + ath6kl_dbg(ATH6KL_DBG_TRC, + "Adding %pM to multicast filter list\n", + mc_filter->hw_addr); + ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi, + vif->fw_vif_idx, mc_filter->hw_addr, + true); + if (ret) { + ath6kl_warn("Failed to add multicast filter :%pM\n", + mc_filter->hw_addr); + kfree(mc_filter); + goto out; + } + + list_add_tail(&mc_filter->list, &mc_filter_new); + } + } + +out: + list_splice_tail(&mc_filter_new, &vif->mc_filter); +} + static struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, .ndo_get_stats = ath6kl_get_stats, .ndo_set_features = ath6kl_set_features, + .ndo_set_rx_mode = ath6kl_set_multicast_list, }; void init_netdev(struct net_device *dev) -- cgit v1.2.3-70-g09d2 From 3d6aba260bcd5a5f9d47056cac2e313ce986ad12 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 15:19:02 +0530 Subject: ath6kl: Remove deadcode in main.c In ath6kl_reset_device(), since control can never reach switch..case when the target_type is neither TARGET_TYPE_AR6003 nor TARGET_TYPE_AR6004, remove the default option of switch statement. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index cffbc62ee79..d764768f8f7 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -347,9 +347,6 @@ void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, case TARGET_TYPE_AR6004: address = AR6004_RESET_CONTROL_ADDRESS; break; - default: - address = AR6003_RESET_CONTROL_ADDRESS; - break; } status = ath6kl_diag_write32(ar, address, data); -- cgit v1.2.3-70-g09d2 From 982767b8c94482b4b7f694e2ab2074c95fbf3e0e Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Tue, 3 Jan 2012 15:28:53 +0530 Subject: ath6kl: Change ielen in ath6kl_add_new_sta() from u8 to size_t Otherwise if (ielen <= ATH6KL_MAX_IE) is dead code. It looks safe to change the type of ielen from u8 to size_t instead of removing this if check, this ielen can have the length of more than one ies in future. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index d764768f8f7..325d316f40e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -53,7 +53,7 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) } static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) + size_t ielen, u8 keymgmt, u8 ucipher, u8 auth) { struct ath6kl_sta *sta; u8 free_slot; -- cgit v1.2.3-70-g09d2 From 9d82682d45ef7407474e0ae043a587cb33a7fa26 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Wed, 4 Jan 2012 15:57:19 +0530 Subject: ath6kl: Use a mutex_lock to avoid race in diabling and handling irq Currently this race is handled but in a messy way an atomic variable is being checked in a loop which sleeps upto ms in every iteration. Remove this logic and use a mutex to make sure irq is not disabled when irq handling is in progress. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 278a9f30795..8b36904ec3e 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -49,11 +49,13 @@ struct ath6kl_sdio { /* scatter request list head */ struct list_head scat_req; + /* Avoids disabling irq while the interrupts being handled */ + struct mutex mtx_irq; + spinlock_t scat_lock; bool scatter_enabled; bool is_disabled; - atomic_t irq_handling; const struct sdio_device_id *id; struct work_struct wr_async_work; struct list_head wr_asyncq; @@ -460,8 +462,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) ath6kl_dbg(ATH6KL_DBG_SDIO, "irq\n"); ar_sdio = sdio_get_drvdata(func); - atomic_set(&ar_sdio->irq_handling, 1); - + mutex_lock(&ar_sdio->mtx_irq); /* * Release the host during interrups so we can pick it back up when * we process commands. @@ -470,7 +471,7 @@ static void ath6kl_sdio_irq_handler(struct sdio_func *func) status = ath6kl_hif_intr_bh_handler(ar_sdio->ar); sdio_claim_host(ar_sdio->func); - atomic_set(&ar_sdio->irq_handling, 0); + mutex_unlock(&ar_sdio->mtx_irq); WARN_ON(status && status != -ECANCELED); } @@ -578,17 +579,14 @@ static void ath6kl_sdio_irq_disable(struct ath6kl *ar) sdio_claim_host(ar_sdio->func); - /* Mask our function IRQ */ - while (atomic_read(&ar_sdio->irq_handling)) { - sdio_release_host(ar_sdio->func); - schedule_timeout(HZ / 10); - sdio_claim_host(ar_sdio->func); - } + mutex_lock(&ar_sdio->mtx_irq); ret = sdio_release_irq(ar_sdio->func); if (ret) ath6kl_err("Failed to release sdio irq: %d\n", ret); + mutex_unlock(&ar_sdio->mtx_irq); + sdio_release_host(ar_sdio->func); } @@ -1253,6 +1251,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, spin_lock_init(&ar_sdio->scat_lock); spin_lock_init(&ar_sdio->wr_async_lock); mutex_init(&ar_sdio->dma_buffer_mutex); + mutex_init(&ar_sdio->mtx_irq); INIT_LIST_HEAD(&ar_sdio->scat_req); INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); -- cgit v1.2.3-70-g09d2 From 4269a930548966014dd4186a15c8e023ca4abc29 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 5 Jan 2012 10:39:48 -0800 Subject: ath6kl: make net_device_ops const Signed-off-by: Stephen Hemminger Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 325d316f40e..8742eaa7818 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1158,7 +1158,7 @@ out: list_splice_tail(&mc_filter_new, &vif->mc_filter); } -static struct net_device_ops ath6kl_netdev_ops = { +static const struct net_device_ops ath6kl_netdev_ops = { .ndo_open = ath6kl_open, .ndo_stop = ath6kl_close, .ndo_start_xmit = ath6kl_data_tx, -- cgit v1.2.3-70-g09d2 From 18e83e4cd144e30fb38bf1f714914182c6c8bced Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 19:05:20 +0000 Subject: sfc: Const-qualify static data as appropriate, partly prompted by checkpatch Fix the following warnings: WARNING: struct dev_pm_ops should normally be const WARNING: static const char * array should probably be static const char * const Similarly const-qualify struct i2c_board_info, struct i2c_algo_bit_data, struct efx_ethtool_stat, struct efx_mtd_ops and struct siena_nvram_type_info. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 +++--- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon.c | 2 +- drivers/net/ethernet/sfc/falcon_boards.c | 12 ++++++------ drivers/net/ethernet/sfc/mcdi.c | 4 ++-- drivers/net/ethernet/sfc/mtd.c | 8 ++++---- drivers/net/ethernet/sfc/net_driver.h | 4 ++-- drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/txc43128_phy.c | 2 +- 9 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 0539a8d88a2..9ca5dcdf5a8 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -38,7 +38,7 @@ /* Loopback mode names (see LOOPBACK_MODE()) */ const unsigned int efx_loopback_mode_max = LOOPBACK_MAX; -const char *efx_loopback_mode_names[] = { +const char *const efx_loopback_mode_names[] = { [LOOPBACK_NONE] = "NONE", [LOOPBACK_DATA] = "DATAPATH", [LOOPBACK_GMAC] = "GMAC", @@ -69,7 +69,7 @@ const char *efx_loopback_mode_names[] = { }; const unsigned int efx_reset_type_max = RESET_TYPE_MAX; -const char *efx_reset_type_names[] = { +const char *const efx_reset_type_names[] = { [RESET_TYPE_INVISIBLE] = "INVISIBLE", [RESET_TYPE_ALL] = "ALL", [RESET_TYPE_WORLD] = "WORLD", @@ -2660,7 +2660,7 @@ static int efx_pm_suspend(struct device *dev) return rc; } -static struct dev_pm_ops efx_pm_ops = { +static const struct dev_pm_ops efx_pm_ops = { .suspend = efx_pm_suspend, .resume = efx_pm_resume, .freeze = efx_pm_freeze, diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index c090de4e66c..52c9ee4c8aa 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -91,7 +91,7 @@ static u64 efx_get_atomic_stat(void *field) EFX_ETHTOOL_STAT(tx_##field, tx_queue, field, \ unsigned int, efx_get_uint_stat) -static struct efx_ethtool_stat efx_ethtool_stats[] = { +static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), @@ -486,7 +486,7 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, { struct efx_nic *efx = netdev_priv(net_dev); struct efx_mac_stats *mac_stats = &efx->mac_stats; - struct efx_ethtool_stat *stat; + const struct efx_ethtool_stat *stat; struct efx_channel *channel; struct efx_tx_queue *tx_queue; struct rtnl_link_stats64 temp; diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 8ae1ebd3539..5c7548959dd 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -89,7 +89,7 @@ static int falcon_getscl(void *data) return EFX_OWORD_FIELD(reg, FRF_AB_GPIO0_IN); } -static struct i2c_algo_bit_data falcon_i2c_bit_operations = { +static const struct i2c_algo_bit_data falcon_i2c_bit_operations = { .setsda = falcon_setsda, .setscl = falcon_setscl, .getsda = falcon_getsda, diff --git a/drivers/net/ethernet/sfc/falcon_boards.c b/drivers/net/ethernet/sfc/falcon_boards.c index 6cc16b8cc6f..2084cc6ede5 100644 --- a/drivers/net/ethernet/sfc/falcon_boards.c +++ b/drivers/net/ethernet/sfc/falcon_boards.c @@ -87,7 +87,7 @@ static const u8 falcon_lm87_common_regs[] = { 0 }; -static int efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, +static int efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info, const u8 *reg_values) { struct falcon_board *board = falcon_board(efx); @@ -179,7 +179,7 @@ static int efx_check_lm87(struct efx_nic *efx, unsigned mask) #else /* !CONFIG_SENSORS_LM87 */ static inline int -efx_init_lm87(struct efx_nic *efx, struct i2c_board_info *info, +efx_init_lm87(struct efx_nic *efx, const struct i2c_board_info *info, const u8 *reg_values) { return 0; @@ -442,7 +442,7 @@ static int sfe4001_check_hw(struct efx_nic *efx) return (status < 0) ? -EIO : -ERANGE; } -static struct i2c_board_info sfe4001_hwmon_info = { +static const struct i2c_board_info sfe4001_hwmon_info = { I2C_BOARD_INFO("max6647", 0x4e), }; @@ -522,7 +522,7 @@ static const u8 sfe4002_lm87_regs[] = { 0 }; -static struct i2c_board_info sfe4002_hwmon_info = { +static const struct i2c_board_info sfe4002_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfe4002_lm87_channel, }; @@ -591,7 +591,7 @@ static const u8 sfn4112f_lm87_regs[] = { 0 }; -static struct i2c_board_info sfn4112f_hwmon_info = { +static const struct i2c_board_info sfn4112f_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfn4112f_lm87_channel, }; @@ -653,7 +653,7 @@ static const u8 sfe4003_lm87_regs[] = { 0 }; -static struct i2c_board_info sfe4003_hwmon_info = { +static const struct i2c_board_info sfe4003_hwmon_info = { I2C_BOARD_INFO("lm87", 0x2e), .platform_data = &sfe4003_lm87_channel, }; diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 81a42539746..b1de400ca24 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -502,7 +502,7 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) efx_link_status_changed(efx); } -static const char *sensor_names[] = { +static const char *const sensor_names[] = { [MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor", [MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor", [MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling", @@ -518,7 +518,7 @@ static const char *sensor_names[] = { [MC_CMD_SENSOR_IN_12V0] = "12V supply sensor" }; -static const char *sensor_status_names[] = { +static const char *const sensor_status_names[] = { [MC_CMD_SENSOR_STATE_OK] = "OK", [MC_CMD_SENSOR_STATE_WARNING] = "Warning", [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index bc9dcd6b30d..13f61fba731 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -382,7 +382,7 @@ static int falcon_mtd_sync(struct mtd_info *mtd) return rc; } -static struct efx_mtd_ops falcon_mtd_ops = { +static const struct efx_mtd_ops falcon_mtd_ops = { .read = falcon_mtd_read, .erase = falcon_mtd_erase, .write = falcon_mtd_write, @@ -560,7 +560,7 @@ static int siena_mtd_sync(struct mtd_info *mtd) return rc; } -static struct efx_mtd_ops siena_mtd_ops = { +static const struct efx_mtd_ops siena_mtd_ops = { .read = siena_mtd_read, .erase = siena_mtd_erase, .write = siena_mtd_write, @@ -572,7 +572,7 @@ struct siena_nvram_type_info { const char *name; }; -static struct siena_nvram_type_info siena_nvram_types[] = { +static const struct siena_nvram_type_info siena_nvram_types[] = { [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO] = { 0, "sfc_dummy_phy" }, [MC_CMD_NVRAM_TYPE_MC_FW] = { 0, "sfc_mcfw" }, [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP] = { 0, "sfc_mcfw_backup" }, @@ -593,7 +593,7 @@ static int siena_mtd_probe_partition(struct efx_nic *efx, unsigned int type) { struct efx_mtd_partition *part = &efx_mtd->part[part_id]; - struct siena_nvram_type_info *info; + const struct siena_nvram_type_info *info; size_t size, erase_size; bool protected; int rc; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c49502bab6a..9353ce80175 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -395,12 +395,12 @@ enum efx_led_mode { #define STRING_TABLE_LOOKUP(val, member) \ ((val) < member ## _max) ? member ## _names[val] : "(invalid)" -extern const char *efx_loopback_mode_names[]; +extern const char *const efx_loopback_mode_names[]; extern const unsigned int efx_loopback_mode_max; #define LOOPBACK_MODE(efx) \ STRING_TABLE_LOOKUP((efx)->loopback_mode, efx_loopback_mode) -extern const char *efx_reset_type_names[]; +extern const char *const efx_reset_type_names[]; extern const unsigned int efx_reset_type_max; #define RESET_TYPE(type) \ STRING_TABLE_LOOKUP(type, efx_reset_type) diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index fc62fe2f766..17ff9b39995 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -50,7 +50,7 @@ static const char payload_msg[] = /* Interrupt mode names */ static const unsigned int efx_interrupt_mode_max = EFX_INT_MODE_MAX; -static const char *efx_interrupt_mode_names[] = { +static const char *const efx_interrupt_mode_names[] = { [EFX_INT_MODE_MSIX] = "MSI-X", [EFX_INT_MODE_MSI] = "MSI", [EFX_INT_MODE_LEGACY] = "legacy", diff --git a/drivers/net/ethernet/sfc/txc43128_phy.c b/drivers/net/ethernet/sfc/txc43128_phy.c index 7c21b334a75..29bb3f9941c 100644 --- a/drivers/net/ethernet/sfc/txc43128_phy.c +++ b/drivers/net/ethernet/sfc/txc43128_phy.c @@ -512,7 +512,7 @@ static bool txc43128_phy_poll(struct efx_nic *efx) return efx->link_state.up != was_up; } -static const char *txc43128_test_names[] = { +static const char *const txc43128_test_names[] = { "bist" }; -- cgit v1.2.3-70-g09d2 From 783b6bb66d4289826b3d022ad7b8ac3666951bb6 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 19:09:24 +0000 Subject: sfc: Remove unnecessary inclusion of , prompted by checkpatch Fix the warning: WARNING: Use #include instead of There is no need for selftest.c to include the file at all. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/selftest.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 17ff9b39995..5226d9857f3 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "net_driver.h" #include "efx.h" #include "nic.h" -- cgit v1.2.3-70-g09d2 From 05a9320f7e64b69cbf612a69b7358546519ffc30 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 00:44:06 +0000 Subject: sfc: Update MCDI (firmware interface) definitions Some commands and constants have been renamed; adjust the code accordingly. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 15 +- drivers/net/ethernet/sfc/mcdi_mac.c | 16 +- drivers/net/ethernet/sfc/mcdi_pcol.h | 3542 ++++++++++++++++++++-------------- drivers/net/ethernet/sfc/mcdi_phy.c | 34 +- drivers/net/ethernet/sfc/mtd.c | 3 +- 5 files changed, 2119 insertions(+), 1491 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index b1de400ca24..7c405d16692 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -604,7 +604,7 @@ void efx_mcdi_process_event(struct efx_channel *channel, void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) { - u8 outbuf[ALIGN(MC_CMD_GET_VERSION_V1_OUT_LEN, 4)]; + u8 outbuf[ALIGN(MC_CMD_GET_VERSION_OUT_LEN, 4)]; size_t outlength; const __le16 *ver_words; int rc; @@ -616,7 +616,7 @@ void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len) if (rc) goto fail; - if (outlength < MC_CMD_GET_VERSION_V1_OUT_LEN) { + if (outlength < MC_CMD_GET_VERSION_OUT_LEN) { rc = -EIO; goto fail; } @@ -665,7 +665,7 @@ fail: int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, u16 *fw_subtype_list) { - uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LEN]; + uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN]; size_t outlen; int port_num = efx_port_num(efx); int offset; @@ -678,7 +678,7 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, if (rc) goto fail; - if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LEN) { + if (outlen < MC_CMD_GET_BOARD_CFG_OUT_LENMIN) { rc = -EIO; goto fail; } @@ -691,7 +691,8 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, if (fw_subtype_list) memcpy(fw_subtype_list, outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST, - MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN); + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM * + sizeof(fw_subtype_list[0])); return 0; @@ -779,7 +780,7 @@ int efx_mcdi_nvram_info(struct efx_nic *efx, unsigned int type, *size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_SIZE); *erase_size_out = MCDI_DWORD(outbuf, NVRAM_INFO_OUT_ERASESIZE); *protected_out = !!(MCDI_DWORD(outbuf, NVRAM_INFO_OUT_FLAGS) & - (1 << MC_CMD_NVRAM_PROTECTED_LBN)); + (1 << MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN)); return 0; fail: @@ -1060,7 +1061,7 @@ void efx_mcdi_set_id_led(struct efx_nic *efx, enum efx_led_mode mode) int efx_mcdi_reset_port(struct efx_nic *efx) { - int rc = efx_mcdi_rpc(efx, MC_CMD_PORT_RESET, NULL, 0, NULL, 0, NULL); + int rc = efx_mcdi_rpc(efx, MC_CMD_ENTITY_RESET, NULL, 0, NULL, 0, NULL); if (rc) netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index aa4052c500f..85fe24f8639 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -84,7 +84,7 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, u32 addr_hi; u32 addr_lo; - BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_LEN != 0); + BUILD_BUG_ON(MC_CMD_MAC_STATS_OUT_DMA_LEN != 0); addr_lo = ((u64)dma_addr) >> 0; addr_hi = ((u64)dma_addr) >> 32; @@ -93,13 +93,13 @@ int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_ADDR_HI, addr_hi); cmd_ptr = (efx_dword_t *)MCDI_PTR(inbuf, MAC_STATS_IN_CMD); EFX_POPULATE_DWORD_7(*cmd_ptr, - MC_CMD_MAC_STATS_CMD_DMA, !!enable, - MC_CMD_MAC_STATS_CMD_CLEAR, clear, - MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE, 1, - MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE, !!enable, - MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR, 0, - MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT, 1, - MC_CMD_MAC_STATS_CMD_PERIOD_MS, period); + MC_CMD_MAC_STATS_IN_DMA, !!enable, + MC_CMD_MAC_STATS_IN_CLEAR, clear, + MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE, 1, + MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE, !!enable, + MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR, 0, + MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT, 1, + MC_CMD_MAC_STATS_IN_PERIOD_MS, period); MCDI_SET_DWORD(inbuf, MAC_STATS_IN_DMA_LEN, dma_len); rc = efx_mcdi_rpc(efx, MC_CMD_MAC_STATS, inbuf, sizeof(inbuf), diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index 41fe06fa060..0310b9f08c9 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -22,6 +22,18 @@ /* The Scheduler has started. */ #define MC_FW_STATE_SCHED (8) +/* Siena MC shared memmory offsets */ +/* The 'doorbell' addresses are hard-wired to alert the MC when written */ +#define MC_SMEM_P0_DOORBELL_OFST 0x000 +#define MC_SMEM_P1_DOORBELL_OFST 0x004 +/* The rest of these are firmware-defined */ +#define MC_SMEM_P0_PDU_OFST 0x008 +#define MC_SMEM_P1_PDU_OFST 0x108 +#define MC_SMEM_PDU_LEN 0x100 +#define MC_SMEM_P0_PTP_TIME_OFST 0x7f0 +#define MC_SMEM_P0_STATUS_OFST 0x7f8 +#define MC_SMEM_P1_STATUS_OFST 0x7fc + /* Values to be written to the per-port status dword in shared * memory on reboot and assert */ #define MC_STATUS_DWORD_REBOOT (0xb007b007) @@ -34,6 +46,8 @@ */ #define MCDI_PCOL_VERSION 1 +/* Unused commands: 0x23, 0x27, 0x30, 0x31 */ + /** * MCDI version 1 * @@ -131,53 +145,6 @@ */ #define FSE_AZ_EV_CODE_MCDI_EVRESPONSE 0xc -#define MCDI_EVENT_DATA_LBN 0 -#define MCDI_EVENT_DATA_WIDTH 32 -#define MCDI_EVENT_CONT_LBN 32 -#define MCDI_EVENT_CONT_WIDTH 1 -#define MCDI_EVENT_LEVEL_LBN 33 -#define MCDI_EVENT_LEVEL_WIDTH 3 -#define MCDI_EVENT_LEVEL_INFO (0) -#define MCDI_EVENT_LEVEL_WARN (1) -#define MCDI_EVENT_LEVEL_ERR (2) -#define MCDI_EVENT_LEVEL_FATAL (3) -#define MCDI_EVENT_SRC_LBN 36 -#define MCDI_EVENT_SRC_WIDTH 8 -#define MCDI_EVENT_CODE_LBN 44 -#define MCDI_EVENT_CODE_WIDTH 8 -#define MCDI_EVENT_CODE_BADSSERT (1) -#define MCDI_EVENT_CODE_PMNOTICE (2) -#define MCDI_EVENT_CODE_CMDDONE (3) -#define MCDI_EVENT_CMDDONE_SEQ_LBN 0 -#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 -#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 -#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8 -#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16 -#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8 -#define MCDI_EVENT_CODE_LINKCHANGE (4) -#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0 -#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 -#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 -#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 -#define MCDI_EVENT_LINKCHANGE_SPEED_100M 1 -#define MCDI_EVENT_LINKCHANGE_SPEED_1G 2 -#define MCDI_EVENT_LINKCHANGE_SPEED_10G 3 -#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 -#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 -#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 -#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8 -#define MCDI_EVENT_CODE_SENSOREVT (5) -#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0 -#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8 -#define MCDI_EVENT_SENSOREVT_STATE_LBN 8 -#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8 -#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16 -#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16 -#define MCDI_EVENT_CODE_SCHEDERR (6) -#define MCDI_EVENT_CODE_REBOOT (7) -#define MCDI_EVENT_CODE_MAC_STATS_DMA (8) -#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 -#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 /* Non-existent command target */ #define MC_CMD_ERR_ENOENT 2 @@ -198,121 +165,24 @@ #define MC_CMD_ERR_CODE_OFST 0 +/* We define 8 "escape" commands to allow + for command number space extension */ + +#define MC_CMD_CMD_SPACE_ESCAPE_0 0x78 +#define MC_CMD_CMD_SPACE_ESCAPE_1 0x79 +#define MC_CMD_CMD_SPACE_ESCAPE_2 0x7A +#define MC_CMD_CMD_SPACE_ESCAPE_3 0x7B +#define MC_CMD_CMD_SPACE_ESCAPE_4 0x7C +#define MC_CMD_CMD_SPACE_ESCAPE_5 0x7D +#define MC_CMD_CMD_SPACE_ESCAPE_6 0x7E +#define MC_CMD_CMD_SPACE_ESCAPE_7 0x7F + +/* Vectors in the boot ROM */ +/* Point to the copycode entry point. */ +#define MC_BOOTROM_COPYCODE_VEC (0x7f4) +/* Points to the recovery mode entry point. */ +#define MC_BOOTROM_NOFLASH_VEC (0x7f8) -/* MC_CMD_READ32: (debug, variadic out) - * Read multiple 32byte words from MC memory - */ -#define MC_CMD_READ32 0x01 -#define MC_CMD_READ32_IN_LEN 8 -#define MC_CMD_READ32_IN_ADDR_OFST 0 -#define MC_CMD_READ32_IN_NUMWORDS_OFST 4 -#define MC_CMD_READ32_OUT_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_READ32_OUT_BUFFER_OFST 0 - -/* MC_CMD_WRITE32: (debug, variadic in) - * Write multiple 32byte words to MC memory - */ -#define MC_CMD_WRITE32 0x02 -#define MC_CMD_WRITE32_IN_LEN(_numwords) (((_numwords) * 4) + 4) -#define MC_CMD_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_WRITE32_IN_BUFFER_OFST 4 -#define MC_CMD_WRITE32_OUT_LEN 0 - -/* MC_CMD_COPYCODE: (debug) - * Copy MC code between two locations and jump - */ -#define MC_CMD_COPYCODE 0x03 -#define MC_CMD_COPYCODE_IN_LEN 16 -#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 -#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 -#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 -#define MC_CMD_COPYCODE_IN_JUMP_OFST 12 -/* Control should return to the caller rather than jumping */ -#define MC_CMD_COPYCODE_JUMP_NONE 1 -#define MC_CMD_COPYCODE_OUT_LEN 0 - -/* MC_CMD_SET_FUNC: (debug) - * Select function for function-specific commands. - */ -#define MC_CMD_SET_FUNC 0x04 -#define MC_CMD_SET_FUNC_IN_LEN 4 -#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 -#define MC_CMD_SET_FUNC_OUT_LEN 0 - -/* MC_CMD_GET_BOOT_STATUS: - * Get the instruction address from which the MC booted. - */ -#define MC_CMD_GET_BOOT_STATUS 0x05 -#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 -#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 -#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 -#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 -/* Reboot caused by watchdog */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_LBN (0) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_WATCHDOG_WIDTH (1) -/* MC booted from primary flash partition */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_LBN (1) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_PRIMARY_WIDTH (1) -/* MC booted from backup flash partition */ -#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_LBN (2) -#define MC_CMD_GET_BOOT_STATUS_FLAGS_BACKUP_WIDTH (1) - -/* MC_CMD_GET_ASSERTS: (debug, variadic out) - * Get (and optionally clear) the current assertion status. - * - * Only OUT.GLOBAL_FLAGS is guaranteed to exist in the completion - * payload. The other fields will only be present if - * OUT.GLOBAL_FLAGS != NO_FAILS - */ -#define MC_CMD_GET_ASSERTS 0x06 -#define MC_CMD_GET_ASSERTS_IN_LEN 4 -#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 -#define MC_CMD_GET_ASSERTS_OUT_LEN 140 -/* Assertion status flag */ -#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 -/*! No assertions have failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 1 -/*! A system-level assertion has failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 2 -/*! A thread-level assertion has failed. */ -#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 3 -/*! The system was reset by the watchdog. */ -#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 4 -/* Failing PC value */ -#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 -/* Saved GP regs */ -#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 -#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_LEN 124 -/* Failing thread address */ -#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 - -/* MC_CMD_LOG_CTRL: - * Determine the output stream for various events and messages - */ -#define MC_CMD_LOG_CTRL 0x07 -#define MC_CMD_LOG_CTRL_IN_LEN 8 -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART (1) -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ (2) -#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 -#define MC_CMD_LOG_CTRL_OUT_LEN 0 - -/* MC_CMD_GET_VERSION: - * Get version information about the MC firmware - */ -#define MC_CMD_GET_VERSION 0x08 -#define MC_CMD_GET_VERSION_IN_LEN 0 -#define MC_CMD_GET_VERSION_V0_OUT_LEN 4 -#define MC_CMD_GET_VERSION_V1_OUT_LEN 32 -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 -/* Reserved version number to indicate "any" version. */ -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff -/* The version response of a boot ROM awaiting rescue */ -#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 -#define MC_CMD_GET_VERSION_V1_OUT_PCOL_OFST 4 -/* 128bit mask of functions supported by the current firmware */ -#define MC_CMD_GET_VERSION_V1_OUT_SUPPORTED_FUNCS_OFST 8 /* The command set exported by the boot ROM (MCDI v0) */ #define MC_CMD_GET_VERSION_V0_SUPPORTED_FUNCS { \ (1 << MC_CMD_READ32) | \ @@ -320,1456 +190,2214 @@ (1 << MC_CMD_COPYCODE) | \ (1 << MC_CMD_GET_VERSION), \ 0, 0, 0 } -#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24 -/* Vectors in the boot ROM */ -/* Point to the copycode entry point. */ -#define MC_BOOTROM_COPYCODE_VEC (0x7f4) -/* Points to the recovery mode entry point. */ -#define MC_BOOTROM_NOFLASH_VEC (0x7f8) +#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \ + (MC_CMD_SENSOR_ENTRY_OFST + (_x)) + +#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + +#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + +#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(n) \ + (MC_CMD_DBI_WRITE_IN_DBIWROP_OFST + \ + MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST + \ + (n) * MC_CMD_DBIWROP_TYPEDEF_LEN) + + +/* MCDI_EVENT structuredef */ +#define MCDI_EVENT_LEN 8 +#define MCDI_EVENT_CONT_LBN 32 +#define MCDI_EVENT_CONT_WIDTH 1 +#define MCDI_EVENT_LEVEL_LBN 33 +#define MCDI_EVENT_LEVEL_WIDTH 3 +#define MCDI_EVENT_LEVEL_INFO 0x0 /* enum */ +#define MCDI_EVENT_LEVEL_WARN 0x1 /* enum */ +#define MCDI_EVENT_LEVEL_ERR 0x2 /* enum */ +#define MCDI_EVENT_LEVEL_FATAL 0x3 /* enum */ +#define MCDI_EVENT_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_SEQ_LBN 0 +#define MCDI_EVENT_CMDDONE_SEQ_WIDTH 8 +#define MCDI_EVENT_CMDDONE_DATALEN_LBN 8 +#define MCDI_EVENT_CMDDONE_DATALEN_WIDTH 8 +#define MCDI_EVENT_CMDDONE_ERRNO_LBN 16 +#define MCDI_EVENT_CMDDONE_ERRNO_WIDTH 8 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_LBN 0 +#define MCDI_EVENT_LINKCHANGE_LP_CAP_WIDTH 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_LBN 16 +#define MCDI_EVENT_LINKCHANGE_SPEED_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_SPEED_100M 0x1 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_1G 0x2 /* enum */ +#define MCDI_EVENT_LINKCHANGE_SPEED_10G 0x3 /* enum */ +#define MCDI_EVENT_LINKCHANGE_FCNTL_LBN 20 +#define MCDI_EVENT_LINKCHANGE_FCNTL_WIDTH 4 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_LBN 24 +#define MCDI_EVENT_LINKCHANGE_LINK_FLAGS_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_MONITOR_LBN 0 +#define MCDI_EVENT_SENSOREVT_MONITOR_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_STATE_LBN 8 +#define MCDI_EVENT_SENSOREVT_STATE_WIDTH 8 +#define MCDI_EVENT_SENSOREVT_VALUE_LBN 16 +#define MCDI_EVENT_SENSOREVT_VALUE_WIDTH 16 +#define MCDI_EVENT_FWALERT_DATA_LBN 8 +#define MCDI_EVENT_FWALERT_DATA_WIDTH 24 +#define MCDI_EVENT_FWALERT_REASON_LBN 0 +#define MCDI_EVENT_FWALERT_REASON_WIDTH 8 +#define MCDI_EVENT_FWALERT_REASON_SRAM_ACCESS 0x1 /* enum */ +#define MCDI_EVENT_FLR_VF_LBN 0 +#define MCDI_EVENT_FLR_VF_WIDTH 8 +#define MCDI_EVENT_TX_ERR_TXQ_LBN 0 +#define MCDI_EVENT_TX_ERR_TXQ_WIDTH 12 +#define MCDI_EVENT_TX_ERR_TYPE_LBN 12 +#define MCDI_EVENT_TX_ERR_TYPE_WIDTH 4 +#define MCDI_EVENT_TX_ERR_DL_FAIL 0x1 /* enum */ +#define MCDI_EVENT_TX_ERR_NO_EOP 0x2 /* enum */ +#define MCDI_EVENT_TX_ERR_2BIG 0x3 /* enum */ +#define MCDI_EVENT_TX_ERR_INFO_LBN 16 +#define MCDI_EVENT_TX_ERR_INFO_WIDTH 16 +#define MCDI_EVENT_TX_FLUSH_TXQ_LBN 0 +#define MCDI_EVENT_TX_FLUSH_TXQ_WIDTH 12 +#define MCDI_EVENT_PTP_ERR_TYPE_LBN 0 +#define MCDI_EVENT_PTP_ERR_TYPE_WIDTH 8 +#define MCDI_EVENT_PTP_ERR_PLL_LOST 0x1 /* enum */ +#define MCDI_EVENT_PTP_ERR_FILTER 0x2 /* enum */ +#define MCDI_EVENT_PTP_ERR_FIFO 0x3 /* enum */ +#define MCDI_EVENT_PTP_ERR_QUEUE 0x4 /* enum */ +#define MCDI_EVENT_DATA_LBN 0 +#define MCDI_EVENT_DATA_WIDTH 32 +#define MCDI_EVENT_SRC_LBN 36 +#define MCDI_EVENT_SRC_WIDTH 8 +#define MCDI_EVENT_EV_CODE_LBN 60 +#define MCDI_EVENT_EV_CODE_WIDTH 4 +#define MCDI_EVENT_CODE_LBN 44 +#define MCDI_EVENT_CODE_WIDTH 8 +#define MCDI_EVENT_CODE_BADSSERT 0x1 /* enum */ +#define MCDI_EVENT_CODE_PMNOTICE 0x2 /* enum */ +#define MCDI_EVENT_CODE_CMDDONE 0x3 /* enum */ +#define MCDI_EVENT_CODE_LINKCHANGE 0x4 /* enum */ +#define MCDI_EVENT_CODE_SENSOREVT 0x5 /* enum */ +#define MCDI_EVENT_CODE_SCHEDERR 0x6 /* enum */ +#define MCDI_EVENT_CODE_REBOOT 0x7 /* enum */ +#define MCDI_EVENT_CODE_MAC_STATS_DMA 0x8 /* enum */ +#define MCDI_EVENT_CODE_FWALERT 0x9 /* enum */ +#define MCDI_EVENT_CODE_FLR 0xa /* enum */ +#define MCDI_EVENT_CODE_TX_ERR 0xb /* enum */ +#define MCDI_EVENT_CODE_TX_FLUSH 0xc /* enum */ +#define MCDI_EVENT_CODE_PTP_RX 0xd /* enum */ +#define MCDI_EVENT_CODE_PTP_FAULT 0xe /* enum */ +#define MCDI_EVENT_CMDDONE_DATA_OFST 0 +#define MCDI_EVENT_CMDDONE_DATA_LBN 0 +#define MCDI_EVENT_CMDDONE_DATA_WIDTH 32 +#define MCDI_EVENT_LINKCHANGE_DATA_OFST 0 +#define MCDI_EVENT_LINKCHANGE_DATA_LBN 0 +#define MCDI_EVENT_LINKCHANGE_DATA_WIDTH 32 +#define MCDI_EVENT_SENSOREVT_DATA_OFST 0 +#define MCDI_EVENT_SENSOREVT_DATA_LBN 0 +#define MCDI_EVENT_SENSOREVT_DATA_WIDTH 32 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_OFST 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_LBN 0 +#define MCDI_EVENT_MAC_STATS_DMA_GENERATION_WIDTH 32 +#define MCDI_EVENT_TX_ERR_DATA_OFST 0 +#define MCDI_EVENT_TX_ERR_DATA_LBN 0 +#define MCDI_EVENT_TX_ERR_DATA_WIDTH 32 +#define MCDI_EVENT_PTP_SECONDS_OFST 0 +#define MCDI_EVENT_PTP_SECONDS_LBN 0 +#define MCDI_EVENT_PTP_SECONDS_WIDTH 32 +#define MCDI_EVENT_PTP_NANOSECONDS_OFST 0 +#define MCDI_EVENT_PTP_NANOSECONDS_LBN 0 +#define MCDI_EVENT_PTP_NANOSECONDS_WIDTH 32 +#define MCDI_EVENT_PTP_UUID_OFST 0 +#define MCDI_EVENT_PTP_UUID_LBN 0 +#define MCDI_EVENT_PTP_UUID_WIDTH 32 + + +/***********************************/ +/* MC_CMD_READ32 + * Read multiple 32byte words from MC memory. + */ +#define MC_CMD_READ32 0x1 + +/* MC_CMD_READ32_IN msgrequest */ +#define MC_CMD_READ32_IN_LEN 8 +#define MC_CMD_READ32_IN_ADDR_OFST 0 +#define MC_CMD_READ32_IN_NUMWORDS_OFST 4 + +/* MC_CMD_READ32_OUT msgresponse */ +#define MC_CMD_READ32_OUT_LENMIN 4 +#define MC_CMD_READ32_OUT_LENMAX 252 +#define MC_CMD_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_WRITE32 + * Write multiple 32byte words to MC memory. + */ +#define MC_CMD_WRITE32 0x2 + +/* MC_CMD_WRITE32_IN msgrequest */ +#define MC_CMD_WRITE32_IN_LENMIN 8 +#define MC_CMD_WRITE32_IN_LENMAX 252 +#define MC_CMD_WRITE32_IN_LEN(num) (4+4*(num)) +#define MC_CMD_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_WRITE32_IN_BUFFER_OFST 4 +#define MC_CMD_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_WRITE32_IN_BUFFER_MAXNUM 62 + +/* MC_CMD_WRITE32_OUT msgresponse */ +#define MC_CMD_WRITE32_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_COPYCODE + * Copy MC code between two locations and jump. + */ +#define MC_CMD_COPYCODE 0x3 + +/* MC_CMD_COPYCODE_IN msgrequest */ +#define MC_CMD_COPYCODE_IN_LEN 16 +#define MC_CMD_COPYCODE_IN_SRC_ADDR_OFST 0 +#define MC_CMD_COPYCODE_IN_DEST_ADDR_OFST 4 +#define MC_CMD_COPYCODE_IN_NUMWORDS_OFST 8 +#define MC_CMD_COPYCODE_IN_JUMP_OFST 12 +#define MC_CMD_COPYCODE_JUMP_NONE 0x1 /* enum */ + +/* MC_CMD_COPYCODE_OUT msgresponse */ +#define MC_CMD_COPYCODE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_FUNC + */ +#define MC_CMD_SET_FUNC 0x4 + +/* MC_CMD_SET_FUNC_IN msgrequest */ +#define MC_CMD_SET_FUNC_IN_LEN 4 +#define MC_CMD_SET_FUNC_IN_FUNC_OFST 0 + +/* MC_CMD_SET_FUNC_OUT msgresponse */ +#define MC_CMD_SET_FUNC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_BOOT_STATUS + */ +#define MC_CMD_GET_BOOT_STATUS 0x5 + +/* MC_CMD_GET_BOOT_STATUS_IN msgrequest */ +#define MC_CMD_GET_BOOT_STATUS_IN_LEN 0 + +/* MC_CMD_GET_BOOT_STATUS_OUT msgresponse */ +#define MC_CMD_GET_BOOT_STATUS_OUT_LEN 8 +#define MC_CMD_GET_BOOT_STATUS_OUT_BOOT_OFFSET_OFST 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_OFST 4 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_LBN 0 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_WATCHDOG_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_LBN 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_PRIMARY_WIDTH 1 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_LBN 2 +#define MC_CMD_GET_BOOT_STATUS_OUT_FLAGS_BACKUP_WIDTH 1 -/* Test execution limits */ -#define MC_TESTEXEC_VARIANT_COUNT 16 -#define MC_TESTEXEC_RESULT_COUNT 7 -/* MC_CMD_SET_TESTVARS: (debug, variadic in) - * Write variant words for test. - * - * The user supplies a bitmap of the variants they wish to set. - * They must ensure that IN.LEN >= 4 + 4 * ffs(BITMAP) - */ -#define MC_CMD_SET_TESTVARS 0x09 -#define MC_CMD_SET_TESTVARS_IN_LEN(_numwords) \ - (4 + 4*(_numwords)) -#define MC_CMD_SET_TESTVARS_IN_ARGS_BITMAP_OFST 0 -/* Up to MC_TESTEXEC_VARIANT_COUNT of 32byte words start here */ -#define MC_CMD_SET_TESTVARS_IN_ARGS_BUFFER_OFST 4 -#define MC_CMD_SET_TESTVARS_OUT_LEN 0 - -/* MC_CMD_GET_TESTRCS: (debug, variadic out) - * Return result words from test. - */ -#define MC_CMD_GET_TESTRCS 0x0a -#define MC_CMD_GET_TESTRCS_IN_LEN 4 -#define MC_CMD_GET_TESTRCS_IN_NUMWORDS_OFST 0 -#define MC_CMD_GET_TESTRCS_OUT_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_GET_TESTRCS_OUT_BUFFER_OFST 0 - -/* MC_CMD_RUN_TEST: (debug) - * Run the test exported by this firmware image - */ -#define MC_CMD_RUN_TEST 0x0b -#define MC_CMD_RUN_TEST_IN_LEN 0 -#define MC_CMD_RUN_TEST_OUT_LEN 0 - -/* MC_CMD_CSR_READ32: (debug, variadic out) - * Read 32bit words from the indirect memory map - */ -#define MC_CMD_CSR_READ32 0x0c -#define MC_CMD_CSR_READ32_IN_LEN 12 -#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 -#define MC_CMD_CSR_READ32_IN_STEP_OFST 4 -#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 -#define MC_CMD_CSR_READ32_OUT_LEN(_numwords) \ - (((_numwords) * 4) + 4) -/* IN.NUMWORDS of 32bit words start here */ -#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0 -#define MC_CMD_CSR_READ32_OUT_IREG_STATUS_OFST(_numwords) \ - ((_numwords) * 4) - -/* MC_CMD_CSR_WRITE32: (debug, variadic in) - * Write 32bit dwords to the indirect memory map - */ -#define MC_CMD_CSR_WRITE32 0x0d -#define MC_CMD_CSR_WRITE32_IN_LEN(_numwords) \ - (((_numwords) * 4) + 8) -#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 -/* Multiple 32bit words of data to write start here */ -#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 -#define MC_CMD_CSR_WRITE32_OUT_LEN 4 -#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 - -/* MC_CMD_JTAG_WORK: (debug, fpga only) - * Process JTAG work buffer for RBF acceleration. - * - * Host: bit count, (up to) 32 words of data to clock out to JTAG - * (bits 1,0=TMS,TDO for first bit; bits 3,2=TMS,TDO for second bit, etc.) - * MC: bit count, (up to) 32 words of data clocked in from JTAG - * (bit 0=TDI for first bit, bit 1=TDI for second bit, etc.; [31:16] unused) +/***********************************/ +/* MC_CMD_GET_ASSERTS + * Get and clear any assertion status. */ -#define MC_CMD_JTAG_WORK 0x0e +#define MC_CMD_GET_ASSERTS 0x6 -/* MC_CMD_STACKINFO: (debug, variadic out) - * Get stack information - * - * Host: nothing - * MC: (thread ptr, stack size, free space) for each thread in system - */ -#define MC_CMD_STACKINFO 0x0f +/* MC_CMD_GET_ASSERTS_IN msgrequest */ +#define MC_CMD_GET_ASSERTS_IN_LEN 4 +#define MC_CMD_GET_ASSERTS_IN_CLEAR_OFST 0 + +/* MC_CMD_GET_ASSERTS_OUT msgresponse */ +#define MC_CMD_GET_ASSERTS_OUT_LEN 140 +#define MC_CMD_GET_ASSERTS_OUT_GLOBAL_FLAGS_OFST 0 +#define MC_CMD_GET_ASSERTS_FLAGS_NO_FAILS 0x1 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_SYS_FAIL 0x2 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_THR_FAIL 0x3 /* enum */ +#define MC_CMD_GET_ASSERTS_FLAGS_WDOG_FIRED 0x4 /* enum */ +#define MC_CMD_GET_ASSERTS_OUT_SAVED_PC_OFFS_OFST 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_OFST 8 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_LEN 4 +#define MC_CMD_GET_ASSERTS_OUT_GP_REGS_OFFS_NUM 31 +#define MC_CMD_GET_ASSERTS_OUT_THREAD_OFFS_OFST 132 +#define MC_CMD_GET_ASSERTS_OUT_RESERVED_OFST 136 -/* MC_CMD_MDIO_READ: - * MDIO register read + +/***********************************/ +/* MC_CMD_LOG_CTRL + * Configure the output stream for various events and messages. + */ +#define MC_CMD_LOG_CTRL 0x7 + +/* MC_CMD_LOG_CTRL_IN msgrequest */ +#define MC_CMD_LOG_CTRL_IN_LEN 8 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_OFST 0 +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_UART 0x1 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ 0x2 /* enum */ +#define MC_CMD_LOG_CTRL_IN_LOG_DEST_EVQ_OFST 4 + +/* MC_CMD_LOG_CTRL_OUT msgresponse */ +#define MC_CMD_LOG_CTRL_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_VERSION + * Get version information about the MC firmware. + */ +#define MC_CMD_GET_VERSION 0x8 + +/* MC_CMD_GET_VERSION_IN msgrequest */ +#define MC_CMD_GET_VERSION_IN_LEN 0 + +/* MC_CMD_GET_VERSION_V0_OUT msgresponse */ +#define MC_CMD_GET_VERSION_V0_OUT_LEN 4 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_ANY 0xffffffff /* enum */ +#define MC_CMD_GET_VERSION_OUT_FIRMWARE_BOOTROM 0xb0070000 /* enum */ + +/* MC_CMD_GET_VERSION_OUT msgresponse */ +#define MC_CMD_GET_VERSION_OUT_LEN 32 +/* MC_CMD_GET_VERSION_OUT_FIRMWARE_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_GET_VERSION_V0_OUT/MC_CMD_GET_VERSION_OUT_FIRMWARE */ +#define MC_CMD_GET_VERSION_OUT_PCOL_OFST 4 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_OFST 8 +#define MC_CMD_GET_VERSION_OUT_SUPPORTED_FUNCS_LEN 16 +#define MC_CMD_GET_VERSION_OUT_VERSION_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_LEN 8 +#define MC_CMD_GET_VERSION_OUT_VERSION_LO_OFST 24 +#define MC_CMD_GET_VERSION_OUT_VERSION_HI_OFST 28 + + +/***********************************/ +/* MC_CMD_GET_FPGAREG + * Read multiple bytes from PTP FPGA. + */ +#define MC_CMD_GET_FPGAREG 0x9 + +/* MC_CMD_GET_FPGAREG_IN msgrequest */ +#define MC_CMD_GET_FPGAREG_IN_LEN 8 +#define MC_CMD_GET_FPGAREG_IN_ADDR_OFST 0 +#define MC_CMD_GET_FPGAREG_IN_NUMBYTES_OFST 4 + +/* MC_CMD_GET_FPGAREG_OUT msgresponse */ +#define MC_CMD_GET_FPGAREG_OUT_LENMIN 1 +#define MC_CMD_GET_FPGAREG_OUT_LENMAX 255 +#define MC_CMD_GET_FPGAREG_OUT_LEN(num) (0+1*(num)) +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_OFST 0 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_LEN 1 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MINNUM 1 +#define MC_CMD_GET_FPGAREG_OUT_BUFFER_MAXNUM 255 + + +/***********************************/ +/* MC_CMD_PUT_FPGAREG + * Write multiple bytes to PTP FPGA. + */ +#define MC_CMD_PUT_FPGAREG 0xa + +/* MC_CMD_PUT_FPGAREG_IN msgrequest */ +#define MC_CMD_PUT_FPGAREG_IN_LENMIN 5 +#define MC_CMD_PUT_FPGAREG_IN_LENMAX 255 +#define MC_CMD_PUT_FPGAREG_IN_LEN(num) (4+1*(num)) +#define MC_CMD_PUT_FPGAREG_IN_ADDR_OFST 0 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_OFST 4 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_LEN 1 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MINNUM 1 +#define MC_CMD_PUT_FPGAREG_IN_BUFFER_MAXNUM 251 + +/* MC_CMD_PUT_FPGAREG_OUT msgresponse */ +#define MC_CMD_PUT_FPGAREG_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PTP + * Perform PTP operation + */ +#define MC_CMD_PTP 0xb + +/* MC_CMD_PTP_IN msgrequest */ +#define MC_CMD_PTP_IN_LEN 1 +#define MC_CMD_PTP_IN_OP_OFST 0 +#define MC_CMD_PTP_IN_OP_LEN 1 +#define MC_CMD_PTP_OP_ENABLE 0x1 /* enum */ +#define MC_CMD_PTP_OP_DISABLE 0x2 /* enum */ +#define MC_CMD_PTP_OP_TRANSMIT 0x3 /* enum */ +#define MC_CMD_PTP_OP_READ_NIC_TIME 0x4 /* enum */ +#define MC_CMD_PTP_OP_STATUS 0x5 /* enum */ +#define MC_CMD_PTP_OP_ADJUST 0x6 /* enum */ +#define MC_CMD_PTP_OP_SYNCHRONIZE 0x7 /* enum */ +#define MC_CMD_PTP_OP_MANFTEST_BASIC 0x8 /* enum */ +#define MC_CMD_PTP_OP_MANFTEST_PACKET 0x9 /* enum */ +#define MC_CMD_PTP_OP_RESET_STATS 0xa /* enum */ +#define MC_CMD_PTP_OP_DEBUG 0xb /* enum */ +#define MC_CMD_PTP_OP_MAX 0xc /* enum */ + +/* MC_CMD_PTP_IN_ENABLE msgrequest */ +#define MC_CMD_PTP_IN_ENABLE_LEN 16 +#define MC_CMD_PTP_IN_CMD_OFST 0 +#define MC_CMD_PTP_IN_PERIPH_ID_OFST 4 +#define MC_CMD_PTP_IN_ENABLE_QUEUE_OFST 8 +#define MC_CMD_PTP_IN_ENABLE_MODE_OFST 12 +#define MC_CMD_PTP_MODE_V1 0x0 /* enum */ +#define MC_CMD_PTP_MODE_V1_VLAN 0x1 /* enum */ +#define MC_CMD_PTP_MODE_V2 0x2 /* enum */ +#define MC_CMD_PTP_MODE_V2_VLAN 0x3 /* enum */ + +/* MC_CMD_PTP_IN_DISABLE msgrequest */ +#define MC_CMD_PTP_IN_DISABLE_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_TRANSMIT msgrequest */ +#define MC_CMD_PTP_IN_TRANSMIT_LENMIN 13 +#define MC_CMD_PTP_IN_TRANSMIT_LENMAX 255 +#define MC_CMD_PTP_IN_TRANSMIT_LEN(num) (12+1*(num)) +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_TRANSMIT_LENGTH_OFST 8 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_OFST 12 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_LEN 1 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MINNUM 1 +#define MC_CMD_PTP_IN_TRANSMIT_PACKET_MAXNUM 243 + +/* MC_CMD_PTP_IN_READ_NIC_TIME msgrequest */ +#define MC_CMD_PTP_IN_READ_NIC_TIME_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_STATUS msgrequest */ +#define MC_CMD_PTP_IN_STATUS_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_ADJUST msgrequest */ +#define MC_CMD_PTP_IN_ADJUST_LEN 24 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_ADJUST_FREQ_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_LEN 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_LO_OFST 8 +#define MC_CMD_PTP_IN_ADJUST_FREQ_HI_OFST 12 +#define MC_CMD_PTP_IN_ADJUST_BITS 0x28 /* enum */ +#define MC_CMD_PTP_IN_ADJUST_SECONDS_OFST 16 +#define MC_CMD_PTP_IN_ADJUST_NANOSECONDS_OFST 20 + +/* MC_CMD_PTP_IN_SYNCHRONIZE msgrequest */ +#define MC_CMD_PTP_IN_SYNCHRONIZE_LEN 20 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_SYNCHRONIZE_NUMTIMESETS_OFST 8 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_OFST 12 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LEN 8 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_LO_OFST 12 +#define MC_CMD_PTP_IN_SYNCHRONIZE_START_ADDR_HI_OFST 16 + +/* MC_CMD_PTP_IN_MANFTEST_BASIC msgrequest */ +#define MC_CMD_PTP_IN_MANFTEST_BASIC_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_MANFTEST_PACKET msgrequest */ +#define MC_CMD_PTP_IN_MANFTEST_PACKET_LEN 12 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_MANFTEST_PACKET_TEST_ENABLE_OFST 8 + +/* MC_CMD_PTP_IN_RESET_STATS msgrequest */ +#define MC_CMD_PTP_IN_RESET_STATS_LEN 8 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ + +/* MC_CMD_PTP_IN_DEBUG msgrequest */ +#define MC_CMD_PTP_IN_DEBUG_LEN 12 +/* MC_CMD_PTP_IN_CMD_OFST 0 */ +/* MC_CMD_PTP_IN_PERIPH_ID_OFST 4 */ +#define MC_CMD_PTP_IN_DEBUG_DEBUG_PARAM_OFST 8 + +/* MC_CMD_PTP_OUT msgresponse */ +#define MC_CMD_PTP_OUT_LEN 0 + +/* MC_CMD_PTP_OUT_TRANSMIT msgresponse */ +#define MC_CMD_PTP_OUT_TRANSMIT_LEN 8 +#define MC_CMD_PTP_OUT_TRANSMIT_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_TRANSMIT_NANOSECONDS_OFST 4 + +/* MC_CMD_PTP_OUT_READ_NIC_TIME msgresponse */ +#define MC_CMD_PTP_OUT_READ_NIC_TIME_LEN 8 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_SECONDS_OFST 0 +#define MC_CMD_PTP_OUT_READ_NIC_TIME_NANOSECONDS_OFST 4 + +/* MC_CMD_PTP_OUT_STATUS msgresponse */ +#define MC_CMD_PTP_OUT_STATUS_LEN 64 +#define MC_CMD_PTP_OUT_STATUS_CLOCK_FREQ_OFST 0 +#define MC_CMD_PTP_OUT_STATUS_STATS_TX_OFST 4 +#define MC_CMD_PTP_OUT_STATUS_STATS_RX_OFST 8 +#define MC_CMD_PTP_OUT_STATUS_STATS_TS_OFST 12 +#define MC_CMD_PTP_OUT_STATUS_STATS_FM_OFST 16 +#define MC_CMD_PTP_OUT_STATUS_STATS_NFM_OFST 20 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFLOW_OFST 24 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_BAD_OFST 28 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MIN_OFST 32 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MAX_OFST 36 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_LAST_OFST 40 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_PER_MEAN_OFST 44 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MIN_OFST 48 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MAX_OFST 52 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_LAST_OFST 56 +#define MC_CMD_PTP_OUT_STATUS_STATS_PPS_OFF_MEAN_OFST 60 + +/* MC_CMD_PTP_OUT_SYNCHRONIZE msgresponse */ +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMIN 20 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LENMAX 240 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_LEN(num) (0+20*(num)) +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_OFST 0 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_LEN 20 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MINNUM 1 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_TIMESET_MAXNUM 12 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTSTART_OFST 0 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_SECONDS_OFST 4 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_NANOSECONDS_OFST 8 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_HOSTEND_OFST 12 +#define MC_CMD_PTP_OUT_SYNCHRONIZE_WAITNS_OFST 16 + +/* MC_CMD_PTP_OUT_MANFTEST_BASIC msgresponse */ +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_LEN 8 +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_MANF_SUCCESS 0x0 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_LOAD 0x1 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_VERSION 0x2 /* enum */ +#define MC_CMD_PTP_MANF_FPGA_REGISTERS 0x3 /* enum */ +#define MC_CMD_PTP_MANF_OSCILLATOR 0x4 /* enum */ +#define MC_CMD_PTP_MANF_TIMESTAMPS 0x5 /* enum */ +#define MC_CMD_PTP_MANF_PACKET_COUNT 0x6 /* enum */ +#define MC_CMD_PTP_MANF_FILTER_COUNT 0x7 /* enum */ +#define MC_CMD_PTP_MANF_PACKET_ENOUGH 0x8 /* enum */ +#define MC_CMD_PTP_MANF_GPIO_TRIGGER 0x9 /* enum */ +#define MC_CMD_PTP_OUT_MANFTEST_BASIC_TEST_EXTOSC_OFST 4 + +/* MC_CMD_PTP_OUT_MANFTEST_PACKET msgresponse */ +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_LEN 12 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_RESULT_OFST 0 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FPGACOUNT_OFST 4 +#define MC_CMD_PTP_OUT_MANFTEST_PACKET_TEST_FILTERCOUNT_OFST 8 + + +/***********************************/ +/* MC_CMD_CSR_READ32 + * Read 32bit words from the indirect memory map. + */ +#define MC_CMD_CSR_READ32 0xc + +/* MC_CMD_CSR_READ32_IN msgrequest */ +#define MC_CMD_CSR_READ32_IN_LEN 12 +#define MC_CMD_CSR_READ32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_READ32_IN_STEP_OFST 4 +#define MC_CMD_CSR_READ32_IN_NUMWORDS_OFST 8 + +/* MC_CMD_CSR_READ32_OUT msgresponse */ +#define MC_CMD_CSR_READ32_OUT_LENMIN 4 +#define MC_CMD_CSR_READ32_OUT_LENMAX 252 +#define MC_CMD_CSR_READ32_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_CSR_READ32_OUT_BUFFER_OFST 0 +#define MC_CMD_CSR_READ32_OUT_BUFFER_LEN 4 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MINNUM 1 +#define MC_CMD_CSR_READ32_OUT_BUFFER_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_CSR_WRITE32 + * Write 32bit dwords to the indirect memory map. + */ +#define MC_CMD_CSR_WRITE32 0xd + +/* MC_CMD_CSR_WRITE32_IN msgrequest */ +#define MC_CMD_CSR_WRITE32_IN_LENMIN 12 +#define MC_CMD_CSR_WRITE32_IN_LENMAX 252 +#define MC_CMD_CSR_WRITE32_IN_LEN(num) (8+4*(num)) +#define MC_CMD_CSR_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_CSR_WRITE32_IN_STEP_OFST 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_OFST 8 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_LEN 4 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MINNUM 1 +#define MC_CMD_CSR_WRITE32_IN_BUFFER_MAXNUM 61 + +/* MC_CMD_CSR_WRITE32_OUT msgresponse */ +#define MC_CMD_CSR_WRITE32_OUT_LEN 4 +#define MC_CMD_CSR_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_STACKINFO + * Get stack information. + */ +#define MC_CMD_STACKINFO 0xf + +/* MC_CMD_STACKINFO_IN msgrequest */ +#define MC_CMD_STACKINFO_IN_LEN 0 + +/* MC_CMD_STACKINFO_OUT msgresponse */ +#define MC_CMD_STACKINFO_OUT_LENMIN 12 +#define MC_CMD_STACKINFO_OUT_LENMAX 252 +#define MC_CMD_STACKINFO_OUT_LEN(num) (0+12*(num)) +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_OFST 0 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_LEN 12 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MINNUM 1 +#define MC_CMD_STACKINFO_OUT_THREAD_INFO_MAXNUM 21 + + +/***********************************/ +/* MC_CMD_MDIO_READ + * MDIO register read. */ #define MC_CMD_MDIO_READ 0x10 -#define MC_CMD_MDIO_READ_IN_LEN 16 -#define MC_CMD_MDIO_READ_IN_BUS_OFST 0 -#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 -#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 -#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 -#define MC_CMD_MDIO_READ_OUT_LEN 8 -#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 -#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 - -/* MC_CMD_MDIO_WRITE: - * MDIO register write - */ -#define MC_CMD_MDIO_WRITE 0x11 -#define MC_CMD_MDIO_WRITE_IN_LEN 20 -#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 -#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 -#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 -#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 -#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 -#define MC_CMD_MDIO_WRITE_OUT_LEN 4 -#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 -/* By default all the MCDI MDIO operations perform clause45 mode. - * If you want to use clause22 then set DEVAD = MC_CMD_MDIO_CLAUSE22. - */ -#define MC_CMD_MDIO_CLAUSE22 32 +/* MC_CMD_MDIO_READ_IN msgrequest */ +#define MC_CMD_MDIO_READ_IN_LEN 16 +#define MC_CMD_MDIO_READ_IN_BUS_OFST 0 +#define MC_CMD_MDIO_BUS_INTERNAL 0x0 /* enum */ +#define MC_CMD_MDIO_BUS_EXTERNAL 0x1 /* enum */ +#define MC_CMD_MDIO_READ_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_READ_IN_DEVAD_OFST 8 +#define MC_CMD_MDIO_CLAUSE22 0x20 /* enum */ +#define MC_CMD_MDIO_READ_IN_ADDR_OFST 12 -/* There are two MDIO buses: one for the internal PHY, and one for external - * devices. - */ -#define MC_CMD_MDIO_BUS_INTERNAL 0 -#define MC_CMD_MDIO_BUS_EXTERNAL 1 +/* MC_CMD_MDIO_READ_OUT msgresponse */ +#define MC_CMD_MDIO_READ_OUT_LEN 8 +#define MC_CMD_MDIO_READ_OUT_VALUE_OFST 0 +#define MC_CMD_MDIO_READ_OUT_STATUS_OFST 4 +#define MC_CMD_MDIO_STATUS_GOOD 0x8 /* enum */ -/* The MDIO commands return the raw status bits from the MDIO block. A "good" - * transaction should have the DONE bit set and all other bits clear. + +/***********************************/ +/* MC_CMD_MDIO_WRITE + * MDIO register write. */ -#define MC_CMD_MDIO_STATUS_GOOD 0x08 +#define MC_CMD_MDIO_WRITE 0x11 +/* MC_CMD_MDIO_WRITE_IN msgrequest */ +#define MC_CMD_MDIO_WRITE_IN_LEN 20 +#define MC_CMD_MDIO_WRITE_IN_BUS_OFST 0 +/* MC_CMD_MDIO_BUS_INTERNAL 0x0 */ +/* MC_CMD_MDIO_BUS_EXTERNAL 0x1 */ +#define MC_CMD_MDIO_WRITE_IN_PRTAD_OFST 4 +#define MC_CMD_MDIO_WRITE_IN_DEVAD_OFST 8 +/* MC_CMD_MDIO_CLAUSE22 0x20 */ +#define MC_CMD_MDIO_WRITE_IN_ADDR_OFST 12 +#define MC_CMD_MDIO_WRITE_IN_VALUE_OFST 16 -/* MC_CMD_DBI_WRITE: (debug) - * Write DBI register(s) - * - * Host: address, byte-enables (and VF selection, and cs2 flag), - * value [,address ...] - * MC: nothing +/* MC_CMD_MDIO_WRITE_OUT msgresponse */ +#define MC_CMD_MDIO_WRITE_OUT_LEN 4 +#define MC_CMD_MDIO_WRITE_OUT_STATUS_OFST 0 +/* MC_CMD_MDIO_STATUS_GOOD 0x8 */ + + +/***********************************/ +/* MC_CMD_DBI_WRITE + * Write DBI register(s). */ #define MC_CMD_DBI_WRITE 0x12 -#define MC_CMD_DBI_WRITE_IN_LEN(_numwords) \ - (12 * (_numwords)) -#define MC_CMD_DBI_WRITE_IN_ADDRESS_OFST(_word) \ - (((_word) * 12) + 0) -#define MC_CMD_DBI_WRITE_IN_BYTE_MASK_OFST(_word) \ - (((_word) * 12) + 4) -#define MC_CMD_DBI_WRITE_IN_VALUE_OFST(_word) \ - (((_word) * 12) + 8) -#define MC_CMD_DBI_WRITE_OUT_LEN 0 - -/* MC_CMD_DBI_READ: (debug) - * Read DBI register(s) - * - * Host: address, [,address ...] - * MC: value [,value ...] - * (note: this does not support reading from VFs, but is retained for backwards - * compatibility; see MC_CMD_DBI_READX below) - */ -#define MC_CMD_DBI_READ 0x13 -#define MC_CMD_DBI_READ_IN_LEN(_numwords) \ - (4 * (_numwords)) -#define MC_CMD_DBI_READ_OUT_LEN(_numwords) \ - (4 * (_numwords)) - -/* MC_CMD_PORT_READ32: (debug) + +/* MC_CMD_DBI_WRITE_IN msgrequest */ +#define MC_CMD_DBI_WRITE_IN_LENMIN 12 +#define MC_CMD_DBI_WRITE_IN_LENMAX 252 +#define MC_CMD_DBI_WRITE_IN_LEN(num) (0+12*(num)) +#define MC_CMD_DBI_WRITE_IN_DBIWROP_OFST 0 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_LEN 12 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MINNUM 1 +#define MC_CMD_DBI_WRITE_IN_DBIWROP_MAXNUM 21 + +/* MC_CMD_DBI_WRITE_OUT msgresponse */ +#define MC_CMD_DBI_WRITE_OUT_LEN 0 + +/* MC_CMD_DBIWROP_TYPEDEF structuredef */ +#define MC_CMD_DBIWROP_TYPEDEF_LEN 12 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_OFST 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_LBN 0 +#define MC_CMD_DBIWROP_TYPEDEF_ADDRESS_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_OFST 4 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_LBN 32 +#define MC_CMD_DBIWROP_TYPEDEF_BYTE_MASK_WIDTH 32 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_OFST 8 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_LBN 64 +#define MC_CMD_DBIWROP_TYPEDEF_VALUE_WIDTH 32 + + +/***********************************/ +/* MC_CMD_PORT_READ32 * Read a 32-bit register from the indirect port register map. - * - * The port to access is implied by the Shared memory channel used. */ #define MC_CMD_PORT_READ32 0x14 -#define MC_CMD_PORT_READ32_IN_LEN 4 -#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 -#define MC_CMD_PORT_READ32_OUT_LEN 8 -#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 -#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 -/* MC_CMD_PORT_WRITE32: (debug) +/* MC_CMD_PORT_READ32_IN msgrequest */ +#define MC_CMD_PORT_READ32_IN_LEN 4 +#define MC_CMD_PORT_READ32_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ32_OUT msgresponse */ +#define MC_CMD_PORT_READ32_OUT_LEN 8 +#define MC_CMD_PORT_READ32_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ32_OUT_STATUS_OFST 4 + + +/***********************************/ +/* MC_CMD_PORT_WRITE32 * Write a 32-bit register to the indirect port register map. - * - * The port to access is implied by the Shared memory channel used. */ #define MC_CMD_PORT_WRITE32 0x15 -#define MC_CMD_PORT_WRITE32_IN_LEN 8 -#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 -#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 -#define MC_CMD_PORT_WRITE32_OUT_LEN 4 -#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 - -/* MC_CMD_PORT_READ128: (debug) - * Read a 128-bit register from indirect port register map - * - * The port to access is implied by the Shared memory channel used. + +/* MC_CMD_PORT_WRITE32_IN msgrequest */ +#define MC_CMD_PORT_WRITE32_IN_LEN 8 +#define MC_CMD_PORT_WRITE32_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE32_IN_VALUE_OFST 4 + +/* MC_CMD_PORT_WRITE32_OUT msgresponse */ +#define MC_CMD_PORT_WRITE32_OUT_LEN 4 +#define MC_CMD_PORT_WRITE32_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_PORT_READ128 + * Read a 128-bit register from the indirect port register map. */ #define MC_CMD_PORT_READ128 0x16 -#define MC_CMD_PORT_READ128_IN_LEN 4 -#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 -#define MC_CMD_PORT_READ128_OUT_LEN 20 -#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0 -#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 - -/* MC_CMD_PORT_WRITE128: (debug) - * Write a 128-bit register to indirect port register map. - * - * The port to access is implied by the Shared memory channel used. + +/* MC_CMD_PORT_READ128_IN msgrequest */ +#define MC_CMD_PORT_READ128_IN_LEN 4 +#define MC_CMD_PORT_READ128_IN_ADDR_OFST 0 + +/* MC_CMD_PORT_READ128_OUT msgresponse */ +#define MC_CMD_PORT_READ128_OUT_LEN 20 +#define MC_CMD_PORT_READ128_OUT_VALUE_OFST 0 +#define MC_CMD_PORT_READ128_OUT_VALUE_LEN 16 +#define MC_CMD_PORT_READ128_OUT_STATUS_OFST 16 + + +/***********************************/ +/* MC_CMD_PORT_WRITE128 + * Write a 128-bit register to the indirect port register map. */ #define MC_CMD_PORT_WRITE128 0x17 -#define MC_CMD_PORT_WRITE128_IN_LEN 20 -#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 -#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 -#define MC_CMD_PORT_WRITE128_OUT_LEN 4 -#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 - -/* MC_CMD_GET_BOARD_CFG: - * Returns the MC firmware configuration structure - * - * The FW_SUBTYPE_LIST contains a 16-bit value for each of the 12 types of - * NVRAM area. The values are defined in the firmware/mc/platform/.c file - * for a specific board type, but otherwise have no meaning to the MC; they - * are used by the driver to manage selection of appropriate firmware updates. + +/* MC_CMD_PORT_WRITE128_IN msgrequest */ +#define MC_CMD_PORT_WRITE128_IN_LEN 20 +#define MC_CMD_PORT_WRITE128_IN_ADDR_OFST 0 +#define MC_CMD_PORT_WRITE128_IN_VALUE_OFST 4 +#define MC_CMD_PORT_WRITE128_IN_VALUE_LEN 16 + +/* MC_CMD_PORT_WRITE128_OUT msgresponse */ +#define MC_CMD_PORT_WRITE128_OUT_LEN 4 +#define MC_CMD_PORT_WRITE128_OUT_STATUS_OFST 0 + + +/***********************************/ +/* MC_CMD_GET_BOARD_CFG + * Returns the MC firmware configuration structure. */ #define MC_CMD_GET_BOARD_CFG 0x18 -#define MC_CMD_GET_BOARD_CFG_IN_LEN 0 -#define MC_CMD_GET_BOARD_CFG_OUT_LEN 96 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 -#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 -#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 -#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 -#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 -#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 -#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 24 - -/* MC_CMD_DBI_READX: (debug) - * Read DBI register(s) -- extended functionality - * - * Host: vf selection, address, [,vf selection ...] - * MC: value [,value ...] + +/* MC_CMD_GET_BOARD_CFG_IN msgrequest */ +#define MC_CMD_GET_BOARD_CFG_IN_LEN 0 + +/* MC_CMD_GET_BOARD_CFG_OUT msgresponse */ +#define MC_CMD_GET_BOARD_CFG_OUT_LENMIN 96 +#define MC_CMD_GET_BOARD_CFG_OUT_LENMAX 136 +#define MC_CMD_GET_BOARD_CFG_OUT_LEN(num) (72+2*(num)) +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_TYPE_OFST 0 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_OFST 4 +#define MC_CMD_GET_BOARD_CFG_OUT_BOARD_NAME_LEN 32 +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT0_OFST 36 +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_LBN 0x0 /* enum */ +#define MC_CMD_CAPABILITIES_SMALL_BUF_TBL_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_LBN 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN 0x2 /* enum */ +#define MC_CMD_CAPABILITIES_TURBO_ACTIVE_WIDTH 0x1 /* enum */ +#define MC_CMD_CAPABILITIES_PTP_LBN 0x3 /* enum */ +#define MC_CMD_CAPABILITIES_PTP_WIDTH 0x1 /* enum */ +#define MC_CMD_GET_BOARD_CFG_OUT_CAPABILITIES_PORT1_OFST 40 +/* Enum values, see field(s): */ +/* CAPABILITIES_PORT0 */ +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_OFST 44 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT0_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_OFST 50 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_ADDR_BASE_PORT1_LEN 6 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT0_OFST 56 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_COUNT_PORT1_OFST 60 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT0_OFST 64 +#define MC_CMD_GET_BOARD_CFG_OUT_MAC_STRIDE_PORT1_OFST 68 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST 72 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN 2 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM 12 +#define MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MAXNUM 32 + + +/***********************************/ +/* MC_CMD_DBI_READX + * Read DBI register(s). */ #define MC_CMD_DBI_READX 0x19 -#define MC_CMD_DBI_READX_IN_LEN(_numwords) \ - (8*(_numwords)) -#define MC_CMD_DBI_READX_OUT_LEN(_numwords) \ - (4*(_numwords)) -/* MC_CMD_SET_RAND_SEED: - * Set the 16byte seed for the MC pseudo-random generator +/* MC_CMD_DBI_READX_IN msgrequest */ +#define MC_CMD_DBI_READX_IN_LENMIN 8 +#define MC_CMD_DBI_READX_IN_LENMAX 248 +#define MC_CMD_DBI_READX_IN_LEN(num) (0+8*(num)) +#define MC_CMD_DBI_READX_IN_DBIRDOP_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LEN 8 +#define MC_CMD_DBI_READX_IN_DBIRDOP_LO_OFST 0 +#define MC_CMD_DBI_READX_IN_DBIRDOP_HI_OFST 4 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MINNUM 1 +#define MC_CMD_DBI_READX_IN_DBIRDOP_MAXNUM 31 + +/* MC_CMD_DBI_READX_OUT msgresponse */ +#define MC_CMD_DBI_READX_OUT_LENMIN 4 +#define MC_CMD_DBI_READX_OUT_LENMAX 252 +#define MC_CMD_DBI_READX_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_DBI_READX_OUT_VALUE_OFST 0 +#define MC_CMD_DBI_READX_OUT_VALUE_LEN 4 +#define MC_CMD_DBI_READX_OUT_VALUE_MINNUM 1 +#define MC_CMD_DBI_READX_OUT_VALUE_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_SET_RAND_SEED + * Set the 16byte seed for the MC pseudo-random generator. */ #define MC_CMD_SET_RAND_SEED 0x1a -#define MC_CMD_SET_RAND_SEED_IN_LEN 16 -#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0 -#define MC_CMD_SET_RAND_SEED_OUT_LEN 0 -/* MC_CMD_LTSSM_HIST: (debug) - * Retrieve the history of the LTSSM, if the build supports it. - * - * Host: nothing - * MC: variable number of LTSSM values, as bytes - * The history is read-to-clear. +/* MC_CMD_SET_RAND_SEED_IN msgrequest */ +#define MC_CMD_SET_RAND_SEED_IN_LEN 16 +#define MC_CMD_SET_RAND_SEED_IN_SEED_OFST 0 +#define MC_CMD_SET_RAND_SEED_IN_SEED_LEN 16 + +/* MC_CMD_SET_RAND_SEED_OUT msgresponse */ +#define MC_CMD_SET_RAND_SEED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_LTSSM_HIST + * Retrieve the history of the PCIE LTSSM. */ #define MC_CMD_LTSSM_HIST 0x1b -/* MC_CMD_DRV_ATTACH: - * Inform MCPU that this port is managed on the host (i.e. driver active) +/* MC_CMD_LTSSM_HIST_IN msgrequest */ +#define MC_CMD_LTSSM_HIST_IN_LEN 0 + +/* MC_CMD_LTSSM_HIST_OUT msgresponse */ +#define MC_CMD_LTSSM_HIST_OUT_LENMIN 0 +#define MC_CMD_LTSSM_HIST_OUT_LENMAX 252 +#define MC_CMD_LTSSM_HIST_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_LTSSM_HIST_OUT_DATA_OFST 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_LEN 4 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MINNUM 0 +#define MC_CMD_LTSSM_HIST_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_DRV_ATTACH + * Inform MCPU that this port is managed on the host. */ #define MC_CMD_DRV_ATTACH 0x1c -#define MC_CMD_DRV_ATTACH_IN_LEN 8 -#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 -#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 -#define MC_CMD_DRV_ATTACH_OUT_LEN 4 -#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 -/* MC_CMD_NCSI_PROD: (debug) - * Trigger an NC-SI event (and possibly an AEN in response) +/* MC_CMD_DRV_ATTACH_IN msgrequest */ +#define MC_CMD_DRV_ATTACH_IN_LEN 8 +#define MC_CMD_DRV_ATTACH_IN_NEW_STATE_OFST 0 +#define MC_CMD_DRV_ATTACH_IN_UPDATE_OFST 4 + +/* MC_CMD_DRV_ATTACH_OUT msgresponse */ +#define MC_CMD_DRV_ATTACH_OUT_LEN 4 +#define MC_CMD_DRV_ATTACH_OUT_OLD_STATE_OFST 0 + + +/***********************************/ +/* MC_CMD_NCSI_PROD + * Trigger an NC-SI event. */ #define MC_CMD_NCSI_PROD 0x1d -#define MC_CMD_NCSI_PROD_IN_LEN 4 -#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0 -#define MC_CMD_NCSI_PROD_LINKCHANGE_LBN 0 -#define MC_CMD_NCSI_PROD_LINKCHANGE_WIDTH 1 -#define MC_CMD_NCSI_PROD_RESET_LBN 1 -#define MC_CMD_NCSI_PROD_RESET_WIDTH 1 -#define MC_CMD_NCSI_PROD_DRVATTACH_LBN 2 -#define MC_CMD_NCSI_PROD_DRVATTACH_WIDTH 1 -#define MC_CMD_NCSI_PROD_OUT_LEN 0 - -/* Enumeration */ -#define MC_CMD_NCSI_PROD_LINKCHANGE 0 -#define MC_CMD_NCSI_PROD_RESET 1 -#define MC_CMD_NCSI_PROD_DRVATTACH 2 - -/* MC_CMD_DEVEL: (debug) - * Reserved for development - */ -#define MC_CMD_DEVEL 0x1e - -/* MC_CMD_SHMUART: (debug) + +/* MC_CMD_NCSI_PROD_IN msgrequest */ +#define MC_CMD_NCSI_PROD_IN_LEN 4 +#define MC_CMD_NCSI_PROD_IN_EVENTS_OFST 0 +#define MC_CMD_NCSI_PROD_LINKCHANGE 0x0 /* enum */ +#define MC_CMD_NCSI_PROD_RESET 0x1 /* enum */ +#define MC_CMD_NCSI_PROD_DRVATTACH 0x2 /* enum */ +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_LBN 0 +#define MC_CMD_NCSI_PROD_IN_LINKCHANGE_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_RESET_LBN 1 +#define MC_CMD_NCSI_PROD_IN_RESET_WIDTH 1 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_LBN 2 +#define MC_CMD_NCSI_PROD_IN_DRVATTACH_WIDTH 1 + +/* MC_CMD_NCSI_PROD_OUT msgresponse */ +#define MC_CMD_NCSI_PROD_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SHMUART * Route UART output to circular buffer in shared memory instead. */ #define MC_CMD_SHMUART 0x1f -#define MC_CMD_SHMUART_IN_FLAG_OFST 0 -#define MC_CMD_SHMUART_IN_LEN 4 -#define MC_CMD_SHMUART_OUT_LEN 0 -/* MC_CMD_PORT_RESET: - * Generic per-port reset. There is no equivalent for per-board reset. - * - * Locks required: None - * Return code: 0, ETIME - */ -#define MC_CMD_PORT_RESET 0x20 -#define MC_CMD_PORT_RESET_IN_LEN 0 -#define MC_CMD_PORT_RESET_OUT_LEN 0 - -/* MC_CMD_RESOURCE_LOCK: - * Generic resource lock/unlock interface. - * - * Locks required: None - * Return code: 0, - * EBUSY (if trylock is contended by other port), - * EDEADLK (if trylock is already acquired by this port) - * EINVAL (if unlock doesn't own the lock) - */ -#define MC_CMD_RESOURCE_LOCK 0x21 -#define MC_CMD_RESOURCE_LOCK_IN_LEN 8 -#define MC_CMD_RESOURCE_LOCK_IN_ACTION_OFST 0 -#define MC_CMD_RESOURCE_LOCK_ACTION_TRYLOCK 1 -#define MC_CMD_RESOURCE_LOCK_ACTION_UNLOCK 0 -#define MC_CMD_RESOURCE_LOCK_IN_RESOURCE_OFST 4 -#define MC_CMD_RESOURCE_LOCK_I2C 2 -#define MC_CMD_RESOURCE_LOCK_PHY 3 -#define MC_CMD_RESOURCE_LOCK_OUT_LEN 0 - -/* MC_CMD_SPI_COMMAND: (variadic in, variadic out) - * Read/Write to/from the SPI device. - * - * Locks required: SPI_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if SPI_LOCK is not held) - */ -#define MC_CMD_SPI_COMMAND 0x22 -#define MC_CMD_SPI_COMMAND_IN_LEN(_write_bytes) (12 + (_write_bytes)) -#define MC_CMD_SPI_COMMAND_IN_ARGS_OFST 0 -#define MC_CMD_SPI_COMMAND_IN_ARGS_ADDRESS_OFST 0 -#define MC_CMD_SPI_COMMAND_IN_ARGS_READ_BYTES_OFST 4 -#define MC_CMD_SPI_COMMAND_IN_ARGS_CHIP_SELECT_OFST 8 -/* Data to write here */ -#define MC_CMD_SPI_COMMAND_IN_WRITE_BUFFER_OFST 12 -#define MC_CMD_SPI_COMMAND_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_SPI_COMMAND_OUT_READ_BUFFER_OFST 0 - -/* MC_CMD_I2C_READ_WRITE: (variadic in, variadic out) - * Read/Write to/from the I2C bus. - * - * Locks required: I2C_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if I2C_LOCK is not held) - */ -#define MC_CMD_I2C_RW 0x23 -#define MC_CMD_I2C_RW_IN_LEN(_write_bytes) (8 + (_write_bytes)) -#define MC_CMD_I2C_RW_IN_ARGS_OFST 0 -#define MC_CMD_I2C_RW_IN_ARGS_ADDR_OFST 0 -#define MC_CMD_I2C_RW_IN_ARGS_READ_BYTES_OFST 4 -/* Data to write here */ -#define MC_CMD_I2C_RW_IN_WRITE_BUFFER_OFSET 8 -#define MC_CMD_I2C_RW_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_I2C_RW_OUT_READ_BUFFER_OFST 0 - -/* Generic phy capability bitmask */ -#define MC_CMD_PHY_CAP_10HDX_LBN 1 -#define MC_CMD_PHY_CAP_10HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_10FDX_LBN 2 -#define MC_CMD_PHY_CAP_10FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_100HDX_LBN 3 -#define MC_CMD_PHY_CAP_100HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_100FDX_LBN 4 -#define MC_CMD_PHY_CAP_100FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_1000HDX_LBN 5 -#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1 -#define MC_CMD_PHY_CAP_1000FDX_LBN 6 -#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_10000FDX_LBN 7 -#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1 -#define MC_CMD_PHY_CAP_PAUSE_LBN 8 -#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1 -#define MC_CMD_PHY_CAP_ASYM_LBN 9 -#define MC_CMD_PHY_CAP_ASYM_WIDTH 1 -#define MC_CMD_PHY_CAP_AN_LBN 10 -#define MC_CMD_PHY_CAP_AN_WIDTH 1 - -/* Generic loopback enumeration */ -#define MC_CMD_LOOPBACK_NONE 0 -#define MC_CMD_LOOPBACK_DATA 1 -#define MC_CMD_LOOPBACK_GMAC 2 -#define MC_CMD_LOOPBACK_XGMII 3 -#define MC_CMD_LOOPBACK_XGXS 4 -#define MC_CMD_LOOPBACK_XAUI 5 -#define MC_CMD_LOOPBACK_GMII 6 -#define MC_CMD_LOOPBACK_SGMII 7 -#define MC_CMD_LOOPBACK_XGBR 8 -#define MC_CMD_LOOPBACK_XFI 9 -#define MC_CMD_LOOPBACK_XAUI_FAR 10 -#define MC_CMD_LOOPBACK_GMII_FAR 11 -#define MC_CMD_LOOPBACK_SGMII_FAR 12 -#define MC_CMD_LOOPBACK_XFI_FAR 13 -#define MC_CMD_LOOPBACK_GPHY 14 -#define MC_CMD_LOOPBACK_PHYXS 15 -#define MC_CMD_LOOPBACK_PCS 16 -#define MC_CMD_LOOPBACK_PMAPMD 17 -#define MC_CMD_LOOPBACK_XPORT 18 -#define MC_CMD_LOOPBACK_XGMII_WS 19 -#define MC_CMD_LOOPBACK_XAUI_WS 20 -#define MC_CMD_LOOPBACK_XAUI_WS_FAR 21 -#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 22 -#define MC_CMD_LOOPBACK_GMII_WS 23 -#define MC_CMD_LOOPBACK_XFI_WS 24 -#define MC_CMD_LOOPBACK_XFI_WS_FAR 25 -#define MC_CMD_LOOPBACK_PHYXS_WS 26 - -/* Generic PHY statistics enumeration */ -#define MC_CMD_OUI 0 -#define MC_CMD_PMA_PMD_LINK_UP 1 -#define MC_CMD_PMA_PMD_RX_FAULT 2 -#define MC_CMD_PMA_PMD_TX_FAULT 3 -#define MC_CMD_PMA_PMD_SIGNAL 4 -#define MC_CMD_PMA_PMD_SNR_A 5 -#define MC_CMD_PMA_PMD_SNR_B 6 -#define MC_CMD_PMA_PMD_SNR_C 7 -#define MC_CMD_PMA_PMD_SNR_D 8 -#define MC_CMD_PCS_LINK_UP 9 -#define MC_CMD_PCS_RX_FAULT 10 -#define MC_CMD_PCS_TX_FAULT 11 -#define MC_CMD_PCS_BER 12 -#define MC_CMD_PCS_BLOCK_ERRORS 13 -#define MC_CMD_PHYXS_LINK_UP 14 -#define MC_CMD_PHYXS_RX_FAULT 15 -#define MC_CMD_PHYXS_TX_FAULT 16 -#define MC_CMD_PHYXS_ALIGN 17 -#define MC_CMD_PHYXS_SYNC 18 -#define MC_CMD_AN_LINK_UP 19 -#define MC_CMD_AN_COMPLETE 20 -#define MC_CMD_AN_10GBT_STATUS 21 -#define MC_CMD_CL22_LINK_UP 22 -#define MC_CMD_PHY_NSTATS 23 - -/* MC_CMD_GET_PHY_CFG: - * Report PHY configuration. This guarantees to succeed even if the PHY is in - * a "zombie" state. - * - * Locks required: None - * Return code: 0 +/* MC_CMD_SHMUART_IN msgrequest */ +#define MC_CMD_SHMUART_IN_LEN 4 +#define MC_CMD_SHMUART_IN_FLAG_OFST 0 + +/* MC_CMD_SHMUART_OUT msgresponse */ +#define MC_CMD_SHMUART_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_ENTITY_RESET + * Generic per-port reset. + */ +#define MC_CMD_ENTITY_RESET 0x20 + +/* MC_CMD_ENTITY_RESET_IN msgrequest */ +#define MC_CMD_ENTITY_RESET_IN_LEN 4 +#define MC_CMD_ENTITY_RESET_IN_FLAG_OFST 0 +#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_LBN 0 +#define MC_CMD_ENTITY_RESET_IN_FUNCTION_RESOURCE_RESET_WIDTH 1 + +/* MC_CMD_ENTITY_RESET_OUT msgresponse */ +#define MC_CMD_ENTITY_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PCIE_CREDITS + * Read instantaneous and minimum flow control thresholds. + */ +#define MC_CMD_PCIE_CREDITS 0x21 + +/* MC_CMD_PCIE_CREDITS_IN msgrequest */ +#define MC_CMD_PCIE_CREDITS_IN_LEN 8 +#define MC_CMD_PCIE_CREDITS_IN_POLL_PERIOD_OFST 0 +#define MC_CMD_PCIE_CREDITS_IN_WIPE_OFST 4 + +/* MC_CMD_PCIE_CREDITS_OUT msgresponse */ +#define MC_CMD_PCIE_CREDITS_OUT_LEN 16 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_OFST 0 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_OFST 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_OFST 4 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_OFST 6 +#define MC_CMD_PCIE_CREDITS_OUT_CURRENT_NP_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_OFST 8 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_OFST 10 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_P_DATA_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_OFST 12 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_HDR_LEN 2 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_OFST 14 +#define MC_CMD_PCIE_CREDITS_OUT_MINIMUM_NP_DATA_LEN 2 + + +/***********************************/ +/* MC_CMD_RXD_MONITOR + * Get histogram of RX queue fill level. + */ +#define MC_CMD_RXD_MONITOR 0x22 + +/* MC_CMD_RXD_MONITOR_IN msgrequest */ +#define MC_CMD_RXD_MONITOR_IN_LEN 12 +#define MC_CMD_RXD_MONITOR_IN_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_IN_POLL_PERIOD_OFST 4 +#define MC_CMD_RXD_MONITOR_IN_WIPE_OFST 8 + +/* MC_CMD_RXD_MONITOR_OUT msgresponse */ +#define MC_CMD_RXD_MONITOR_OUT_LEN 80 +#define MC_CMD_RXD_MONITOR_OUT_QID_OFST 0 +#define MC_CMD_RXD_MONITOR_OUT_RING_FILL_OFST 4 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_FILL_OFST 8 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_1_OFST 12 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_2_OFST 16 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_4_OFST 20 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_8_OFST 24 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_16_OFST 28 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_32_OFST 32 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_64_OFST 36 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_128_OFST 40 +#define MC_CMD_RXD_MONITOR_OUT_RING_LT_256_OFST 44 +#define MC_CMD_RXD_MONITOR_OUT_RING_GE_256_OFST 48 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_1_OFST 52 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_2_OFST 56 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_4_OFST 60 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_8_OFST 64 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_16_OFST 68 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_LT_32_OFST 72 +#define MC_CMD_RXD_MONITOR_OUT_CACHE_GE_32_OFST 76 + + +/***********************************/ +/* MC_CMD_PUTS + * puts(3) implementation over MCDI + */ +#define MC_CMD_PUTS 0x23 + +/* MC_CMD_PUTS_IN msgrequest */ +#define MC_CMD_PUTS_IN_LENMIN 13 +#define MC_CMD_PUTS_IN_LENMAX 255 +#define MC_CMD_PUTS_IN_LEN(num) (12+1*(num)) +#define MC_CMD_PUTS_IN_DEST_OFST 0 +#define MC_CMD_PUTS_IN_UART_LBN 0 +#define MC_CMD_PUTS_IN_UART_WIDTH 1 +#define MC_CMD_PUTS_IN_PORT_LBN 1 +#define MC_CMD_PUTS_IN_PORT_WIDTH 1 +#define MC_CMD_PUTS_IN_DHOST_OFST 4 +#define MC_CMD_PUTS_IN_DHOST_LEN 6 +#define MC_CMD_PUTS_IN_STRING_OFST 12 +#define MC_CMD_PUTS_IN_STRING_LEN 1 +#define MC_CMD_PUTS_IN_STRING_MINNUM 1 +#define MC_CMD_PUTS_IN_STRING_MAXNUM 243 + +/* MC_CMD_PUTS_OUT msgresponse */ +#define MC_CMD_PUTS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_CFG + * Report PHY configuration. */ #define MC_CMD_GET_PHY_CFG 0x24 -#define MC_CMD_GET_PHY_CFG_IN_LEN 0 -#define MC_CMD_GET_PHY_CFG_OUT_LEN 72 - -#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 -#define MC_CMD_GET_PHY_CFG_PRESENT_LBN 0 -#define MC_CMD_GET_PHY_CFG_PRESENT_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN 2 -#define MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_LOWPOWER_LBN 3 -#define MC_CMD_GET_PHY_CFG_LOWPOWER_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_POWEROFF_LBN 4 -#define MC_CMD_GET_PHY_CFG_POWEROFF_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_TXDIS_LBN 5 -#define MC_CMD_GET_PHY_CFG_TXDIS_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_BIST_LBN 6 -#define MC_CMD_GET_PHY_CFG_BIST_WIDTH 1 -#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 -/* Bitmask of supported capabilities */ -#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 -#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 -#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 -/* PHY statistics bitmap */ -#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 -/* PHY type/name string */ -#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 -#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 -#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 -#define MC_CMD_MEDIA_XAUI 1 -#define MC_CMD_MEDIA_CX4 2 -#define MC_CMD_MEDIA_KX4 3 -#define MC_CMD_MEDIA_XFP 4 -#define MC_CMD_MEDIA_SFP_PLUS 5 -#define MC_CMD_MEDIA_BASE_T 6 -/* MDIO "MMDS" supported */ -#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 -/* Native clause 22 */ -#define MC_CMD_MMD_CLAUSE22 0 -#define MC_CMD_MMD_CLAUSE45_PMAPMD 1 -#define MC_CMD_MMD_CLAUSE45_WIS 2 -#define MC_CMD_MMD_CLAUSE45_PCS 3 -#define MC_CMD_MMD_CLAUSE45_PHYXS 4 -#define MC_CMD_MMD_CLAUSE45_DTEXS 5 -#define MC_CMD_MMD_CLAUSE45_TC 6 -#define MC_CMD_MMD_CLAUSE45_AN 7 -/* Clause22 proxied over clause45 by PHY */ -#define MC_CMD_MMD_CLAUSE45_C22EXT 29 -#define MC_CMD_MMD_CLAUSE45_VEND1 30 -#define MC_CMD_MMD_CLAUSE45_VEND2 31 -/* PHY stepping version */ -#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52 -#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20 - -/* MC_CMD_START_BIST: +/* MC_CMD_GET_PHY_CFG_IN msgrequest */ +#define MC_CMD_GET_PHY_CFG_IN_LEN 0 + +/* MC_CMD_GET_PHY_CFG_OUT msgresponse */ +#define MC_CMD_GET_PHY_CFG_OUT_LEN 72 +#define MC_CMD_GET_PHY_CFG_OUT_FLAGS_OFST 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_LBN 0 +#define MC_CMD_GET_PHY_CFG_OUT_PRESENT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN 2 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN 3 +#define MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN 4 +#define MC_CMD_GET_PHY_CFG_OUT_POWEROFF_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN 5 +#define MC_CMD_GET_PHY_CFG_OUT_TXDIS_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_LBN 6 +#define MC_CMD_GET_PHY_CFG_OUT_BIST_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_TYPE_OFST 4 +#define MC_CMD_GET_PHY_CFG_OUT_SUPPORTED_CAP_OFST 8 +#define MC_CMD_PHY_CAP_10HDX_LBN 1 +#define MC_CMD_PHY_CAP_10HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10FDX_LBN 2 +#define MC_CMD_PHY_CAP_10FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100HDX_LBN 3 +#define MC_CMD_PHY_CAP_100HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_100FDX_LBN 4 +#define MC_CMD_PHY_CAP_100FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000HDX_LBN 5 +#define MC_CMD_PHY_CAP_1000HDX_WIDTH 1 +#define MC_CMD_PHY_CAP_1000FDX_LBN 6 +#define MC_CMD_PHY_CAP_1000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_10000FDX_LBN 7 +#define MC_CMD_PHY_CAP_10000FDX_WIDTH 1 +#define MC_CMD_PHY_CAP_PAUSE_LBN 8 +#define MC_CMD_PHY_CAP_PAUSE_WIDTH 1 +#define MC_CMD_PHY_CAP_ASYM_LBN 9 +#define MC_CMD_PHY_CAP_ASYM_WIDTH 1 +#define MC_CMD_PHY_CAP_AN_LBN 10 +#define MC_CMD_PHY_CAP_AN_WIDTH 1 +#define MC_CMD_GET_PHY_CFG_OUT_CHANNEL_OFST 12 +#define MC_CMD_GET_PHY_CFG_OUT_PRT_OFST 16 +#define MC_CMD_GET_PHY_CFG_OUT_STATS_MASK_OFST 20 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_OFST 24 +#define MC_CMD_GET_PHY_CFG_OUT_NAME_LEN 20 +#define MC_CMD_GET_PHY_CFG_OUT_MEDIA_TYPE_OFST 44 +#define MC_CMD_MEDIA_XAUI 0x1 /* enum */ +#define MC_CMD_MEDIA_CX4 0x2 /* enum */ +#define MC_CMD_MEDIA_KX4 0x3 /* enum */ +#define MC_CMD_MEDIA_XFP 0x4 /* enum */ +#define MC_CMD_MEDIA_SFP_PLUS 0x5 /* enum */ +#define MC_CMD_MEDIA_BASE_T 0x6 /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_MMD_MASK_OFST 48 +#define MC_CMD_MMD_CLAUSE22 0x0 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PMAPMD 0x1 /* enum */ +#define MC_CMD_MMD_CLAUSE45_WIS 0x2 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PCS 0x3 /* enum */ +#define MC_CMD_MMD_CLAUSE45_PHYXS 0x4 /* enum */ +#define MC_CMD_MMD_CLAUSE45_DTEXS 0x5 /* enum */ +#define MC_CMD_MMD_CLAUSE45_TC 0x6 /* enum */ +#define MC_CMD_MMD_CLAUSE45_AN 0x7 /* enum */ +#define MC_CMD_MMD_CLAUSE45_C22EXT 0x1d /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND1 0x1e /* enum */ +#define MC_CMD_MMD_CLAUSE45_VEND2 0x1f /* enum */ +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_OFST 52 +#define MC_CMD_GET_PHY_CFG_OUT_REVISION_LEN 20 + + +/***********************************/ +/* MC_CMD_START_BIST * Start a BIST test on the PHY. - * - * Locks required: PHY_LOCK if doing a PHY BIST - * Return code: 0, EINVAL, EACCES (if PHY_LOCK is not held) */ #define MC_CMD_START_BIST 0x25 -#define MC_CMD_START_BIST_IN_LEN 4 -#define MC_CMD_START_BIST_IN_TYPE_OFST 0 -#define MC_CMD_START_BIST_OUT_LEN 0 - -/* Run the PHY's short cable BIST */ -#define MC_CMD_PHY_BIST_CABLE_SHORT 1 -/* Run the PHY's long cable BIST */ -#define MC_CMD_PHY_BIST_CABLE_LONG 2 -/* Run BIST on the currently selected BPX Serdes (XAUI or XFI) */ -#define MC_CMD_BPX_SERDES_BIST 3 -/* Run the MC loopback tests */ -#define MC_CMD_MC_LOOPBACK_BIST 4 -/* Run the PHY's standard BIST */ -#define MC_CMD_PHY_BIST 5 - -/* MC_CMD_POLL_PHY_BIST: (variadic output) - * Poll for BIST completion - * - * Returns a single status code, and optionally some PHY specific - * bist output. The driver should only consume the BIST output - * after validating OUTLEN and PHY_CFG.PHY_TYPE. - * - * If a driver can't successfully parse the BIST output, it should - * still respect the pass/Fail in OUT.RESULT - * - * Locks required: PHY_LOCK if doing a PHY BIST - * Return code: 0, EACCES (if PHY_LOCK is not held) + +/* MC_CMD_START_BIST_IN msgrequest */ +#define MC_CMD_START_BIST_IN_LEN 4 +#define MC_CMD_START_BIST_IN_TYPE_OFST 0 +#define MC_CMD_PHY_BIST_CABLE_SHORT 0x1 /* enum */ +#define MC_CMD_PHY_BIST_CABLE_LONG 0x2 /* enum */ +#define MC_CMD_BPX_SERDES_BIST 0x3 /* enum */ +#define MC_CMD_MC_LOOPBACK_BIST 0x4 /* enum */ +#define MC_CMD_PHY_BIST 0x5 /* enum */ + +/* MC_CMD_START_BIST_OUT msgresponse */ +#define MC_CMD_START_BIST_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_POLL_BIST + * Poll for BIST completion. */ #define MC_CMD_POLL_BIST 0x26 -#define MC_CMD_POLL_BIST_IN_LEN 0 -#define MC_CMD_POLL_BIST_OUT_LEN UNKNOWN -#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 -#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 -#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 -#define MC_CMD_POLL_BIST_RUNNING 1 -#define MC_CMD_POLL_BIST_PASSED 2 -#define MC_CMD_POLL_BIST_FAILED 3 -#define MC_CMD_POLL_BIST_TIMEOUT 4 -/* Generic: */ -#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 -/* SFT9001-specific: */ -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 -#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 1 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 2 -#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 3 -#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 4 -#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 9 -/* mrsfp "PHY" driver: */ -#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 -#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 1 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 2 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 3 -#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 4 -#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 5 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 6 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 7 -#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 8 - -/* MC_CMD_PHY_SPI: (variadic in, variadic out) - * Read/Write/Erase the PHY SPI device - * - * Locks required: PHY_LOCK - * Return code: 0, ETIME, EINVAL, EACCES (if PHY_LOCK is not held) - */ -#define MC_CMD_PHY_SPI 0x27 -#define MC_CMD_PHY_SPI_IN_LEN(_write_bytes) (12 + (_write_bytes)) -#define MC_CMD_PHY_SPI_IN_ARGS_OFST 0 -#define MC_CMD_PHY_SPI_IN_ARGS_ADDR_OFST 0 -#define MC_CMD_PHY_SPI_IN_ARGS_READ_BYTES_OFST 4 -#define MC_CMD_PHY_SPI_IN_ARGS_ERASE_ALL_OFST 8 -/* Data to write here */ -#define MC_CMD_PHY_SPI_IN_WRITE_BUFFER_OFSET 12 -#define MC_CMD_PHY_SPI_OUT_LEN(_read_bytes) (_read_bytes) -/* Data read here */ -#define MC_CMD_PHY_SPI_OUT_READ_BUFFER_OFST 0 - - -/* MC_CMD_GET_LOOPBACK_MODES: - * Returns a bitmask of loopback modes evailable at each speed. - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_POLL_BIST_IN msgrequest */ +#define MC_CMD_POLL_BIST_IN_LEN 0 + +/* MC_CMD_POLL_BIST_OUT msgresponse */ +#define MC_CMD_POLL_BIST_OUT_LEN 8 +#define MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 +#define MC_CMD_POLL_BIST_RUNNING 0x1 /* enum */ +#define MC_CMD_POLL_BIST_PASSED 0x2 /* enum */ +#define MC_CMD_POLL_BIST_FAILED 0x3 /* enum */ +#define MC_CMD_POLL_BIST_TIMEOUT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_OUT_PRIVATE_OFST 4 + +/* MC_CMD_POLL_BIST_OUT_SFT9001 msgresponse */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_LEN 36 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_A_OFST 4 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_B_OFST 8 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_C_OFST 12 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_LENGTH_D_OFST 16 +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_A_OFST 20 +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OK 0x1 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_OPEN 0x2 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTRA_PAIR_SHORT 0x3 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_INTER_PAIR_SHORT 0x4 /* enum */ +#define MC_CMD_POLL_BIST_SFT9001_PAIR_BUSY 0x9 /* enum */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_B_OFST 24 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_C_OFST 28 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ +#define MC_CMD_POLL_BIST_OUT_SFT9001_CABLE_STATUS_D_OFST 32 +/* Enum values, see field(s): */ +/* CABLE_STATUS_A */ + +/* MC_CMD_POLL_BIST_OUT_MRSFP msgresponse */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_LEN 8 +/* MC_CMD_POLL_BIST_OUT_RESULT_OFST 0 */ +/* Enum values, see field(s): */ +/* MC_CMD_POLL_BIST_OUT/MC_CMD_POLL_BIST_OUT_RESULT */ +#define MC_CMD_POLL_BIST_OUT_MRSFP_TEST_OFST 4 +#define MC_CMD_POLL_BIST_MRSFP_TEST_COMPLETE 0x0 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_WRITE 0x1 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_IO_EXP 0x2 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_OFF_I2C_NO_ACCESS_MODULE 0x3 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_IO_EXP_I2C_CONFIGURE 0x4 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_BUS_SWITCH_I2C_NO_CROSSTALK 0x5 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_PRESENCE 0x6 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_I2C_ACCESS 0x7 /* enum */ +#define MC_CMD_POLL_BIST_MRSFP_TEST_MODULE_ID_SANE_VALUE 0x8 /* enum */ + + +/***********************************/ +/* MC_CMD_FLUSH_RX_QUEUES + * Flush receive queue(s). + */ +#define MC_CMD_FLUSH_RX_QUEUES 0x27 + +/* MC_CMD_FLUSH_RX_QUEUES_IN msgrequest */ +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMIN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LENMAX 252 +#define MC_CMD_FLUSH_RX_QUEUES_IN_LEN(num) (0+4*(num)) +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_OFST 0 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_LEN 4 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MINNUM 1 +#define MC_CMD_FLUSH_RX_QUEUES_IN_QID_OFST_MAXNUM 63 + +/* MC_CMD_FLUSH_RX_QUEUES_OUT msgresponse */ +#define MC_CMD_FLUSH_RX_QUEUES_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_LOOPBACK_MODES + * Get port's loopback modes. */ #define MC_CMD_GET_LOOPBACK_MODES 0x28 -#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0 -#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32 -#define MC_CMD_GET_LOOPBACK_MODES_100M_OFST 0 -#define MC_CMD_GET_LOOPBACK_MODES_1G_OFST 8 -#define MC_CMD_GET_LOOPBACK_MODES_10G_OFST 16 -#define MC_CMD_GET_LOOPBACK_MODES_SUGGESTED_OFST 24 - -/* Flow control enumeration */ -#define MC_CMD_FCNTL_OFF 0 -#define MC_CMD_FCNTL_RESPOND 1 -#define MC_CMD_FCNTL_BIDIR 2 -/* Auto - Use what the link has autonegotiated - * - The driver should modify the advertised capabilities via SET_LINK.CAP - * to control the negotiated flow control mode. - * - Can only be set if the PHY supports PAUSE+ASYM capabilities - * - Never returned by GET_LINK as the value programmed into the MAC - */ -#define MC_CMD_FCNTL_AUTO 3 - -/* Generic mac fault bitmask */ -#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 -#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 -#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 -#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 -#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 -#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 - -/* MC_CMD_GET_LINK: - * Read the unified MAC/PHY link state - * - * Locks required: None - * Return code: 0, ETIME + +/* MC_CMD_GET_LOOPBACK_MODES_IN msgrequest */ +#define MC_CMD_GET_LOOPBACK_MODES_IN_LEN 0 + +/* MC_CMD_GET_LOOPBACK_MODES_OUT msgresponse */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_LEN 32 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_LO_OFST 0 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_100M_HI_OFST 4 +#define MC_CMD_LOOPBACK_NONE 0x0 /* enum */ +#define MC_CMD_LOOPBACK_DATA 0x1 /* enum */ +#define MC_CMD_LOOPBACK_GMAC 0x2 /* enum */ +#define MC_CMD_LOOPBACK_XGMII 0x3 /* enum */ +#define MC_CMD_LOOPBACK_XGXS 0x4 /* enum */ +#define MC_CMD_LOOPBACK_XAUI 0x5 /* enum */ +#define MC_CMD_LOOPBACK_GMII 0x6 /* enum */ +#define MC_CMD_LOOPBACK_SGMII 0x7 /* enum */ +#define MC_CMD_LOOPBACK_XGBR 0x8 /* enum */ +#define MC_CMD_LOOPBACK_XFI 0x9 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_FAR 0xa /* enum */ +#define MC_CMD_LOOPBACK_GMII_FAR 0xb /* enum */ +#define MC_CMD_LOOPBACK_SGMII_FAR 0xc /* enum */ +#define MC_CMD_LOOPBACK_XFI_FAR 0xd /* enum */ +#define MC_CMD_LOOPBACK_GPHY 0xe /* enum */ +#define MC_CMD_LOOPBACK_PHYXS 0xf /* enum */ +#define MC_CMD_LOOPBACK_PCS 0x10 /* enum */ +#define MC_CMD_LOOPBACK_PMAPMD 0x11 /* enum */ +#define MC_CMD_LOOPBACK_XPORT 0x12 /* enum */ +#define MC_CMD_LOOPBACK_XGMII_WS 0x13 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS 0x14 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_FAR 0x15 /* enum */ +#define MC_CMD_LOOPBACK_XAUI_WS_NEAR 0x16 /* enum */ +#define MC_CMD_LOOPBACK_GMII_WS 0x17 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS 0x18 /* enum */ +#define MC_CMD_LOOPBACK_XFI_WS_FAR 0x19 /* enum */ +#define MC_CMD_LOOPBACK_PHYXS_WS 0x1a /* enum */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_LO_OFST 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_1G_HI_OFST 12 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_LO_OFST 16 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_10G_HI_OFST 20 +/* Enum values, see field(s): */ +/* 100M */ +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LEN 8 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_LO_OFST 24 +#define MC_CMD_GET_LOOPBACK_MODES_OUT_SUGGESTED_HI_OFST 28 +/* Enum values, see field(s): */ +/* 100M */ + + +/***********************************/ +/* MC_CMD_GET_LINK + * Read the unified MAC/PHY link state. */ #define MC_CMD_GET_LINK 0x29 -#define MC_CMD_GET_LINK_IN_LEN 0 -#define MC_CMD_GET_LINK_OUT_LEN 28 -/* near-side and link-partner advertised capabilities */ -#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 -#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 -/* Autonegotiated speed in mbit/s. The link may still be down - * even if this reads non-zero */ -#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 -#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 -#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 -/* Whether we have overall link up */ -#define MC_CMD_GET_LINK_LINK_UP_LBN 0 -#define MC_CMD_GET_LINK_LINK_UP_WIDTH 1 -#define MC_CMD_GET_LINK_FULL_DUPLEX_LBN 1 -#define MC_CMD_GET_LINK_FULL_DUPLEX_WIDTH 1 -/* Whether we have link at the layers provided by the BPX */ -#define MC_CMD_GET_LINK_BPX_LINK_LBN 2 -#define MC_CMD_GET_LINK_BPX_LINK_WIDTH 1 -/* Whether the PHY has external link */ -#define MC_CMD_GET_LINK_PHY_LINK_LBN 3 -#define MC_CMD_GET_LINK_PHY_LINK_WIDTH 1 -#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 -#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 - -/* MC_CMD_SET_LINK: - * Write the unified MAC/PHY link configuration - * - * A loopback speed of "0" is supported, and means - * (choose any available speed) - * - * Locks required: None - * Return code: 0, EINVAL, ETIME + +/* MC_CMD_GET_LINK_IN msgrequest */ +#define MC_CMD_GET_LINK_IN_LEN 0 + +/* MC_CMD_GET_LINK_OUT msgresponse */ +#define MC_CMD_GET_LINK_OUT_LEN 28 +#define MC_CMD_GET_LINK_OUT_CAP_OFST 0 +#define MC_CMD_GET_LINK_OUT_LP_CAP_OFST 4 +#define MC_CMD_GET_LINK_OUT_LINK_SPEED_OFST 8 +#define MC_CMD_GET_LINK_OUT_LOOPBACK_MODE_OFST 12 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_GET_LINK_OUT_FLAGS_OFST 16 +#define MC_CMD_GET_LINK_OUT_LINK_UP_LBN 0 +#define MC_CMD_GET_LINK_OUT_LINK_UP_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN 1 +#define MC_CMD_GET_LINK_OUT_FULL_DUPLEX_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_LBN 2 +#define MC_CMD_GET_LINK_OUT_BPX_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_LBN 3 +#define MC_CMD_GET_LINK_OUT_PHY_LINK_WIDTH 1 +#define MC_CMD_GET_LINK_OUT_FCNTL_OFST 20 +#define MC_CMD_FCNTL_OFF 0x0 /* enum */ +#define MC_CMD_FCNTL_RESPOND 0x1 /* enum */ +#define MC_CMD_FCNTL_BIDIR 0x2 /* enum */ +#define MC_CMD_GET_LINK_OUT_MAC_FAULT_OFST 24 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_LBN 0 +#define MC_CMD_MAC_FAULT_XGMII_LOCAL_WIDTH 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_LBN 1 +#define MC_CMD_MAC_FAULT_XGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_LBN 2 +#define MC_CMD_MAC_FAULT_SGMII_REMOTE_WIDTH 1 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_LBN 3 +#define MC_CMD_MAC_FAULT_PENDING_RECONFIG_WIDTH 1 + + +/***********************************/ +/* MC_CMD_SET_LINK + * Write the unified MAC/PHY link configuration. */ #define MC_CMD_SET_LINK 0x2a -#define MC_CMD_SET_LINK_IN_LEN 16 -#define MC_CMD_SET_LINK_IN_CAP_OFST 0 -#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 -#define MC_CMD_SET_LINK_LOWPOWER_LBN 0 -#define MC_CMD_SET_LINK_LOWPOWER_WIDTH 1 -#define MC_CMD_SET_LINK_POWEROFF_LBN 1 -#define MC_CMD_SET_LINK_POWEROFF_WIDTH 1 -#define MC_CMD_SET_LINK_TXDIS_LBN 2 -#define MC_CMD_SET_LINK_TXDIS_WIDTH 1 -#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 -#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 -#define MC_CMD_SET_LINK_OUT_LEN 0 - -/* MC_CMD_SET_ID_LED: - * Set indentification LED state - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_SET_LINK_IN msgrequest */ +#define MC_CMD_SET_LINK_IN_LEN 16 +#define MC_CMD_SET_LINK_IN_CAP_OFST 0 +#define MC_CMD_SET_LINK_IN_FLAGS_OFST 4 +#define MC_CMD_SET_LINK_IN_LOWPOWER_LBN 0 +#define MC_CMD_SET_LINK_IN_LOWPOWER_WIDTH 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_LBN 1 +#define MC_CMD_SET_LINK_IN_POWEROFF_WIDTH 1 +#define MC_CMD_SET_LINK_IN_TXDIS_LBN 2 +#define MC_CMD_SET_LINK_IN_TXDIS_WIDTH 1 +#define MC_CMD_SET_LINK_IN_LOOPBACK_MODE_OFST 8 +/* Enum values, see field(s): */ +/* MC_CMD_GET_LOOPBACK_MODES/MC_CMD_GET_LOOPBACK_MODES_OUT/100M */ +#define MC_CMD_SET_LINK_IN_LOOPBACK_SPEED_OFST 12 + +/* MC_CMD_SET_LINK_OUT msgresponse */ +#define MC_CMD_SET_LINK_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_ID_LED + * Set indentification LED state. */ #define MC_CMD_SET_ID_LED 0x2b -#define MC_CMD_SET_ID_LED_IN_LEN 4 -#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 -#define MC_CMD_LED_OFF 0 -#define MC_CMD_LED_ON 1 -#define MC_CMD_LED_DEFAULT 2 -#define MC_CMD_SET_ID_LED_OUT_LEN 0 - -/* MC_CMD_SET_MAC: - * Set MAC configuration - * - * The MTU is the MTU programmed directly into the XMAC/GMAC - * (inclusive of EtherII, VLAN, bug16011 padding) - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_SET_ID_LED_IN msgrequest */ +#define MC_CMD_SET_ID_LED_IN_LEN 4 +#define MC_CMD_SET_ID_LED_IN_STATE_OFST 0 +#define MC_CMD_LED_OFF 0x0 /* enum */ +#define MC_CMD_LED_ON 0x1 /* enum */ +#define MC_CMD_LED_DEFAULT 0x2 /* enum */ + +/* MC_CMD_SET_ID_LED_OUT msgresponse */ +#define MC_CMD_SET_ID_LED_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MAC + * Set MAC configuration. */ #define MC_CMD_SET_MAC 0x2c -#define MC_CMD_SET_MAC_IN_LEN 24 -#define MC_CMD_SET_MAC_IN_MTU_OFST 0 -#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 -#define MC_CMD_SET_MAC_IN_ADDR_OFST 8 -#define MC_CMD_SET_MAC_IN_REJECT_OFST 16 -#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 -#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 -#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 -#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 -#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 -#define MC_CMD_SET_MAC_OUT_LEN 0 - -/* MC_CMD_PHY_STATS: - * Get generic PHY statistics - * - * This call returns the statistics for a generic PHY in a sparse - * array (indexed by the enumerate). Each value is represented by - * a 32bit number. - * - * If the DMA_ADDR is 0, then no DMA is performed, and the statistics - * may be read directly out of shared memory. If DMA_ADDR != 0, then - * the statistics are dmad to that (page-aligned location) - * - * Locks required: None - * Returns: 0, ETIME - * Response methods: shared memory, event + +/* MC_CMD_SET_MAC_IN msgrequest */ +#define MC_CMD_SET_MAC_IN_LEN 24 +#define MC_CMD_SET_MAC_IN_MTU_OFST 0 +#define MC_CMD_SET_MAC_IN_DRAIN_OFST 4 +#define MC_CMD_SET_MAC_IN_ADDR_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_LEN 8 +#define MC_CMD_SET_MAC_IN_ADDR_LO_OFST 8 +#define MC_CMD_SET_MAC_IN_ADDR_HI_OFST 12 +#define MC_CMD_SET_MAC_IN_REJECT_OFST 16 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_LBN 0 +#define MC_CMD_SET_MAC_IN_REJECT_UNCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_LBN 1 +#define MC_CMD_SET_MAC_IN_REJECT_BRDCST_WIDTH 1 +#define MC_CMD_SET_MAC_IN_FCNTL_OFST 20 +/* MC_CMD_FCNTL_OFF 0x0 */ +/* MC_CMD_FCNTL_RESPOND 0x1 */ +/* MC_CMD_FCNTL_BIDIR 0x2 */ +#define MC_CMD_FCNTL_AUTO 0x3 /* enum */ + +/* MC_CMD_SET_MAC_OUT msgresponse */ +#define MC_CMD_SET_MAC_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_PHY_STATS + * Get generic PHY statistics. */ #define MC_CMD_PHY_STATS 0x2d -#define MC_CMD_PHY_STATS_IN_LEN 8 -#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0 -#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (MC_CMD_PHY_NSTATS * 4) - -/* Unified MAC statistics enumeration */ -#define MC_CMD_MAC_GENERATION_START 0 -#define MC_CMD_MAC_TX_PKTS 1 -#define MC_CMD_MAC_TX_PAUSE_PKTS 2 -#define MC_CMD_MAC_TX_CONTROL_PKTS 3 -#define MC_CMD_MAC_TX_UNICAST_PKTS 4 -#define MC_CMD_MAC_TX_MULTICAST_PKTS 5 -#define MC_CMD_MAC_TX_BROADCAST_PKTS 6 -#define MC_CMD_MAC_TX_BYTES 7 -#define MC_CMD_MAC_TX_BAD_BYTES 8 -#define MC_CMD_MAC_TX_LT64_PKTS 9 -#define MC_CMD_MAC_TX_64_PKTS 10 -#define MC_CMD_MAC_TX_65_TO_127_PKTS 11 -#define MC_CMD_MAC_TX_128_TO_255_PKTS 12 -#define MC_CMD_MAC_TX_256_TO_511_PKTS 13 -#define MC_CMD_MAC_TX_512_TO_1023_PKTS 14 -#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 15 -#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 16 -#define MC_CMD_MAC_TX_GTJUMBO_PKTS 17 -#define MC_CMD_MAC_TX_BAD_FCS_PKTS 18 -#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 19 -#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 20 -#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 21 -#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 22 -#define MC_CMD_MAC_TX_DEFERRED_PKTS 23 -#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 24 -#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 25 -#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 26 -#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 27 -#define MC_CMD_MAC_RX_PKTS 28 -#define MC_CMD_MAC_RX_PAUSE_PKTS 29 -#define MC_CMD_MAC_RX_GOOD_PKTS 30 -#define MC_CMD_MAC_RX_CONTROL_PKTS 31 -#define MC_CMD_MAC_RX_UNICAST_PKTS 32 -#define MC_CMD_MAC_RX_MULTICAST_PKTS 33 -#define MC_CMD_MAC_RX_BROADCAST_PKTS 34 -#define MC_CMD_MAC_RX_BYTES 35 -#define MC_CMD_MAC_RX_BAD_BYTES 36 -#define MC_CMD_MAC_RX_64_PKTS 37 -#define MC_CMD_MAC_RX_65_TO_127_PKTS 38 -#define MC_CMD_MAC_RX_128_TO_255_PKTS 39 -#define MC_CMD_MAC_RX_256_TO_511_PKTS 40 -#define MC_CMD_MAC_RX_512_TO_1023_PKTS 41 -#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 42 -#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 43 -#define MC_CMD_MAC_RX_GTJUMBO_PKTS 44 -#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 45 -#define MC_CMD_MAC_RX_BAD_FCS_PKTS 46 -#define MC_CMD_MAC_RX_OVERFLOW_PKTS 47 -#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 48 -#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 49 -#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 50 -#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 51 -#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 52 -#define MC_CMD_MAC_RX_JABBER_PKTS 53 -#define MC_CMD_MAC_RX_NODESC_DROPS 54 -#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 55 -#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 56 -#define MC_CMD_MAC_RX_LANES01_DISP_ERR 57 -#define MC_CMD_MAC_RX_LANES23_DISP_ERR 58 -#define MC_CMD_MAC_RX_MATCH_FAULT 59 -#define MC_CMD_GMAC_DMABUF_START 64 -#define MC_CMD_GMAC_DMABUF_END 95 -/* Insert new members here. */ -#define MC_CMD_MAC_GENERATION_END 96 -#define MC_CMD_MAC_NSTATS (MC_CMD_MAC_GENERATION_END+1) - -/* MC_CMD_MAC_STATS: - * Get unified GMAC/XMAC statistics - * - * This call returns unified statistics maintained by the MC as it - * switches between the GMAC and XMAC. The MC will write out all - * supported stats. The driver should zero initialise the buffer to - * guarantee consistent results. - * - * Locks required: None - * Returns: 0 - * Response methods: shared memory, event - */ -#define MC_CMD_MAC_STATS 0x2e -#define MC_CMD_MAC_STATS_IN_LEN 16 -#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_MAC_STATS_IN_CMD_OFST 8 -#define MC_CMD_MAC_STATS_CMD_DMA_LBN 0 -#define MC_CMD_MAC_STATS_CMD_DMA_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_CLEAR_LBN 1 -#define MC_CMD_MAC_STATS_CMD_CLEAR_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_LBN 2 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CHANGE_WIDTH 1 -/* Remaining PERIOD* fields only relevant when PERIODIC_CHANGE is set */ -#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_LBN 3 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_ENABLE_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_LBN 4 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_CLEAR_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_LBN 5 -#define MC_CMD_MAC_STATS_CMD_PERIODIC_NOEVENT_WIDTH 1 -#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_LBN 16 -#define MC_CMD_MAC_STATS_CMD_PERIOD_MS_WIDTH 16 -#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 - -#define MC_CMD_MAC_STATS_OUT_LEN 0 - -/* Callisto flags */ -#define MC_CMD_SFT9001_ROBUST_LBN 0 -#define MC_CMD_SFT9001_ROBUST_WIDTH 1 -#define MC_CMD_SFT9001_SHORT_REACH_LBN 1 -#define MC_CMD_SFT9001_SHORT_REACH_WIDTH 1 - -/* MC_CMD_SFT9001_GET: - * Read current callisto specific setting - * - * Locks required: None - * Returns: 0, ETIME - */ -#define MC_CMD_SFT9001_GET 0x30 -#define MC_CMD_SFT9001_GET_IN_LEN 0 -#define MC_CMD_SFT9001_GET_OUT_LEN 4 -#define MC_CMD_SFT9001_GET_OUT_FLAGS_OFST 0 -/* MC_CMD_SFT9001_SET: - * Write current callisto specific setting - * - * Locks required: None - * Returns: 0, ETIME, EINVAL +/* MC_CMD_PHY_STATS_IN msgrequest */ +#define MC_CMD_PHY_STATS_IN_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_PHY_STATS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_PHY_STATS_OUT_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_PHY_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_PHY_STATS_OUT_NO_DMA_LEN (((MC_CMD_PHY_NSTATS*32))>>3) +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_LEN 4 +#define MC_CMD_PHY_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_PHY_NSTATS +#define MC_CMD_OUI 0x0 /* enum */ +#define MC_CMD_PMA_PMD_LINK_UP 0x1 /* enum */ +#define MC_CMD_PMA_PMD_RX_FAULT 0x2 /* enum */ +#define MC_CMD_PMA_PMD_TX_FAULT 0x3 /* enum */ +#define MC_CMD_PMA_PMD_SIGNAL 0x4 /* enum */ +#define MC_CMD_PMA_PMD_SNR_A 0x5 /* enum */ +#define MC_CMD_PMA_PMD_SNR_B 0x6 /* enum */ +#define MC_CMD_PMA_PMD_SNR_C 0x7 /* enum */ +#define MC_CMD_PMA_PMD_SNR_D 0x8 /* enum */ +#define MC_CMD_PCS_LINK_UP 0x9 /* enum */ +#define MC_CMD_PCS_RX_FAULT 0xa /* enum */ +#define MC_CMD_PCS_TX_FAULT 0xb /* enum */ +#define MC_CMD_PCS_BER 0xc /* enum */ +#define MC_CMD_PCS_BLOCK_ERRORS 0xd /* enum */ +#define MC_CMD_PHYXS_LINK_UP 0xe /* enum */ +#define MC_CMD_PHYXS_RX_FAULT 0xf /* enum */ +#define MC_CMD_PHYXS_TX_FAULT 0x10 /* enum */ +#define MC_CMD_PHYXS_ALIGN 0x11 /* enum */ +#define MC_CMD_PHYXS_SYNC 0x12 /* enum */ +#define MC_CMD_AN_LINK_UP 0x13 /* enum */ +#define MC_CMD_AN_COMPLETE 0x14 /* enum */ +#define MC_CMD_AN_10GBT_STATUS 0x15 /* enum */ +#define MC_CMD_CL22_LINK_UP 0x16 /* enum */ +#define MC_CMD_PHY_NSTATS 0x17 /* enum */ + + +/***********************************/ +/* MC_CMD_MAC_STATS + * Get generic MAC statistics. */ -#define MC_CMD_SFT9001_SET 0x31 -#define MC_CMD_SFT9001_SET_IN_LEN 4 -#define MC_CMD_SFT9001_SET_IN_FLAGS_OFST 0 -#define MC_CMD_SFT9001_SET_OUT_LEN 0 - +#define MC_CMD_MAC_STATS 0x2e -/* MC_CMD_WOL_FILTER_SET: - * Set a WoL filter - * - * Locks required: None - * Returns: 0, EBUSY, EINVAL, ENOSYS +/* MC_CMD_MAC_STATS_IN msgrequest */ +#define MC_CMD_MAC_STATS_IN_LEN 16 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_MAC_STATS_IN_DMA_ADDR_HI_OFST 4 +#define MC_CMD_MAC_STATS_IN_CMD_OFST 8 +#define MC_CMD_MAC_STATS_IN_DMA_LBN 0 +#define MC_CMD_MAC_STATS_IN_DMA_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_LBN 1 +#define MC_CMD_MAC_STATS_IN_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_LBN 2 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CHANGE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_LBN 3 +#define MC_CMD_MAC_STATS_IN_PERIODIC_ENABLE_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_LBN 4 +#define MC_CMD_MAC_STATS_IN_PERIODIC_CLEAR_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_LBN 5 +#define MC_CMD_MAC_STATS_IN_PERIODIC_NOEVENT_WIDTH 1 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_LBN 16 +#define MC_CMD_MAC_STATS_IN_PERIOD_MS_WIDTH 16 +#define MC_CMD_MAC_STATS_IN_DMA_LEN_OFST 12 + +/* MC_CMD_MAC_STATS_OUT_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_DMA_LEN 0 + +/* MC_CMD_MAC_STATS_OUT_NO_DMA msgresponse */ +#define MC_CMD_MAC_STATS_OUT_NO_DMA_LEN (((MC_CMD_MAC_NSTATS*64))>>3) +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LEN 8 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_LO_OFST 0 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_HI_OFST 4 +#define MC_CMD_MAC_STATS_OUT_NO_DMA_STATISTICS_NUM MC_CMD_MAC_NSTATS +#define MC_CMD_MAC_GENERATION_START 0x0 /* enum */ +#define MC_CMD_MAC_TX_PKTS 0x1 /* enum */ +#define MC_CMD_MAC_TX_PAUSE_PKTS 0x2 /* enum */ +#define MC_CMD_MAC_TX_CONTROL_PKTS 0x3 /* enum */ +#define MC_CMD_MAC_TX_UNICAST_PKTS 0x4 /* enum */ +#define MC_CMD_MAC_TX_MULTICAST_PKTS 0x5 /* enum */ +#define MC_CMD_MAC_TX_BROADCAST_PKTS 0x6 /* enum */ +#define MC_CMD_MAC_TX_BYTES 0x7 /* enum */ +#define MC_CMD_MAC_TX_BAD_BYTES 0x8 /* enum */ +#define MC_CMD_MAC_TX_LT64_PKTS 0x9 /* enum */ +#define MC_CMD_MAC_TX_64_PKTS 0xa /* enum */ +#define MC_CMD_MAC_TX_65_TO_127_PKTS 0xb /* enum */ +#define MC_CMD_MAC_TX_128_TO_255_PKTS 0xc /* enum */ +#define MC_CMD_MAC_TX_256_TO_511_PKTS 0xd /* enum */ +#define MC_CMD_MAC_TX_512_TO_1023_PKTS 0xe /* enum */ +#define MC_CMD_MAC_TX_1024_TO_15XX_PKTS 0xf /* enum */ +#define MC_CMD_MAC_TX_15XX_TO_JUMBO_PKTS 0x10 /* enum */ +#define MC_CMD_MAC_TX_GTJUMBO_PKTS 0x11 /* enum */ +#define MC_CMD_MAC_TX_BAD_FCS_PKTS 0x12 /* enum */ +#define MC_CMD_MAC_TX_SINGLE_COLLISION_PKTS 0x13 /* enum */ +#define MC_CMD_MAC_TX_MULTIPLE_COLLISION_PKTS 0x14 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_COLLISION_PKTS 0x15 /* enum */ +#define MC_CMD_MAC_TX_LATE_COLLISION_PKTS 0x16 /* enum */ +#define MC_CMD_MAC_TX_DEFERRED_PKTS 0x17 /* enum */ +#define MC_CMD_MAC_TX_EXCESSIVE_DEFERRED_PKTS 0x18 /* enum */ +#define MC_CMD_MAC_TX_NON_TCPUDP_PKTS 0x19 /* enum */ +#define MC_CMD_MAC_TX_MAC_SRC_ERR_PKTS 0x1a /* enum */ +#define MC_CMD_MAC_TX_IP_SRC_ERR_PKTS 0x1b /* enum */ +#define MC_CMD_MAC_RX_PKTS 0x1c /* enum */ +#define MC_CMD_MAC_RX_PAUSE_PKTS 0x1d /* enum */ +#define MC_CMD_MAC_RX_GOOD_PKTS 0x1e /* enum */ +#define MC_CMD_MAC_RX_CONTROL_PKTS 0x1f /* enum */ +#define MC_CMD_MAC_RX_UNICAST_PKTS 0x20 /* enum */ +#define MC_CMD_MAC_RX_MULTICAST_PKTS 0x21 /* enum */ +#define MC_CMD_MAC_RX_BROADCAST_PKTS 0x22 /* enum */ +#define MC_CMD_MAC_RX_BYTES 0x23 /* enum */ +#define MC_CMD_MAC_RX_BAD_BYTES 0x24 /* enum */ +#define MC_CMD_MAC_RX_64_PKTS 0x25 /* enum */ +#define MC_CMD_MAC_RX_65_TO_127_PKTS 0x26 /* enum */ +#define MC_CMD_MAC_RX_128_TO_255_PKTS 0x27 /* enum */ +#define MC_CMD_MAC_RX_256_TO_511_PKTS 0x28 /* enum */ +#define MC_CMD_MAC_RX_512_TO_1023_PKTS 0x29 /* enum */ +#define MC_CMD_MAC_RX_1024_TO_15XX_PKTS 0x2a /* enum */ +#define MC_CMD_MAC_RX_15XX_TO_JUMBO_PKTS 0x2b /* enum */ +#define MC_CMD_MAC_RX_GTJUMBO_PKTS 0x2c /* enum */ +#define MC_CMD_MAC_RX_UNDERSIZE_PKTS 0x2d /* enum */ +#define MC_CMD_MAC_RX_BAD_FCS_PKTS 0x2e /* enum */ +#define MC_CMD_MAC_RX_OVERFLOW_PKTS 0x2f /* enum */ +#define MC_CMD_MAC_RX_FALSE_CARRIER_PKTS 0x30 /* enum */ +#define MC_CMD_MAC_RX_SYMBOL_ERROR_PKTS 0x31 /* enum */ +#define MC_CMD_MAC_RX_ALIGN_ERROR_PKTS 0x32 /* enum */ +#define MC_CMD_MAC_RX_LENGTH_ERROR_PKTS 0x33 /* enum */ +#define MC_CMD_MAC_RX_INTERNAL_ERROR_PKTS 0x34 /* enum */ +#define MC_CMD_MAC_RX_JABBER_PKTS 0x35 /* enum */ +#define MC_CMD_MAC_RX_NODESC_DROPS 0x36 /* enum */ +#define MC_CMD_MAC_RX_LANES01_CHAR_ERR 0x37 /* enum */ +#define MC_CMD_MAC_RX_LANES23_CHAR_ERR 0x38 /* enum */ +#define MC_CMD_MAC_RX_LANES01_DISP_ERR 0x39 /* enum */ +#define MC_CMD_MAC_RX_LANES23_DISP_ERR 0x3a /* enum */ +#define MC_CMD_MAC_RX_MATCH_FAULT 0x3b /* enum */ +#define MC_CMD_GMAC_DMABUF_START 0x40 /* enum */ +#define MC_CMD_GMAC_DMABUF_END 0x5f /* enum */ +#define MC_CMD_MAC_GENERATION_END 0x60 /* enum */ +#define MC_CMD_MAC_NSTATS 0x61 /* enum */ + + +/***********************************/ +/* MC_CMD_SRIOV + * to be documented + */ +#define MC_CMD_SRIOV 0x30 + +/* MC_CMD_SRIOV_IN msgrequest */ +#define MC_CMD_SRIOV_IN_LEN 12 +#define MC_CMD_SRIOV_IN_ENABLE_OFST 0 +#define MC_CMD_SRIOV_IN_VI_BASE_OFST 4 +#define MC_CMD_SRIOV_IN_VF_COUNT_OFST 8 + +/* MC_CMD_SRIOV_OUT msgresponse */ +#define MC_CMD_SRIOV_OUT_LEN 8 +#define MC_CMD_SRIOV_OUT_VI_SCALE_OFST 0 +#define MC_CMD_SRIOV_OUT_VF_TOTAL_OFST 4 + +/* MC_CMD_MEMCPY_RECORD_TYPEDEF structuredef */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LEN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_OFST 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_LBN 0 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_NUM_RECORDS_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_OFST 4 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_LBN 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LO_OFST 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_HI_OFST 12 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_LBN 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_TO_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_OFST 16 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_RID_INLINE 0x100 /* enum */ +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_LBN 128 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_RID_WIDTH 32 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LEN 8 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LO_OFST 20 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_HI_OFST 24 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_LBN 160 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_FROM_ADDR_WIDTH 64 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_OFST 28 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_LBN 224 +#define MC_CMD_MEMCPY_RECORD_TYPEDEF_LENGTH_WIDTH 32 + + +/***********************************/ +/* MC_CMD_MEMCPY + * Perform memory copy operation. + */ +#define MC_CMD_MEMCPY 0x31 + +/* MC_CMD_MEMCPY_IN msgrequest */ +#define MC_CMD_MEMCPY_IN_LENMIN 32 +#define MC_CMD_MEMCPY_IN_LENMAX 224 +#define MC_CMD_MEMCPY_IN_LEN(num) (0+32*(num)) +#define MC_CMD_MEMCPY_IN_RECORD_OFST 0 +#define MC_CMD_MEMCPY_IN_RECORD_LEN 32 +#define MC_CMD_MEMCPY_IN_RECORD_MINNUM 1 +#define MC_CMD_MEMCPY_IN_RECORD_MAXNUM 7 + +/* MC_CMD_MEMCPY_OUT msgresponse */ +#define MC_CMD_MEMCPY_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_SET + * Set a WoL filter. */ #define MC_CMD_WOL_FILTER_SET 0x32 -#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 /* 190 rounded up to a word */ -#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 -#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 - -/* There is a union at offset 8, following defines overlap due to - * this */ -#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 - -#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST - -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 4) -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 8) -#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 10) - -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 16) -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 32) -#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 34) - -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 48) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 176) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 177) -#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST \ - (MC_CMD_WOL_FILTER_SET_IN_DATA_OFST + 178) - -#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST \ - MC_CMD_WOL_FILTER_SET_IN_DATA_OFST -#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 -#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1 - -#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 -#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 - -/* WOL Filter types enumeration */ -#define MC_CMD_WOL_TYPE_MAGIC 0x0 - /* unused 0x1 */ -#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 -#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 -#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 -#define MC_CMD_WOL_TYPE_BITMAP 0x5 -#define MC_CMD_WOL_TYPE_LINK 0x6 -#define MC_CMD_WOL_TYPE_MAX 0x7 - -#define MC_CMD_FILTER_MODE_SIMPLE 0x0 -#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff - -/* MC_CMD_WOL_FILTER_REMOVE: - * Remove a WoL filter - * - * Locks required: None - * Returns: 0, EINVAL, ENOSYS + +/* MC_CMD_WOL_FILTER_SET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LEN 192 +#define MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 +#define MC_CMD_FILTER_MODE_SIMPLE 0x0 /* enum */ +#define MC_CMD_FILTER_MODE_STRUCTURED 0xffffffff /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 +#define MC_CMD_WOL_TYPE_MAGIC 0x0 /* enum */ +#define MC_CMD_WOL_TYPE_WIN_MAGIC 0x2 /* enum */ +#define MC_CMD_WOL_TYPE_IPV4_SYN 0x3 /* enum */ +#define MC_CMD_WOL_TYPE_IPV6_SYN 0x4 /* enum */ +#define MC_CMD_WOL_TYPE_BITMAP 0x5 /* enum */ +#define MC_CMD_WOL_TYPE_LINK 0x6 /* enum */ +#define MC_CMD_WOL_TYPE_MAX 0x7 /* enum */ +#define MC_CMD_WOL_FILTER_SET_IN_DATA_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_LEN 4 +#define MC_CMD_WOL_FILTER_SET_IN_DATA_NUM 46 + +/* MC_CMD_WOL_FILTER_SET_IN_MAGIC msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_LEN 16 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LEN 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_LO_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_MAGIC_MAC_HI_OFST 12 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_LEN 20 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_IP_OFST 12 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_OFST 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_OFST 18 +#define MC_CMD_WOL_FILTER_SET_IN_IPV4_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_LEN 44 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_OFST 24 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_IP_LEN 16 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_OFST 40 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_SRC_PORT_LEN 2 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_OFST 42 +#define MC_CMD_WOL_FILTER_SET_IN_IPV6_SYN_DST_PORT_LEN 2 + +/* MC_CMD_WOL_FILTER_SET_IN_BITMAP msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN 187 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_MASK_LEN 48 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_OFST 56 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_BITMAP_LEN 128 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_OFST 184 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LEN_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_OFST 185 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER3_LEN 1 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_OFST 186 +#define MC_CMD_WOL_FILTER_SET_IN_BITMAP_LAYER4_LEN 1 + +/* MC_CMD_WOL_FILTER_SET_IN_LINK msgrequest */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_LEN 12 +/* MC_CMD_WOL_FILTER_SET_IN_FILTER_MODE_OFST 0 */ +/* MC_CMD_WOL_FILTER_SET_IN_WOL_TYPE_OFST 4 */ +#define MC_CMD_WOL_FILTER_SET_IN_LINK_MASK_OFST 8 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_LBN 0 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_UP_WIDTH 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_LBN 1 +#define MC_CMD_WOL_FILTER_SET_IN_LINK_DOWN_WIDTH 1 + +/* MC_CMD_WOL_FILTER_SET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_SET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_SET_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_REMOVE + * Remove a WoL filter. */ #define MC_CMD_WOL_FILTER_REMOVE 0x33 -#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 -#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 -#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 +/* MC_CMD_WOL_FILTER_REMOVE_IN msgrequest */ +#define MC_CMD_WOL_FILTER_REMOVE_IN_LEN 4 +#define MC_CMD_WOL_FILTER_REMOVE_IN_FILTER_ID_OFST 0 -/* MC_CMD_WOL_FILTER_RESET: - * Reset (i.e. remove all) WoL filters - * - * Locks required: None - * Returns: 0, ENOSYS +/* MC_CMD_WOL_FILTER_REMOVE_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_REMOVE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WOL_FILTER_RESET + * Reset (i.e. remove all) WoL filters. */ #define MC_CMD_WOL_FILTER_RESET 0x34 -#define MC_CMD_WOL_FILTER_RESET_IN_LEN 0 -#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0 -/* MC_CMD_SET_MCAST_HASH: - * Set the MCASH hash value without otherwise - * reconfiguring the MAC +/* MC_CMD_WOL_FILTER_RESET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_RESET_IN_LEN 4 +#define MC_CMD_WOL_FILTER_RESET_IN_MASK_OFST 0 +#define MC_CMD_WOL_FILTER_RESET_IN_WAKE_FILTERS 0x1 /* enum */ +#define MC_CMD_WOL_FILTER_RESET_IN_LIGHTSOUT_OFFLOADS 0x2 /* enum */ + +/* MC_CMD_WOL_FILTER_RESET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_RESET_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SET_MCAST_HASH + * Set the MCASH hash value. */ #define MC_CMD_SET_MCAST_HASH 0x35 -#define MC_CMD_SET_MCAST_HASH_IN_LEN 32 -#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0 -#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16 -#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0 -/* MC_CMD_NVRAM_TYPES: - * Return bitfield indicating available types of virtual NVRAM partitions - * - * Locks required: none - * Returns: 0 +/* MC_CMD_SET_MCAST_HASH_IN msgrequest */ +#define MC_CMD_SET_MCAST_HASH_IN_LEN 32 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_OFST 0 +#define MC_CMD_SET_MCAST_HASH_IN_HASH0_LEN 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_OFST 16 +#define MC_CMD_SET_MCAST_HASH_IN_HASH1_LEN 16 + +/* MC_CMD_SET_MCAST_HASH_OUT msgresponse */ +#define MC_CMD_SET_MCAST_HASH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_TYPES + * Get virtual NVRAM partitions information. */ #define MC_CMD_NVRAM_TYPES 0x36 -#define MC_CMD_NVRAM_TYPES_IN_LEN 0 -#define MC_CMD_NVRAM_TYPES_OUT_LEN 4 -#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 - -/* Supported NVRAM types */ -#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0 -#define MC_CMD_NVRAM_TYPE_MC_FW 1 -#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 2 -#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 3 -#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 4 -#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 5 -#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 6 -#define MC_CMD_NVRAM_TYPE_EXP_ROM 7 -#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 8 -#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 9 -#define MC_CMD_NVRAM_TYPE_PHY_PORT0 10 -#define MC_CMD_NVRAM_TYPE_PHY_PORT1 11 -#define MC_CMD_NVRAM_TYPE_LOG 12 - -/* MC_CMD_NVRAM_INFO: - * Read info about a virtual NVRAM partition - * - * Locks required: none - * Returns: 0, EINVAL (bad type) + +/* MC_CMD_NVRAM_TYPES_IN msgrequest */ +#define MC_CMD_NVRAM_TYPES_IN_LEN 0 + +/* MC_CMD_NVRAM_TYPES_OUT msgresponse */ +#define MC_CMD_NVRAM_TYPES_OUT_LEN 4 +#define MC_CMD_NVRAM_TYPES_OUT_TYPES_OFST 0 +#define MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO 0x0 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW 0x1 /* enum */ +#define MC_CMD_NVRAM_TYPE_MC_FW_BACKUP 0x2 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT0 0x3 /* enum */ +#define MC_CMD_NVRAM_TYPE_STATIC_CFG_PORT1 0x4 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT0 0x5 /* enum */ +#define MC_CMD_NVRAM_TYPE_DYNAMIC_CFG_PORT1 0x6 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM 0x7 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT0 0x8 /* enum */ +#define MC_CMD_NVRAM_TYPE_EXP_ROM_CFG_PORT1 0x9 /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT0 0xa /* enum */ +#define MC_CMD_NVRAM_TYPE_PHY_PORT1 0xb /* enum */ +#define MC_CMD_NVRAM_TYPE_LOG 0xc /* enum */ +#define MC_CMD_NVRAM_TYPE_FPGA 0xd /* enum */ + + +/***********************************/ +/* MC_CMD_NVRAM_INFO + * Read info about a virtual NVRAM partition. */ #define MC_CMD_NVRAM_INFO 0x37 -#define MC_CMD_NVRAM_INFO_IN_LEN 4 -#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_INFO_OUT_LEN 24 -#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 -#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 -#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 -#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 -#define MC_CMD_NVRAM_PROTECTED_LBN 0 -#define MC_CMD_NVRAM_PROTECTED_WIDTH 1 -#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 -#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 - -/* MC_CMD_NVRAM_UPDATE_START: - * Start a group of update operations on a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_INFO_IN msgrequest */ +#define MC_CMD_NVRAM_INFO_IN_LEN 4 +#define MC_CMD_NVRAM_INFO_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_INFO_OUT msgresponse */ +#define MC_CMD_NVRAM_INFO_OUT_LEN 24 +#define MC_CMD_NVRAM_INFO_OUT_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_INFO_OUT_SIZE_OFST 4 +#define MC_CMD_NVRAM_INFO_OUT_ERASESIZE_OFST 8 +#define MC_CMD_NVRAM_INFO_OUT_FLAGS_OFST 12 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_LBN 0 +#define MC_CMD_NVRAM_INFO_OUT_PROTECTED_WIDTH 1 +#define MC_CMD_NVRAM_INFO_OUT_PHYSDEV_OFST 16 +#define MC_CMD_NVRAM_INFO_OUT_PHYSADDR_OFST 20 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_START + * Start a group of update operations on a virtual NVRAM partition. */ #define MC_CMD_NVRAM_UPDATE_START 0x38 -#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 -#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0 -/* MC_CMD_NVRAM_READ: - * Read data from a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) +/* MC_CMD_NVRAM_UPDATE_START_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_START_IN_LEN 4 +#define MC_CMD_NVRAM_UPDATE_START_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_UPDATE_START_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_START_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_READ + * Read data from a virtual NVRAM partition. */ #define MC_CMD_NVRAM_READ 0x39 -#define MC_CMD_NVRAM_READ_IN_LEN 12 -#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_READ_OUT_LEN(_read_bytes) (_read_bytes) -#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0 - -/* MC_CMD_NVRAM_WRITE: - * Write data to a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_READ_IN msgrequest */ +#define MC_CMD_NVRAM_READ_IN_LEN 12 +#define MC_CMD_NVRAM_READ_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_READ_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_READ_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_READ_OUT msgresponse */ +#define MC_CMD_NVRAM_READ_OUT_LENMIN 1 +#define MC_CMD_NVRAM_READ_OUT_LENMAX 255 +#define MC_CMD_NVRAM_READ_OUT_LEN(num) (0+1*(num)) +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_OFST 0 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_LEN 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_READ_OUT_READ_BUFFER_MAXNUM 255 + + +/***********************************/ +/* MC_CMD_NVRAM_WRITE + * Write data to a virtual NVRAM partition. */ #define MC_CMD_NVRAM_WRITE 0x3a -#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 -#define MC_CMD_NVRAM_WRITE_IN_LEN(_write_bytes) (12 + _write_bytes) -#define MC_CMD_NVRAM_WRITE_OUT_LEN 0 - -/* MC_CMD_NVRAM_ERASE: - * Erase sector(s) from a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_WRITE_IN msgrequest */ +#define MC_CMD_NVRAM_WRITE_IN_LENMIN 13 +#define MC_CMD_NVRAM_WRITE_IN_LENMAX 255 +#define MC_CMD_NVRAM_WRITE_IN_LEN(num) (12+1*(num)) +#define MC_CMD_NVRAM_WRITE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_WRITE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_WRITE_IN_LENGTH_OFST 8 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_OFST 12 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MINNUM 1 +#define MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM 243 + +/* MC_CMD_NVRAM_WRITE_OUT msgresponse */ +#define MC_CMD_NVRAM_WRITE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_ERASE + * Erase sector(s) from a virtual NVRAM partition. */ #define MC_CMD_NVRAM_ERASE 0x3b -#define MC_CMD_NVRAM_ERASE_IN_LEN 12 -#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 -#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 -#define MC_CMD_NVRAM_ERASE_OUT_LEN 0 - -/* MC_CMD_NVRAM_UPDATE_FINISH: - * Finish a group of update operations on a virtual NVRAM partition - * - * Locks required: PHY_LOCK if type==*PHY* - * Returns: 0, EINVAL (bad type/offset/length), EACCES (if PHY_LOCK required and not held) + +/* MC_CMD_NVRAM_ERASE_IN msgrequest */ +#define MC_CMD_NVRAM_ERASE_IN_LEN 12 +#define MC_CMD_NVRAM_ERASE_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_ERASE_IN_OFFSET_OFST 4 +#define MC_CMD_NVRAM_ERASE_IN_LENGTH_OFST 8 + +/* MC_CMD_NVRAM_ERASE_OUT msgresponse */ +#define MC_CMD_NVRAM_ERASE_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_NVRAM_UPDATE_FINISH + * Finish a group of update operations on a virtual NVRAM partition. */ #define MC_CMD_NVRAM_UPDATE_FINISH 0x3c -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 -#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0 -/* MC_CMD_REBOOT: +/* MC_CMD_NVRAM_UPDATE_FINISH_IN msgrequest */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_LEN 8 +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ +#define MC_CMD_NVRAM_UPDATE_FINISH_IN_REBOOT_OFST 4 + +/* MC_CMD_NVRAM_UPDATE_FINISH_OUT msgresponse */ +#define MC_CMD_NVRAM_UPDATE_FINISH_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_REBOOT * Reboot the MC. - * - * The AFTER_ASSERTION flag is intended to be used when the driver notices - * an assertion failure (at which point it is expected to perform a complete - * tear down and reinitialise), to allow both ports to reset the MC once - * in an atomic fashion. - * - * Production mc firmwares are generally compiled with REBOOT_ON_ASSERT=1, - * which means that they will automatically reboot out of the assertion - * handler, so this is in practise an optional operation. It is still - * recommended that drivers execute this to support custom firmwares - * with REBOOT_ON_ASSERT=0. - * - * Locks required: NONE - * Returns: Nothing. You get back a response with ERR=1, DATALEN=0 */ #define MC_CMD_REBOOT 0x3d -#define MC_CMD_REBOOT_IN_LEN 4 -#define MC_CMD_REBOOT_IN_FLAGS_OFST 0 -#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 1 -#define MC_CMD_REBOOT_OUT_LEN 0 -/* MC_CMD_SCHEDINFO: - * Request scheduler info. from the MC. - * - * Locks required: NONE - * Returns: An array of (timeslice,maximum overrun), one for each thread, - * in ascending order of thread address.s +/* MC_CMD_REBOOT_IN msgrequest */ +#define MC_CMD_REBOOT_IN_LEN 4 +#define MC_CMD_REBOOT_IN_FLAGS_OFST 0 +#define MC_CMD_REBOOT_FLAGS_AFTER_ASSERTION 0x1 /* enum */ + +/* MC_CMD_REBOOT_OUT msgresponse */ +#define MC_CMD_REBOOT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_SCHEDINFO + * Request scheduler info. */ #define MC_CMD_SCHEDINFO 0x3e -#define MC_CMD_SCHEDINFO_IN_LEN 0 +/* MC_CMD_SCHEDINFO_IN msgrequest */ +#define MC_CMD_SCHEDINFO_IN_LEN 0 -/* MC_CMD_SET_REBOOT_MODE: (debug) - * Set the mode for the next MC reboot. - * - * Locks required: NONE - * - * Sets the reboot mode to the specified value. Returns the old mode. +/* MC_CMD_SCHEDINFO_OUT msgresponse */ +#define MC_CMD_SCHEDINFO_OUT_LENMIN 4 +#define MC_CMD_SCHEDINFO_OUT_LENMAX 252 +#define MC_CMD_SCHEDINFO_OUT_LEN(num) (0+4*(num)) +#define MC_CMD_SCHEDINFO_OUT_DATA_OFST 0 +#define MC_CMD_SCHEDINFO_OUT_DATA_LEN 4 +#define MC_CMD_SCHEDINFO_OUT_DATA_MINNUM 1 +#define MC_CMD_SCHEDINFO_OUT_DATA_MAXNUM 63 + + +/***********************************/ +/* MC_CMD_REBOOT_MODE */ #define MC_CMD_REBOOT_MODE 0x3f -#define MC_CMD_REBOOT_MODE_IN_LEN 4 -#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 -#define MC_CMD_REBOOT_MODE_OUT_LEN 4 -#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 -#define MC_CMD_REBOOT_MODE_NORMAL 0 -#define MC_CMD_REBOOT_MODE_SNAPPER 3 - -/* MC_CMD_DEBUG_LOG: - * Null request/response command (debug) - * - sequence number is always zero - * - only supported on the UART interface - * (the same set of bytes is delivered as an - * event over PCI) - */ -#define MC_CMD_DEBUG_LOG 0x40 -#define MC_CMD_DEBUG_LOG_IN_LEN 0 -#define MC_CMD_DEBUG_LOG_OUT_LEN 0 - -/* Generic sensor enumeration. Note that a dual port NIC - * will EITHER expose PHY_COMMON_TEMP OR PHY0_TEMP and - * PHY1_TEMP depending on whether there is a single sensor - * in the vicinity of the two port, or one per port. - */ -#define MC_CMD_SENSOR_CONTROLLER_TEMP 0 /* degC */ -#define MC_CMD_SENSOR_PHY_COMMON_TEMP 1 /* degC */ -#define MC_CMD_SENSOR_CONTROLLER_COOLING 2 /* bool */ -#define MC_CMD_SENSOR_PHY0_TEMP 3 /* degC */ -#define MC_CMD_SENSOR_PHY0_COOLING 4 /* bool */ -#define MC_CMD_SENSOR_PHY1_TEMP 5 /* degC */ -#define MC_CMD_SENSOR_PHY1_COOLING 6 /* bool */ -#define MC_CMD_SENSOR_IN_1V0 7 /* mV */ -#define MC_CMD_SENSOR_IN_1V2 8 /* mV */ -#define MC_CMD_SENSOR_IN_1V8 9 /* mV */ -#define MC_CMD_SENSOR_IN_2V5 10 /* mV */ -#define MC_CMD_SENSOR_IN_3V3 11 /* mV */ -#define MC_CMD_SENSOR_IN_12V0 12 /* mV */ - - -/* Sensor state */ -#define MC_CMD_SENSOR_STATE_OK 0 -#define MC_CMD_SENSOR_STATE_WARNING 1 -#define MC_CMD_SENSOR_STATE_FATAL 2 -#define MC_CMD_SENSOR_STATE_BROKEN 3 - -/* MC_CMD_SENSOR_INFO: + +/* MC_CMD_REBOOT_MODE_IN msgrequest */ +#define MC_CMD_REBOOT_MODE_IN_LEN 4 +#define MC_CMD_REBOOT_MODE_IN_VALUE_OFST 0 +#define MC_CMD_REBOOT_MODE_NORMAL 0x0 /* enum */ +#define MC_CMD_REBOOT_MODE_SNAPPER 0x3 /* enum */ + +/* MC_CMD_REBOOT_MODE_OUT msgresponse */ +#define MC_CMD_REBOOT_MODE_OUT_LEN 4 +#define MC_CMD_REBOOT_MODE_OUT_VALUE_OFST 0 + + +/***********************************/ +/* MC_CMD_SENSOR_INFO * Returns information about every available sensor. - * - * Each sensor has a single (16bit) value, and a corresponding state. - * The mapping between value and sensor is nominally determined by the - * MC, but in practise is implemented as zero (BROKEN), one (TEMPERATURE), - * or two (VOLTAGE) ranges per sensor per state. - * - * This call returns a mask (32bit) of the sensors that are supported - * by this platform, then an array (indexed by MC_CMD_SENSOR) of byte - * offsets to the per-sensor arrays. Each sensor array has four 16bit - * numbers, min1, max1, min2, max2. - * - * Locks required: None - * Returns: 0 */ #define MC_CMD_SENSOR_INFO 0x41 -#define MC_CMD_SENSOR_INFO_IN_LEN 0 -#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 -#define MC_CMD_SENSOR_INFO_OUT_OFFSET_OFST(_x) \ - (4 + (_x)) -#define MC_CMD_SENSOR_INFO_OUT_MIN1_OFST(_ofst) \ - ((_ofst) + 0) -#define MC_CMD_SENSOR_INFO_OUT_MAX1_OFST(_ofst) \ - ((_ofst) + 2) -#define MC_CMD_SENSOR_INFO_OUT_MIN2_OFST(_ofst) \ - ((_ofst) + 4) -#define MC_CMD_SENSOR_INFO_OUT_MAX2_OFST(_ofst) \ - ((_ofst) + 6) +/* MC_CMD_SENSOR_INFO_IN msgrequest */ +#define MC_CMD_SENSOR_INFO_IN_LEN 0 + +/* MC_CMD_SENSOR_INFO_OUT msgresponse */ +#define MC_CMD_SENSOR_INFO_OUT_LENMIN 12 +#define MC_CMD_SENSOR_INFO_OUT_LENMAX 252 +#define MC_CMD_SENSOR_INFO_OUT_LEN(num) (4+8*(num)) +#define MC_CMD_SENSOR_INFO_OUT_MASK_OFST 0 +#define MC_CMD_SENSOR_CONTROLLER_TEMP 0x0 /* enum */ +#define MC_CMD_SENSOR_PHY_COMMON_TEMP 0x1 /* enum */ +#define MC_CMD_SENSOR_CONTROLLER_COOLING 0x2 /* enum */ +#define MC_CMD_SENSOR_PHY0_TEMP 0x3 /* enum */ +#define MC_CMD_SENSOR_PHY0_COOLING 0x4 /* enum */ +#define MC_CMD_SENSOR_PHY1_TEMP 0x5 /* enum */ +#define MC_CMD_SENSOR_PHY1_COOLING 0x6 /* enum */ +#define MC_CMD_SENSOR_IN_1V0 0x7 /* enum */ +#define MC_CMD_SENSOR_IN_1V2 0x8 /* enum */ +#define MC_CMD_SENSOR_IN_1V8 0x9 /* enum */ +#define MC_CMD_SENSOR_IN_2V5 0xa /* enum */ +#define MC_CMD_SENSOR_IN_3V3 0xb /* enum */ +#define MC_CMD_SENSOR_IN_12V0 0xc /* enum */ +#define MC_CMD_SENSOR_IN_1V2A 0xd /* enum */ +#define MC_CMD_SENSOR_IN_VREF 0xe /* enum */ +#define MC_CMD_SENSOR_ENTRY_OFST 4 +#define MC_CMD_SENSOR_ENTRY_LEN 8 +#define MC_CMD_SENSOR_ENTRY_LO_OFST 4 +#define MC_CMD_SENSOR_ENTRY_HI_OFST 8 +#define MC_CMD_SENSOR_ENTRY_MINNUM 1 +#define MC_CMD_SENSOR_ENTRY_MAXNUM 31 + +/* MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_LEN 8 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_OFST 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_LBN 0 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_OFST 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_LBN 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX1_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_OFST 4 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_LBN 32 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MIN2_WIDTH 16 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_OFST 6 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LEN 2 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_LBN 48 +#define MC_CMD_SENSOR_INFO_ENTRY_TYPEDEF_MAX2_WIDTH 16 + + +/***********************************/ /* MC_CMD_READ_SENSORS - * Returns the current reading from each sensor - * - * Returns a sparse array of sensor readings (indexed by the sensor - * type) into host memory. Each array element is a dword. - * - * The MC will send a SENSOREVT event every time any sensor changes state. The - * driver is responsible for ensuring that it doesn't miss any events. The board - * will function normally if all sensors are in STATE_OK or state_WARNING. - * Otherwise the board should not be expected to function. + * Returns the current reading from each sensor. */ #define MC_CMD_READ_SENSORS 0x42 -#define MC_CMD_READ_SENSORS_IN_LEN 8 -#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0 -#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4 -#define MC_CMD_READ_SENSORS_OUT_LEN 0 -/* Sensor reading fields */ -#define MC_CMD_READ_SENSOR_VALUE_LBN 0 -#define MC_CMD_READ_SENSOR_VALUE_WIDTH 16 -#define MC_CMD_READ_SENSOR_STATE_LBN 16 -#define MC_CMD_READ_SENSOR_STATE_WIDTH 8 - - -/* MC_CMD_GET_PHY_STATE: - * Report current state of PHY. A "zombie" PHY is a PHY that has failed to - * boot (e.g. due to missing or corrupted firmware). - * - * Locks required: None - * Return code: 0 +/* MC_CMD_READ_SENSORS_IN msgrequest */ +#define MC_CMD_READ_SENSORS_IN_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LEN 8 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_LO_OFST 0 +#define MC_CMD_READ_SENSORS_IN_DMA_ADDR_HI_OFST 4 + +/* MC_CMD_READ_SENSORS_OUT msgresponse */ +#define MC_CMD_READ_SENSORS_OUT_LEN 0 + +/* MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF structuredef */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_LEN 3 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_OFST 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LEN 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_LBN 0 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE_WIDTH 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_OFST 2 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LEN 1 +#define MC_CMD_SENSOR_STATE_OK 0x0 /* enum */ +#define MC_CMD_SENSOR_STATE_WARNING 0x1 /* enum */ +#define MC_CMD_SENSOR_STATE_FATAL 0x2 /* enum */ +#define MC_CMD_SENSOR_STATE_BROKEN 0x3 /* enum */ +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_LBN 16 +#define MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE_WIDTH 8 + + +/***********************************/ +/* MC_CMD_GET_PHY_STATE + * Report current state of PHY. */ #define MC_CMD_GET_PHY_STATE 0x43 -#define MC_CMD_GET_PHY_STATE_IN_LEN 0 -#define MC_CMD_GET_PHY_STATE_OUT_LEN 4 -#define MC_CMD_GET_PHY_STATE_STATE_OFST 0 -/* PHY state enumeration: */ -#define MC_CMD_PHY_STATE_OK 1 -#define MC_CMD_PHY_STATE_ZOMBIE 2 +/* MC_CMD_GET_PHY_STATE_IN msgrequest */ +#define MC_CMD_GET_PHY_STATE_IN_LEN 0 +/* MC_CMD_GET_PHY_STATE_OUT msgresponse */ +#define MC_CMD_GET_PHY_STATE_OUT_LEN 4 +#define MC_CMD_GET_PHY_STATE_OUT_STATE_OFST 0 +#define MC_CMD_PHY_STATE_OK 0x1 /* enum */ +#define MC_CMD_PHY_STATE_ZOMBIE 0x2 /* enum */ -/* 802.1Qbb control. 8 Tx queues that map to priorities 0 - 7. Use all 1s to - * disable 802.Qbb for a given priority. */ + +/***********************************/ +/* MC_CMD_SETUP_8021QBB + * 802.1Qbb control. + */ #define MC_CMD_SETUP_8021QBB 0x44 -#define MC_CMD_SETUP_8021QBB_IN_LEN 32 -#define MC_CMD_SETUP_8021QBB_OUT_LEN 0 -#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFFST 0 +/* MC_CMD_SETUP_8021QBB_IN msgrequest */ +#define MC_CMD_SETUP_8021QBB_IN_LEN 32 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_OFST 0 +#define MC_CMD_SETUP_8021QBB_IN_TXQS_LEN 32 -/* MC_CMD_WOL_FILTER_GET: - * Retrieve ID of any WoL filters - * - * Locks required: None - * Returns: 0, ENOSYS - */ -#define MC_CMD_WOL_FILTER_GET 0x45 -#define MC_CMD_WOL_FILTER_GET_IN_LEN 0 -#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 -#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 +/* MC_CMD_SETUP_8021QBB_OUT msgresponse */ +#define MC_CMD_SETUP_8021QBB_OUT_LEN 0 -/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD: - * Offload a protocol to NIC for lights-out state - * - * Locks required: None - * Returns: 0, ENOSYS +/***********************************/ +/* MC_CMD_WOL_FILTER_GET + * Retrieve ID of any WoL filters. */ -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46 +#define MC_CMD_WOL_FILTER_GET 0x45 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN 16 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +/* MC_CMD_WOL_FILTER_GET_IN msgrequest */ +#define MC_CMD_WOL_FILTER_GET_IN_LEN 0 -/* There is a union at offset 4, following defines overlap due to - * this */ -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPMAC_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARPIP_OFST 10 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSMAC_OFST 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSSNIPV6_OFST 10 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NSIPV6_OFST 26 +/* MC_CMD_WOL_FILTER_GET_OUT msgresponse */ +#define MC_CMD_WOL_FILTER_GET_OUT_LEN 4 +#define MC_CMD_WOL_FILTER_GET_OUT_FILTER_ID_OFST 0 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 -#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 +/***********************************/ +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD + * Add a protocol offload to NIC for lights-out state. + */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD 0x46 -/* MC_CMD_REMOVE_LIGHTSOUT_PROTOCOL_OFFLOAD: - * Offload a protocol to NIC for lights-out state - * - * Locks required: None - * Returns: 0, ENOSYS +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMIN 8 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LENMAX 252 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_LEN(num) (4+4*(num)) +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 /* enum */ +#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 /* enum */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MINNUM 1 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_DATA_MAXNUM 62 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_LEN 14 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_ARP_IP_OFST 10 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS msgrequest */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_LEN 42 +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_OFST 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_MAC_LEN 6 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_OFST 10 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_SNIPV6_LEN 16 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_OFST 26 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_IN_NS_IPV6_LEN 16 + +/* MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_LEN 4 +#define MC_CMD_ADD_LIGHTSOUT_OFFLOAD_OUT_FILTER_ID_OFST 0 + + +/***********************************/ +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD + * Remove a protocol offload from NIC for lights-out state. */ #define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD 0x47 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 -#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN msgrequest */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_LEN 8 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_PROTOCOL_OFST 0 +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_IN_FILTER_ID_OFST 4 -/* Lights-out offload protocols enumeration */ -#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_ARP 0x1 -#define MC_CMD_LIGHTSOUT_OFFLOAD_PROTOCOL_NS 0x2 +/* MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT msgresponse */ +#define MC_CMD_REMOVE_LIGHTSOUT_OFFLOAD_OUT_LEN 0 -/* MC_CMD_MAC_RESET_RESTORE: - * Restore MAC after block reset - * - * Locks required: None - * Returns: 0 +/***********************************/ +/* MC_CMD_MAC_RESET_RESTORE + * Restore MAC after block reset. */ - #define MC_CMD_MAC_RESET_RESTORE 0x48 -#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0 -#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0 +/* MC_CMD_MAC_RESET_RESTORE_IN msgrequest */ +#define MC_CMD_MAC_RESET_RESTORE_IN_LEN 0 + +/* MC_CMD_MAC_RESET_RESTORE_OUT msgresponse */ +#define MC_CMD_MAC_RESET_RESTORE_OUT_LEN 0 -/* MC_CMD_TEST_ASSERT: - * Deliberately trigger an assert-detonation in the firmware for testing - * purposes (i.e. to allow tests that the driver copes gracefully). - * - * Locks required: None - * Returns: 0 - */ +/***********************************/ +/* MC_CMD_TESTASSERT + */ #define MC_CMD_TESTASSERT 0x49 -#define MC_CMD_TESTASSERT_IN_LEN 0 -#define MC_CMD_TESTASSERT_OUT_LEN 0 -/* MC_CMD_WORKAROUND 0x4a - * - * Enable/Disable a given workaround. The mcfw will return EINVAL if it - * doesn't understand the given workaround number - which should not - * be treated as a hard error by client code. - * - * This op does not imply any semantics about each workaround, that's between - * the driver and the mcfw on a per-workaround basis. - * - * Locks required: None - * Returns: 0, EINVAL +/* MC_CMD_TESTASSERT_IN msgrequest */ +#define MC_CMD_TESTASSERT_IN_LEN 0 + +/* MC_CMD_TESTASSERT_OUT msgresponse */ +#define MC_CMD_TESTASSERT_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_WORKAROUND + * Enable/Disable a given workaround. */ #define MC_CMD_WORKAROUND 0x4a -#define MC_CMD_WORKAROUND_IN_LEN 8 -#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 -#define MC_CMD_WORKAROUND_BUG17230 1 -#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 -#define MC_CMD_WORKAROUND_OUT_LEN 0 - -/* MC_CMD_GET_PHY_MEDIA_INFO: - * Read media-specific data from PHY (e.g. SFP/SFP+ module ID information for - * SFP+ PHYs). - * - * The "media type" can be found via GET_PHY_CFG (GET_PHY_CFG_OUT_MEDIA_TYPE); - * the valid "page number" input values, and the output data, are interpreted - * on a per-type basis. - * - * For SFP+: PAGE=0 or 1 returns a 128-byte block read from module I2C address - * 0xA0 offset 0 or 0x80. - * Anything else: currently undefined. - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_WORKAROUND_IN msgrequest */ +#define MC_CMD_WORKAROUND_IN_LEN 8 +#define MC_CMD_WORKAROUND_IN_TYPE_OFST 0 +#define MC_CMD_WORKAROUND_BUG17230 0x1 /* enum */ +#define MC_CMD_WORKAROUND_IN_ENABLED_OFST 4 + +/* MC_CMD_WORKAROUND_OUT msgresponse */ +#define MC_CMD_WORKAROUND_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_PHY_MEDIA_INFO + * Read media-specific data from PHY. */ #define MC_CMD_GET_PHY_MEDIA_INFO 0x4b -#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 -#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(_num_bytes) (4 + (_num_bytes)) -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 -#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 - -/* MC_CMD_NVRAM_TEST: - * Test a particular NVRAM partition for valid contents (where "valid" - * depends on the type of partition). - * - * Locks required: None - * Return code: 0 + +/* MC_CMD_GET_PHY_MEDIA_INFO_IN msgrequest */ +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_LEN 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_IN_PAGE_OFST 0 + +/* MC_CMD_GET_PHY_MEDIA_INFO_OUT msgresponse */ +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMIN 5 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LENMAX 255 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_LEN(num) (4+1*(num)) +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATALEN_OFST 0 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_OFST 4 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_LEN 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MINNUM 1 +#define MC_CMD_GET_PHY_MEDIA_INFO_OUT_DATA_MAXNUM 251 + + +/***********************************/ +/* MC_CMD_NVRAM_TEST + * Test a particular NVRAM partition. */ #define MC_CMD_NVRAM_TEST 0x4c -#define MC_CMD_NVRAM_TEST_IN_LEN 4 -#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 -#define MC_CMD_NVRAM_TEST_OUT_LEN 4 -#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 -#define MC_CMD_NVRAM_TEST_PASS 0 -#define MC_CMD_NVRAM_TEST_FAIL 1 -#define MC_CMD_NVRAM_TEST_NOTSUPP 2 - -/* MC_CMD_MRSFP_TWEAK: (debug) - * Read status and/or set parameters for the "mrsfp" driver in mr_rusty builds. - * I2C I/O expander bits are always read; if equaliser parameters are supplied, - * they are configured first. - * - * Locks required: None - * Return code: 0, EINVAL + +/* MC_CMD_NVRAM_TEST_IN msgrequest */ +#define MC_CMD_NVRAM_TEST_IN_LEN 4 +#define MC_CMD_NVRAM_TEST_IN_TYPE_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_NVRAM_TYPES/MC_CMD_NVRAM_TYPES_OUT/TYPES */ + +/* MC_CMD_NVRAM_TEST_OUT msgresponse */ +#define MC_CMD_NVRAM_TEST_OUT_LEN 4 +#define MC_CMD_NVRAM_TEST_OUT_RESULT_OFST 0 +#define MC_CMD_NVRAM_TEST_PASS 0x0 /* enum */ +#define MC_CMD_NVRAM_TEST_FAIL 0x1 /* enum */ +#define MC_CMD_NVRAM_TEST_NOTSUPP 0x2 /* enum */ + + +/***********************************/ +/* MC_CMD_MRSFP_TWEAK + * Read status and/or set parameters for the 'mrsfp' driver. */ #define MC_CMD_MRSFP_TWEAK 0x4d -#define MC_CMD_MRSFP_TWEAK_IN_LEN_READ_ONLY 0 -#define MC_CMD_MRSFP_TWEAK_IN_LEN_EQ_CONFIG 16 -#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_LEVEL_OFST 0 /* 0-6 low->high de-emph. */ -#define MC_CMD_MRSFP_TWEAK_IN_TXEQ_DT_CFG_OFST 4 /* 0-8 low->high ref.V */ -#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_BOOST_OFST 8 /* 0-8 low->high boost */ -#define MC_CMD_MRSFP_TWEAK_IN_RXEQ_DT_CFG_OFST 12 /* 0-8 low->high ref.V */ -#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 /* input bits */ -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 /* output bits */ -#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 /* dirs: 0=out, 1=in */ - -/* MC_CMD_TEST_HACK: (debug (unsurprisingly)) - * Change bits of network port state for test purposes in ways that would never be - * useful in normal operation and so need a special command to change. */ -#define MC_CMD_TEST_HACK 0x2f -#define MC_CMD_TEST_HACK_IN_LEN 8 -#define MC_CMD_TEST_HACK_IN_TXPAD_OFST 0 -#define MC_CMD_TEST_HACK_IN_TXPAD_AUTO 0 /* Let the MC manage things */ -#define MC_CMD_TEST_HACK_IN_TXPAD_ON 1 /* Force on */ -#define MC_CMD_TEST_HACK_IN_TXPAD_OFF 2 /* Force on */ -#define MC_CMD_TEST_HACK_IN_IPG_OFST 4 /* Takes a value in bits */ -#define MC_CMD_TEST_HACK_IN_IPG_AUTO 0 /* The MC picks the value */ -#define MC_CMD_TEST_HACK_OUT_LEN 0 - -/* MC_CMD_SENSOR_SET_LIMS: (debug) (mostly) adjust the sensor limits. This - * is a warranty-voiding operation. - * - * IN: sensor identifier (one of the enumeration starting with MC_CMD_SENSOR_CONTROLLER_TEMP - * followed by 4 32-bit values: min(warning) max(warning), min(fatal), max(fatal). Which - * of these limits are meaningful and what their interpretation is is sensor-specific. - * - * OUT: nothing - * - * Returns: ENOENT if the sensor specified does not exist, EINVAL if the limits are - * out of range. + +/* MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_LEN 16 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_LEVEL_OFST 0 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_TXEQ_DT_CFG_OFST 4 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_BOOST_OFST 8 +#define MC_CMD_MRSFP_TWEAK_IN_EQ_CONFIG_RXEQ_DT_CFG_OFST 12 + +/* MC_CMD_MRSFP_TWEAK_IN_READ_ONLY msgrequest */ +#define MC_CMD_MRSFP_TWEAK_IN_READ_ONLY_LEN 0 + +/* MC_CMD_MRSFP_TWEAK_OUT msgresponse */ +#define MC_CMD_MRSFP_TWEAK_OUT_LEN 12 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_INPUTS_OFST 0 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_OUTPUTS_OFST 4 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OFST 8 +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_OUT 0x0 /* enum */ +#define MC_CMD_MRSFP_TWEAK_OUT_IOEXP_DIRECTION_IN 0x1 /* enum */ + + +/***********************************/ +/* MC_CMD_SENSOR_SET_LIMS + * Adjusts the sensor limits. */ #define MC_CMD_SENSOR_SET_LIMS 0x4e -#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 -#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 -#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 -#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 -#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 -#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 - -/* Do NOT add new commands beyond 0x4f as part of 3.0 : 0x50 - 0x7f will be - * used for post-3.0 extensions. If you run out of space, look for gaps or - * commands that are unused in the existing range. */ + +/* MC_CMD_SENSOR_SET_LIMS_IN msgrequest */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LEN 20 +#define MC_CMD_SENSOR_SET_LIMS_IN_SENSOR_OFST 0 +/* Enum values, see field(s): */ +/* MC_CMD_SENSOR_INFO/MC_CMD_SENSOR_INFO_OUT/MASK */ +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW0_OFST 4 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI0_OFST 8 +#define MC_CMD_SENSOR_SET_LIMS_IN_LOW1_OFST 12 +#define MC_CMD_SENSOR_SET_LIMS_IN_HI1_OFST 16 + +/* MC_CMD_SENSOR_SET_LIMS_OUT msgresponse */ +#define MC_CMD_SENSOR_SET_LIMS_OUT_LEN 0 + + +/***********************************/ +/* MC_CMD_GET_RESOURCE_LIMITS + */ +#define MC_CMD_GET_RESOURCE_LIMITS 0x4f + +/* MC_CMD_GET_RESOURCE_LIMITS_IN msgrequest */ +#define MC_CMD_GET_RESOURCE_LIMITS_IN_LEN 0 + +/* MC_CMD_GET_RESOURCE_LIMITS_OUT msgresponse */ +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_LEN 16 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_BUFTBL_OFST 0 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_EVQ_OFST 4 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_RXQ_OFST 8 +#define MC_CMD_GET_RESOURCE_LIMITS_OUT_TXQ_OFST 12 + +/* MC_CMD_RESOURCE_SPECIFIER enum */ +#define MC_CMD_RESOURCE_INSTANCE_ANY 0xffffffff /* enum */ +#define MC_CMD_RESOURCE_INSTANCE_NONE 0xfffffffe /* enum */ + #endif /* MCDI_PCOL_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_phy.c b/drivers/net/ethernet/sfc/mcdi_phy.c index 3077bf1e7df..7bcad899a93 100644 --- a/drivers/net/ethernet/sfc/mcdi_phy.c +++ b/drivers/net/ethernet/sfc/mcdi_phy.c @@ -116,7 +116,7 @@ static int efx_mcdi_loopback_modes(struct efx_nic *efx, u64 *loopback_modes) goto fail; } - *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_SUGGESTED); + *loopback_modes = MCDI_QWORD(outbuf, GET_LOOPBACK_MODES_OUT_SUGGESTED); return 0; @@ -264,22 +264,22 @@ static u32 efx_get_mcdi_phy_flags(struct efx_nic *efx) /* TODO: Advertise the capabilities supported by this PHY */ supported = 0; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_TXDIS_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_TXDIS_LBN)) supported |= PHY_MODE_TX_DISABLED; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_LOWPOWER_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_LOWPOWER_LBN)) supported |= PHY_MODE_LOW_POWER; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_POWEROFF_LBN)) + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_POWEROFF_LBN)) supported |= PHY_MODE_OFF; mode = efx->phy_mode & supported; flags = 0; if (mode & PHY_MODE_TX_DISABLED) - flags |= (1 << MC_CMD_SET_LINK_TXDIS_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_TXDIS_LBN); if (mode & PHY_MODE_LOW_POWER) - flags |= (1 << MC_CMD_SET_LINK_LOWPOWER_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_LOWPOWER_LBN); if (mode & PHY_MODE_OFF) - flags |= (1 << MC_CMD_SET_LINK_POWEROFF_LBN); + flags |= (1 << MC_CMD_SET_LINK_IN_POWEROFF_LBN); return flags; } @@ -436,8 +436,8 @@ void efx_mcdi_phy_decode_link(struct efx_nic *efx, break; } - link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_LINK_UP_LBN)); - link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_FULL_DUPLEX_LBN)); + link_state->up = !!(flags & (1 << MC_CMD_GET_LINK_OUT_LINK_UP_LBN)); + link_state->fd = !!(flags & (1 << MC_CMD_GET_LINK_OUT_FULL_DUPLEX_LBN)); link_state->speed = speed; } @@ -592,7 +592,7 @@ static int efx_mcdi_phy_test_alive(struct efx_nic *efx) if (outlen < MC_CMD_GET_PHY_STATE_OUT_LEN) return -EIO; - if (MCDI_DWORD(outbuf, GET_PHY_STATE_STATE) != MC_CMD_PHY_STATE_OK) + if (MCDI_DWORD(outbuf, GET_PHY_STATE_OUT_STATE) != MC_CMD_PHY_STATE_OK) return -EINVAL; return 0; @@ -680,7 +680,7 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, u32 mode; int rc; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) { rc = efx_mcdi_bist(efx, MC_CMD_PHY_BIST, results); if (rc < 0) return rc; @@ -691,15 +691,15 @@ static int efx_mcdi_phy_run_tests(struct efx_nic *efx, int *results, /* If we support both LONG and SHORT, then run each in response to * break or not. Otherwise, run the one we support */ mode = 0; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN)) { if ((flags & ETH_TEST_FL_OFFLINE) && (phy_cfg->flags & - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))) + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) mode = MC_CMD_PHY_BIST_CABLE_LONG; else mode = MC_CMD_PHY_BIST_CABLE_SHORT; } else if (phy_cfg->flags & - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN)) + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN)) mode = MC_CMD_PHY_BIST_CABLE_LONG; if (mode != 0) { @@ -717,14 +717,14 @@ static const char *efx_mcdi_phy_test_name(struct efx_nic *efx, { struct efx_mcdi_phy_data *phy_cfg = efx->phy_data; - if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_BIST_LBN)) { + if (phy_cfg->flags & (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_LBN)) { if (index == 0) return "bist"; --index; } - if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_SHORT_LBN) | - (1 << MC_CMD_GET_PHY_CFG_BIST_CABLE_LONG_LBN))) { + if (phy_cfg->flags & ((1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_SHORT_LBN) | + (1 << MC_CMD_GET_PHY_CFG_OUT_BIST_CABLE_LONG_LBN))) { if (index == 0) return "cable"; --index; diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index 13f61fba731..7f61cd3812d 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -627,8 +627,7 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx, struct efx_mtd *efx_mtd) { struct efx_mtd_partition *part; - uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN / - sizeof(uint16_t)]; + uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM]; int rc; rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list); -- cgit v1.2.3-70-g09d2 From fa142b9da3393fd92b398b6bdecf3f21914e309b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:15:30 +0000 Subject: sfc: Rename efx_wanted_channels() to efx_wanted_parallelism() This function returns the degree of parallelism wanted, which is not necessarily the total number of channels we want to create. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 9ca5dcdf5a8..5fcc42f7d86 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1146,9 +1146,7 @@ static void efx_fini_io(struct efx_nic *efx) pci_disable_device(efx->pci_dev); } -/* Get number of channels wanted. Each channel will have its own IRQ, - * 1 RX queue and/or 2 TX queues. */ -static int efx_wanted_channels(void) +static int efx_wanted_parallelism(void) { cpumask_var_t core_mask; int count; @@ -1211,7 +1209,7 @@ static int efx_probe_interrupts(struct efx_nic *efx) struct msix_entry xentries[EFX_MAX_CHANNELS]; int n_channels; - n_channels = efx_wanted_channels(); + n_channels = efx_wanted_parallelism(); if (separate_tx_channels) n_channels *= 2; n_channels = min(n_channels, max_channels); -- cgit v1.2.3-70-g09d2 From cdb08f8fd8642a6d661c920f565e85cf87a0c9be Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:08:05 +0000 Subject: sfc: Set default parallelism to per-core by default The previous default of per-package can be more CPU-efficient, but users generally seem to prefer per-core. It should also allow accelerated RFS to direct packets more precisely, if IRQ affinity is properly spread out. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 5fcc42f7d86..d7301d2e81a 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -162,7 +162,7 @@ static unsigned int interrupt_mode; * interrupt handling. * * Cards without MSI-X will only target one CPU via legacy or MSI interrupt. - * The default (0) means to assign an interrupt to each package (level II cache) + * The default (0) means to assign an interrupt to each core. */ static unsigned int rss_cpus; module_param(rss_cpus, uint, 0444); @@ -1148,14 +1148,14 @@ static void efx_fini_io(struct efx_nic *efx) static int efx_wanted_parallelism(void) { - cpumask_var_t core_mask; + cpumask_var_t thread_mask; int count; int cpu; if (rss_cpus) return rss_cpus; - if (unlikely(!zalloc_cpumask_var(&core_mask, GFP_KERNEL))) { + if (unlikely(!zalloc_cpumask_var(&thread_mask, GFP_KERNEL))) { printk(KERN_WARNING "sfc: RSS disabled due to allocation failure\n"); return 1; @@ -1163,14 +1163,14 @@ static int efx_wanted_parallelism(void) count = 0; for_each_online_cpu(cpu) { - if (!cpumask_test_cpu(cpu, core_mask)) { + if (!cpumask_test_cpu(cpu, thread_mask)) { ++count; - cpumask_or(core_mask, core_mask, - topology_core_cpumask(cpu)); + cpumask_or(thread_mask, thread_mask, + topology_thread_cpumask(cpu)); } } - free_cpumask_var(core_mask); + free_cpumask_var(thread_mask); return count; } -- cgit v1.2.3-70-g09d2 From 866dc88607aa07f297eec7b504be58ca17d91a26 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:23 +0530 Subject: ath6kl: Fix SDIO error path sdio_release_host() would be called twice if sdio_set_block_size() fails for some reason, which would result in the following warning. WARNING: at /home/sujith/dev/wireless-testing/drivers/mmc/core/core.c:828 mmc_release_host+0x42/0x50 [mmc_core]() Call Trace: [] warn_slowpath_common+0x7f/0xc0 [] warn_slowpath_null+0x1a/0x20 [] mmc_release_host+0x42/0x50 [mmc_core] [] sdio_release_host+0x1e/0x30 [mmc_core] [] ath6kl_sdio_config+0xc7/0x110 [ath6kl_sdio] [] ath6kl_sdio_probe+0x21c/0x320 [ath6kl_sdio] [] ? mmc_release_host+0x2a/0x50 [mmc_core] [] sdio_bus_probe+0xfa/0x130 [mmc_core] [] driver_probe_device+0x7e/0x1b0 [] __driver_attach+0xab/0xb0 [] ? driver_probe_device+0x1b0/0x1b0 [] ? driver_probe_device+0x1b0/0x1b0 [] bus_for_each_dev+0x64/0xa0 [] driver_attach+0x1e/0x20 [] bus_add_driver+0x1b0/0x280 [] ? 0xffffffffa0064fff [] driver_register+0x76/0x140 [] ? 0xffffffffa0064fff [] sdio_register_driver+0x21/0x30 [mmc_core] [] ath6kl_sdio_init+0x12/0x35 [ath6kl_sdio] [] do_one_initcall+0x42/0x180 [] sys_init_module+0x8f/0x200 [] system_call_fastpath+0x16/0x1b Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 8b36904ec3e..50b19d3aefa 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -770,7 +770,6 @@ static int ath6kl_sdio_config(struct ath6kl *ar) if (ret) { ath6kl_err("Set sdio block size %d failed: %d)\n", HIF_MBOX_BLOCK_SIZE, ret); - sdio_release_host(func); goto out; } -- cgit v1.2.3-70-g09d2 From 4a8ce2fd055f8c117fb6fa6da39af8f62cbffe4b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:38 +0530 Subject: ath6kl: Remove redundant pointer check 'params' is already used earlier and there is no point in checking for a NULL condition again. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 14f180eac48..9b26bbaf124 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -983,6 +983,7 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, struct ath6kl *ar = ath6kl_priv(ndev); struct ath6kl_vif *vif = netdev_priv(ndev); struct ath6kl_key *key = NULL; + int seq_len; u8 key_usage; u8 key_type; @@ -1011,23 +1012,21 @@ static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, else key_usage = GROUP_USAGE; - if (params) { - int seq_len = params->seq_len; - if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && - seq_len > ATH6KL_KEY_SEQ_LEN) { - /* Only first half of the WPI PN is configured */ - seq_len = ATH6KL_KEY_SEQ_LEN; - } - if (params->key_len > WLAN_MAX_KEY_LEN || - seq_len > sizeof(key->seq)) - return -EINVAL; - - key->key_len = params->key_len; - memcpy(key->key, params->key, key->key_len); - key->seq_len = seq_len; - memcpy(key->seq, params->seq, key->seq_len); - key->cipher = params->cipher; + seq_len = params->seq_len; + if (params->cipher == WLAN_CIPHER_SUITE_SMS4 && + seq_len > ATH6KL_KEY_SEQ_LEN) { + /* Only first half of the WPI PN is configured */ + seq_len = ATH6KL_KEY_SEQ_LEN; } + if (params->key_len > WLAN_MAX_KEY_LEN || + seq_len > sizeof(key->seq)) + return -EINVAL; + + key->key_len = params->key_len; + memcpy(key->key, params->key, key->key_len); + key->seq_len = seq_len; + memcpy(key->seq, params->seq, key->seq_len); + key->cipher = params->cipher; switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: -- cgit v1.2.3-70-g09d2 From cbec267a5143f70ece4069d18889a442bcb3365b Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:53:53 +0530 Subject: ath6kl: Initialize a variable properly This prevents 'comp_pktq' from being used in an incorrect manner. Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/htc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index b01702258fa..2d721903640 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2062,6 +2062,7 @@ int ath6kl_htc_rxmsg_pending_handler(struct htc_target *target, enum htc_endpoint_id id; int n_fetched = 0; + INIT_LIST_HEAD(&comp_pktq); *num_pkts = 0; /* -- cgit v1.2.3-70-g09d2 From 8232736dabd2a0310f76944fa7af0542fe3ded4f Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Tue, 10 Jan 2012 09:54:10 +0530 Subject: ath6kl: Fix listen interval handling This patch addresses a few problems with the commit: "ath6kl: Implement support for listen interval from userspace" * The debugfs file required for reading/writing the listen interval wasn't created. Fix this. * The interface index was being hardcoded to zero. Fix this. * Two separate parameters, "listen_interval_time and listen_interval_beacons" were being used. This fails to work as expected because the FW assigns higher precedence to "listen_interval_beacons" and "listen_interval_time" ends up being never used at all. To handle this, fix the host driver to exclusively use listen interval based on units of beacon intervals. To set the listen interval, a user would now do something like this: echo "10" > /sys/kernel/debug/ieee80211/*/ath6kl/listen_interval kvalo: fix two checkpatch warnings Signed-off-by: Sujith Manoharan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +- drivers/net/wireless/ath/ath6kl/core.h | 3 +- drivers/net/wireless/ath/ath6kl/debug.c | 44 ++++++++++++------------------ drivers/net/wireless/ath/ath6kl/main.c | 7 +++-- 4 files changed, 24 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 9b26bbaf124..1a98c9256c6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2725,8 +2725,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) clear_bit(SKIP_SCAN, &ar->flag); clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL; - ar->listen_intvl_b = 0; + ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; ar->tx_pwr = 0; ar->intra_bss = 1; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 793c6a58f0f..f4da5e19a36 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -55,7 +55,7 @@ #define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) #define DISCON_TIMER_INTVAL 10000 /* in msec */ -#define A_DEFAULT_LISTEN_INTERVAL 100 +#define A_DEFAULT_LISTEN_INTERVAL 1 /* beacon intervals */ #define A_MAX_WOW_LISTEN_INTERVAL 1000 /* includes also the null byte */ @@ -534,7 +534,6 @@ struct ath6kl { spinlock_t lock; struct semaphore sem; u16 listen_intvl_b; - u16 listen_intvl_t; u8 lrssi_roam_threshold; struct ath6kl_version version; u32 target_type; diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index eb808b46f94..fa7243b4144 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1505,57 +1505,46 @@ static const struct file_operations fops_bgscan_int = { }; static ssize_t ath6kl_listen_int_write(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) + const char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; - u16 listen_int_t, listen_int_b; + struct ath6kl_vif *vif; + u16 listen_interval; char buf[32]; - char *sptr, *token; ssize_t len; + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + len = min(count, sizeof(buf) - 1); if (copy_from_user(buf, user_buf, len)) return -EFAULT; buf[len] = '\0'; - sptr = buf; - - token = strsep(&sptr, " "); - if (!token) - return -EINVAL; - - if (kstrtou16(token, 0, &listen_int_t)) - return -EINVAL; - - if (kstrtou16(sptr, 0, &listen_int_b)) - return -EINVAL; - - if ((listen_int_t < 15) || (listen_int_t > 5000)) + if (kstrtou16(buf, 0, &listen_interval)) return -EINVAL; - if ((listen_int_b < 1) || (listen_int_b > 50)) + if ((listen_interval < 1) || (listen_interval > 50)) return -EINVAL; - ar->listen_intvl_t = listen_int_t; - ar->listen_intvl_b = listen_int_b; - - ath6kl_wmi_listeninterval_cmd(ar->wmi, 0, ar->listen_intvl_t, + ar->listen_intvl_b = listen_interval; + ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, 0, ar->listen_intvl_b); return count; } static ssize_t ath6kl_listen_int_read(struct file *file, - char __user *user_buf, - size_t count, loff_t *ppos) + char __user *user_buf, + size_t count, loff_t *ppos) { struct ath6kl *ar = file->private_data; char buf[32]; int len; - len = scnprintf(buf, sizeof(buf), "%u %u\n", ar->listen_intvl_t, - ar->listen_intvl_b); + len = scnprintf(buf, sizeof(buf), "%u\n", ar->listen_intvl_b); return simple_read_from_buffer(user_buf, count, ppos, buf, len); } @@ -1710,6 +1699,9 @@ int ath6kl_debug_init(struct ath6kl *ar) debugfs_create_file("bgscan_interval", S_IWUSR, ar->debugfs_phy, ar, &fops_bgscan_int); + debugfs_create_file("listen_interval", S_IRUSR | S_IWUSR, + ar->debugfs_phy, ar, &fops_listen_int); + debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar, &fops_power_params); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 8742eaa7818..4c26572214c 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -584,10 +584,11 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, memcpy(vif->bssid, bssid, sizeof(vif->bssid)); vif->bss_ch = channel; - if ((vif->nw_type == INFRA_NETWORK)) + if ((vif->nw_type == INFRA_NETWORK)) { + ar->listen_intvl_b = listen_int; ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx, - ar->listen_intvl_t, - ar->listen_intvl_b); + 0, ar->listen_intvl_b); + } netif_wake_queue(vif->ndev); -- cgit v1.2.3-70-g09d2 From a96d627abaac899e8bfaf18fd0578b228c9c752f Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 4 Jan 2012 14:23:56 -0500 Subject: pci: Introduce __pci_reset_function_locked to be used when holding device_lock. The use case of this is when a driver wants to call FLR when a device is attached to it using the SysFS "bind" or "unbind" functionality. The call chain when a user does "bind" looks as so: echo "0000:01.07.0" > /sys/bus/pci/drivers/XXXX/bind and ends up calling: driver_bind: device_lock(dev); <=== TAKES LOCK XXXX_probe: .. pci_enable_device() ...__pci_reset_function(), which calls pci_dev_reset(dev, 0): if (!0) { device_lock(dev) <==== DEADLOCK The __pci_reset_function_locked function allows the the drivers 'probe' function to call the "pci_reset_function" while still holding the driver mutex lock. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/pci/pci.c | 25 +++++++++++++++++++++++++ include/linux/pci.h | 1 + 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 97fff785e97..192be5dbde5 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -3162,6 +3162,31 @@ int __pci_reset_function(struct pci_dev *dev) } EXPORT_SYMBOL_GPL(__pci_reset_function); +/** + * __pci_reset_function_locked - reset a PCI device function while holding + * the @dev mutex lock. + * @dev: PCI device to reset + * + * Some devices allow an individual function to be reset without affecting + * other functions in the same device. The PCI device must be responsive + * to PCI config space in order to use this function. + * + * The device function is presumed to be unused and the caller is holding + * the device mutex lock when this function is called. + * Resetting the device will make the contents of PCI configuration space + * random, so any caller of this must be prepared to reinitialise the + * device including MSI, bus mastering, BARs, decoding IO and memory spaces, + * etc. + * + * Returns 0 if the device function was successfully reset or negative if the + * device doesn't support resetting a single function. + */ +int __pci_reset_function_locked(struct pci_dev *dev) +{ + return pci_dev_reset(dev, 1); +} +EXPORT_SYMBOL_GPL(__pci_reset_function_locked); + /** * pci_probe_reset_function - check whether the device can be safely reset * @dev: PCI device to reset diff --git a/include/linux/pci.h b/include/linux/pci.h index a16b1df3def..65c2d8a32b2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -817,6 +817,7 @@ int pcie_set_readrq(struct pci_dev *dev, int rq); int pcie_get_mps(struct pci_dev *dev); int pcie_set_mps(struct pci_dev *dev, int mps); int __pci_reset_function(struct pci_dev *dev); +int __pci_reset_function_locked(struct pci_dev *dev); int pci_reset_function(struct pci_dev *dev); void pci_update_resource(struct pci_dev *dev, int resno); int __must_check pci_assign_resource(struct pci_dev *dev, int i); -- cgit v1.2.3-70-g09d2 From cd9db80e5257682a7f7ab245a2459648b3c8d268 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 4 Jan 2012 14:30:58 -0500 Subject: xen/pciback: Support pci_reset_function, aka FLR or D3 support. We use the __pci_reset_function_locked to perform the action. Also on attaching ("bind") and detaching ("unbind") we save and restore the configuration states. When the device is disconnected from a guest we use the "pci_reset_function" to also reset the device before being passed to another guest. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xen-pciback/pci_stub.c | 41 +++++++++++++++++++++++++++++++++++--- drivers/xen/xen-pciback/pciback.h | 1 + 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 7944a17f5cb..6f63b9d954f 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -85,19 +85,34 @@ static struct pcistub_device *pcistub_device_alloc(struct pci_dev *dev) static void pcistub_device_release(struct kref *kref) { struct pcistub_device *psdev; + struct xen_pcibk_dev_data *dev_data; psdev = container_of(kref, struct pcistub_device, kref); + dev_data = pci_get_drvdata(psdev->dev); dev_dbg(&psdev->dev->dev, "pcistub_device_release\n"); xen_unregister_device_domain_owner(psdev->dev); - /* Clean-up the device */ + /* Call the reset function which does not take lock as this + * is called from "unbind" which takes a device_lock mutex. + */ + __pci_reset_function_locked(psdev->dev); + if (pci_load_and_free_saved_state(psdev->dev, + &dev_data->pci_saved_state)) { + dev_dbg(&psdev->dev->dev, "Could not reload PCI state\n"); + } else + pci_restore_state(psdev->dev); + + /* Disable the device */ xen_pcibk_reset_device(psdev->dev); + + kfree(dev_data); + pci_set_drvdata(psdev->dev, NULL); + + /* Clean-up the device */ xen_pcibk_config_free_dyn_fields(psdev->dev); xen_pcibk_config_free_dev(psdev->dev); - kfree(pci_get_drvdata(psdev->dev)); - pci_set_drvdata(psdev->dev, NULL); psdev->dev->dev_flags &= ~PCI_DEV_FLAGS_ASSIGNED; pci_dev_put(psdev->dev); @@ -231,7 +246,17 @@ void pcistub_put_pci_dev(struct pci_dev *dev) /* Cleanup our device * (so it's ready for the next domain) */ + + /* This is OK - we are running from workqueue context + * and want to inhibit the user from fiddling with 'reset' + */ + pci_reset_function(dev); + pci_restore_state(psdev->dev); + + /* This disables the device. */ xen_pcibk_reset_device(found_psdev->dev); + + /* And cleanup up our emulated fields. */ xen_pcibk_config_free_dyn_fields(found_psdev->dev); xen_pcibk_config_reset_dev(found_psdev->dev); @@ -328,6 +353,16 @@ static int __devinit pcistub_init_device(struct pci_dev *dev) if (err) goto config_release; + dev_dbg(&dev->dev, "reseting (FLR, D3, etc) the device\n"); + __pci_reset_function_locked(dev); + + /* We need the device active to save the state. */ + dev_dbg(&dev->dev, "save state of device\n"); + pci_save_state(dev); + dev_data->pci_saved_state = pci_store_saved_state(dev); + if (!dev_data->pci_saved_state) + dev_err(&dev->dev, "Could not store PCI conf saved state!\n"); + /* Now disable the device (this also ensures some private device * data is setup before we export) */ diff --git a/drivers/xen/xen-pciback/pciback.h b/drivers/xen/xen-pciback/pciback.h index e9b4011c5f9..a7def010eba 100644 --- a/drivers/xen/xen-pciback/pciback.h +++ b/drivers/xen/xen-pciback/pciback.h @@ -41,6 +41,7 @@ struct xen_pcibk_device { struct xen_pcibk_dev_data { struct list_head config_fields; + struct pci_saved_state *pci_saved_state; unsigned int permissive:1; unsigned int warned_on_write:1; unsigned int enable_intx:1; -- cgit v1.2.3-70-g09d2 From f1df57d02a0f83e764b4dc9187f58665d70f190e Mon Sep 17 00:00:00 2001 From: Varun Wadekar Date: Fri, 13 Jan 2012 16:38:37 +1100 Subject: crypto: driver for Tegra AES hardware driver supports ecb/cbc/ofb/ansi_x9.31rng modes, 128, 192 and 256-bit key sizes Signed-off-by: Varun Wadekar Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 11 + drivers/crypto/Makefile | 1 + drivers/crypto/tegra-aes.c | 1096 ++++++++++++++++++++++++++++++++++++++++++++ drivers/crypto/tegra-aes.h | 103 +++++ 4 files changed, 1211 insertions(+) create mode 100644 drivers/crypto/tegra-aes.c create mode 100644 drivers/crypto/tegra-aes.h (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 6d16b4b0d7a..e707979767f 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -293,4 +293,15 @@ config CRYPTO_DEV_S5P Select this to offload Samsung S5PV210 or S5PC110 from AES algorithms execution. +config CRYPTO_DEV_TEGRA_AES + tristate "Support for TEGRA AES hw engine" + depends on ARCH_TEGRA + select CRYPTO_AES + help + TEGRA processors have AES module accelerator. Select this if you + want to use the TEGRA module for AES algorithms. + + To compile this driver as a module, choose M here: the module + will be called tegra-aes. + endif # CRYPTO_HW diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 53ea5015531..f3e64eadd7a 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_CRYPTO_DEV_OMAP_SHAM) += omap-sham.o obj-$(CONFIG_CRYPTO_DEV_OMAP_AES) += omap-aes.o obj-$(CONFIG_CRYPTO_DEV_PICOXCELL) += picoxcell_crypto.o obj-$(CONFIG_CRYPTO_DEV_S5P) += s5p-sss.o +obj-$(CONFIG_CRYPTO_DEV_TEGRA_AES) += tegra-aes.o diff --git a/drivers/crypto/tegra-aes.c b/drivers/crypto/tegra-aes.c new file mode 100644 index 00000000000..422a9766c7c --- /dev/null +++ b/drivers/crypto/tegra-aes.c @@ -0,0 +1,1096 @@ +/* + * drivers/crypto/tegra-aes.c + * + * Driver for NVIDIA Tegra AES hardware engine residing inside the + * Bit Stream Engine for Video (BSEV) hardware block. + * + * The programming sequence for this engine is with the help + * of commands which travel via a command queue residing between the + * CPU and the BSEV block. The BSEV engine has an internal RAM (VRAM) + * where the final input plaintext, keys and the IV have to be copied + * before starting the encrypt/decrypt operation. + * + * Copyright (c) 2010, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "tegra-aes.h" + +#define FLAGS_MODE_MASK 0x00FF +#define FLAGS_ENCRYPT BIT(0) +#define FLAGS_CBC BIT(1) +#define FLAGS_GIV BIT(2) +#define FLAGS_RNG BIT(3) +#define FLAGS_OFB BIT(4) +#define FLAGS_NEW_KEY BIT(5) +#define FLAGS_NEW_IV BIT(6) +#define FLAGS_INIT BIT(7) +#define FLAGS_FAST BIT(8) +#define FLAGS_BUSY 9 + +/* + * Defines AES engine Max process bytes size in one go, which takes 1 msec. + * AES engine spends about 176 cycles/16-bytes or 11 cycles/byte + * The duration CPU can use the BSE to 1 msec, then the number of available + * cycles of AVP/BSE is 216K. In this duration, AES can process 216/11 ~= 19KB + * Based on this AES_HW_DMA_BUFFER_SIZE_BYTES is configured to 16KB. + */ +#define AES_HW_DMA_BUFFER_SIZE_BYTES 0x4000 + +/* + * The key table length is 64 bytes + * (This includes first upto 32 bytes key + 16 bytes original initial vector + * and 16 bytes updated initial vector) + */ +#define AES_HW_KEY_TABLE_LENGTH_BYTES 64 + +/* + * The memory being used is divides as follows: + * 1. Key - 32 bytes + * 2. Original IV - 16 bytes + * 3. Updated IV - 16 bytes + * 4. Key schedule - 256 bytes + * + * 1+2+3 constitute the hw key table. + */ +#define AES_HW_IV_SIZE 16 +#define AES_HW_KEYSCHEDULE_LEN 256 +#define AES_IVKEY_SIZE (AES_HW_KEY_TABLE_LENGTH_BYTES + AES_HW_KEYSCHEDULE_LEN) + +/* Define commands required for AES operation */ +enum { + CMD_BLKSTARTENGINE = 0x0E, + CMD_DMASETUP = 0x10, + CMD_DMACOMPLETE = 0x11, + CMD_SETTABLE = 0x15, + CMD_MEMDMAVD = 0x22, +}; + +/* Define sub-commands */ +enum { + SUBCMD_VRAM_SEL = 0x1, + SUBCMD_CRYPTO_TABLE_SEL = 0x3, + SUBCMD_KEY_TABLE_SEL = 0x8, +}; + +/* memdma_vd command */ +#define MEMDMA_DIR_DTOVRAM 0 /* sdram -> vram */ +#define MEMDMA_DIR_VTODRAM 1 /* vram -> sdram */ +#define MEMDMA_DIR_SHIFT 25 +#define MEMDMA_NUM_WORDS_SHIFT 12 + +/* command queue bit shifts */ +enum { + CMDQ_KEYTABLEADDR_SHIFT = 0, + CMDQ_KEYTABLEID_SHIFT = 17, + CMDQ_VRAMSEL_SHIFT = 23, + CMDQ_TABLESEL_SHIFT = 24, + CMDQ_OPCODE_SHIFT = 26, +}; + +/* + * The secure key slot contains a unique secure key generated + * and loaded by the bootloader. This slot is marked as non-accessible + * to the kernel. + */ +#define SSK_SLOT_NUM 4 + +#define AES_NR_KEYSLOTS 8 +#define TEGRA_AES_QUEUE_LENGTH 50 +#define DEFAULT_RNG_BLK_SZ 16 + +/* The command queue depth */ +#define AES_HW_MAX_ICQ_LENGTH 5 + +struct tegra_aes_slot { + struct list_head node; + int slot_num; +}; + +static struct tegra_aes_slot ssk = { + .slot_num = SSK_SLOT_NUM, +}; + +struct tegra_aes_reqctx { + unsigned long mode; +}; + +struct tegra_aes_dev { + struct device *dev; + void __iomem *io_base; + dma_addr_t ivkey_phys_base; + void __iomem *ivkey_base; + struct clk *aes_clk; + struct tegra_aes_ctx *ctx; + int irq; + unsigned long flags; + struct completion op_complete; + u32 *buf_in; + dma_addr_t dma_buf_in; + u32 *buf_out; + dma_addr_t dma_buf_out; + u8 *iv; + u8 dt[DEFAULT_RNG_BLK_SZ]; + int ivlen; + u64 ctr; + spinlock_t lock; + struct crypto_queue queue; + struct tegra_aes_slot *slots; + struct ablkcipher_request *req; + size_t total; + struct scatterlist *in_sg; + size_t in_offset; + struct scatterlist *out_sg; + size_t out_offset; +}; + +static struct tegra_aes_dev *aes_dev; + +struct tegra_aes_ctx { + struct tegra_aes_dev *dd; + unsigned long flags; + struct tegra_aes_slot *slot; + u8 key[AES_MAX_KEY_SIZE]; + size_t keylen; +}; + +static struct tegra_aes_ctx rng_ctx = { + .flags = FLAGS_NEW_KEY, + .keylen = AES_KEYSIZE_128, +}; + +/* keep registered devices data here */ +static struct list_head dev_list; +static DEFINE_SPINLOCK(list_lock); +static DEFINE_MUTEX(aes_lock); + +static void aes_workqueue_handler(struct work_struct *work); +static DECLARE_WORK(aes_work, aes_workqueue_handler); +static struct workqueue_struct *aes_wq; + +extern unsigned long long tegra_chip_uid(void); + +static inline u32 aes_readl(struct tegra_aes_dev *dd, u32 offset) +{ + return readl(dd->io_base + offset); +} + +static inline void aes_writel(struct tegra_aes_dev *dd, u32 val, u32 offset) +{ + writel(val, dd->io_base + offset); +} + +static int aes_start_crypt(struct tegra_aes_dev *dd, u32 in_addr, u32 out_addr, + int nblocks, int mode, bool upd_iv) +{ + u32 cmdq[AES_HW_MAX_ICQ_LENGTH]; + int i, eng_busy, icq_empty, ret; + u32 value; + + /* reset all the interrupt bits */ + aes_writel(dd, 0xFFFFFFFF, TEGRA_AES_INTR_STATUS); + + /* enable error, dma xfer complete interrupts */ + aes_writel(dd, 0x33, TEGRA_AES_INT_ENB); + + cmdq[0] = CMD_DMASETUP << CMDQ_OPCODE_SHIFT; + cmdq[1] = in_addr; + cmdq[2] = CMD_BLKSTARTENGINE << CMDQ_OPCODE_SHIFT | (nblocks-1); + cmdq[3] = CMD_DMACOMPLETE << CMDQ_OPCODE_SHIFT; + + value = aes_readl(dd, TEGRA_AES_CMDQUE_CONTROL); + /* access SDRAM through AHB */ + value &= ~TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD; + value &= ~TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD; + value |= TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD | + TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD | + TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD; + aes_writel(dd, value, TEGRA_AES_CMDQUE_CONTROL); + dev_dbg(dd->dev, "cmd_q_ctrl=0x%x", value); + + value = (0x1 << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT) | + ((dd->ctx->keylen * 8) << + TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT) | + ((u32)upd_iv << TEGRA_AES_SECURE_IV_SELECT_SHIFT); + + if (mode & FLAGS_CBC) { + value |= ((((mode & FLAGS_ENCRYPT) ? 2 : 3) + << TEGRA_AES_SECURE_XOR_POS_SHIFT) | + (((mode & FLAGS_ENCRYPT) ? 2 : 3) + << TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT) | + ((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT); + } else if (mode & FLAGS_OFB) { + value |= ((TEGRA_AES_SECURE_XOR_POS_FIELD) | + (2 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT) | + (TEGRA_AES_SECURE_CORE_SEL_FIELD)); + } else if (mode & FLAGS_RNG) { + value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT | + TEGRA_AES_SECURE_RNG_ENB_FIELD); + } else { + value |= (((mode & FLAGS_ENCRYPT) ? 1 : 0) + << TEGRA_AES_SECURE_CORE_SEL_SHIFT); + } + + dev_dbg(dd->dev, "secure_in_sel=0x%x", value); + aes_writel(dd, value, TEGRA_AES_SECURE_INPUT_SELECT); + + aes_writel(dd, out_addr, TEGRA_AES_SECURE_DEST_ADDR); + INIT_COMPLETION(dd->op_complete); + + for (i = 0; i < AES_HW_MAX_ICQ_LENGTH - 1; i++) { + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + } while (eng_busy & (!icq_empty)); + aes_writel(dd, cmdq[i], TEGRA_AES_ICMDQUE_WR); + } + + ret = wait_for_completion_timeout(&dd->op_complete, + msecs_to_jiffies(150)); + if (ret == 0) { + dev_err(dd->dev, "timed out (0x%x)\n", + aes_readl(dd, TEGRA_AES_INTR_STATUS)); + return -ETIMEDOUT; + } + + aes_writel(dd, cmdq[AES_HW_MAX_ICQ_LENGTH - 1], TEGRA_AES_ICMDQUE_WR); + return 0; +} + +static void aes_release_key_slot(struct tegra_aes_slot *slot) +{ + if (slot->slot_num == SSK_SLOT_NUM) + return; + + spin_lock(&list_lock); + list_add_tail(&slot->node, &dev_list); + slot = NULL; + spin_unlock(&list_lock); +} + +static struct tegra_aes_slot *aes_find_key_slot(void) +{ + struct tegra_aes_slot *slot = NULL; + struct list_head *new_head; + int empty; + + spin_lock(&list_lock); + empty = list_empty(&dev_list); + if (!empty) { + slot = list_entry(&dev_list, struct tegra_aes_slot, node); + new_head = dev_list.next; + list_del(&dev_list); + dev_list.next = new_head->next; + dev_list.prev = NULL; + } + spin_unlock(&list_lock); + + return slot; +} + +static int aes_set_key(struct tegra_aes_dev *dd) +{ + u32 value, cmdq[2]; + struct tegra_aes_ctx *ctx = dd->ctx; + int eng_busy, icq_empty, dma_busy; + bool use_ssk = false; + + /* use ssk? */ + if (!dd->ctx->slot) { + dev_dbg(dd->dev, "using ssk"); + dd->ctx->slot = &ssk; + use_ssk = true; + } + + /* enable key schedule generation in hardware */ + value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG_EXT); + value &= ~TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD; + aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG_EXT); + + /* select the key slot */ + value = aes_readl(dd, TEGRA_AES_SECURE_CONFIG); + value &= ~TEGRA_AES_SECURE_KEY_INDEX_FIELD; + value |= (ctx->slot->slot_num << TEGRA_AES_SECURE_KEY_INDEX_SHIFT); + aes_writel(dd, value, TEGRA_AES_SECURE_CONFIG); + + if (use_ssk) + return 0; + + /* copy the key table from sdram to vram */ + cmdq[0] = CMD_MEMDMAVD << CMDQ_OPCODE_SHIFT | + MEMDMA_DIR_DTOVRAM << MEMDMA_DIR_SHIFT | + AES_HW_KEY_TABLE_LENGTH_BYTES / sizeof(u32) << + MEMDMA_NUM_WORDS_SHIFT; + cmdq[1] = (u32)dd->ivkey_phys_base; + + aes_writel(dd, cmdq[0], TEGRA_AES_ICMDQUE_WR); + aes_writel(dd, cmdq[1], TEGRA_AES_ICMDQUE_WR); + + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + dma_busy = value & TEGRA_AES_DMA_BUSY_FIELD; + } while (eng_busy & (!icq_empty) & dma_busy); + + /* settable command to get key into internal registers */ + value = CMD_SETTABLE << CMDQ_OPCODE_SHIFT | + SUBCMD_CRYPTO_TABLE_SEL << CMDQ_TABLESEL_SHIFT | + SUBCMD_VRAM_SEL << CMDQ_VRAMSEL_SHIFT | + (SUBCMD_KEY_TABLE_SEL | ctx->slot->slot_num) << + CMDQ_KEYTABLEID_SHIFT; + aes_writel(dd, value, TEGRA_AES_ICMDQUE_WR); + + do { + value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + eng_busy = value & TEGRA_AES_ENGINE_BUSY_FIELD; + icq_empty = value & TEGRA_AES_ICQ_EMPTY_FIELD; + } while (eng_busy & (!icq_empty)); + + return 0; +} + +static int tegra_aes_handle_req(struct tegra_aes_dev *dd) +{ + struct crypto_async_request *async_req, *backlog; + struct crypto_ablkcipher *tfm; + struct tegra_aes_ctx *ctx; + struct tegra_aes_reqctx *rctx; + struct ablkcipher_request *req; + unsigned long flags; + int dma_max = AES_HW_DMA_BUFFER_SIZE_BYTES; + int ret = 0, nblocks, total; + int count = 0; + dma_addr_t addr_in, addr_out; + struct scatterlist *in_sg, *out_sg; + + if (!dd) + return -EINVAL; + + spin_lock_irqsave(&dd->lock, flags); + backlog = crypto_get_backlog(&dd->queue); + async_req = crypto_dequeue_request(&dd->queue); + if (!async_req) + clear_bit(FLAGS_BUSY, &dd->flags); + spin_unlock_irqrestore(&dd->lock, flags); + + if (!async_req) + return -ENODATA; + + if (backlog) + backlog->complete(backlog, -EINPROGRESS); + + req = ablkcipher_request_cast(async_req); + + dev_dbg(dd->dev, "%s: get new req\n", __func__); + + if (!req->src || !req->dst) + return -EINVAL; + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + /* assign new request to device */ + dd->req = req; + dd->total = req->nbytes; + dd->in_offset = 0; + dd->in_sg = req->src; + dd->out_offset = 0; + dd->out_sg = req->dst; + + in_sg = dd->in_sg; + out_sg = dd->out_sg; + + total = dd->total; + + tfm = crypto_ablkcipher_reqtfm(req); + rctx = ablkcipher_request_ctx(req); + ctx = crypto_ablkcipher_ctx(tfm); + rctx->mode &= FLAGS_MODE_MASK; + dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; + + dd->iv = (u8 *)req->info; + dd->ivlen = crypto_ablkcipher_ivsize(tfm); + + /* assign new context to device */ + ctx->dd = dd; + dd->ctx = ctx; + + if (ctx->flags & FLAGS_NEW_KEY) { + /* copy the key */ + memcpy(dd->ivkey_base, ctx->key, ctx->keylen); + memset(dd->ivkey_base + ctx->keylen, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - ctx->keylen); + aes_set_key(dd); + ctx->flags &= ~FLAGS_NEW_KEY; + } + + if (((dd->flags & FLAGS_CBC) || (dd->flags & FLAGS_OFB)) && dd->iv) { + /* set iv to the aes hw slot + * Hw generates updated iv only after iv is set in slot. + * So key and iv is passed asynchronously. + */ + memcpy(dd->buf_in, dd->iv, dd->ivlen); + + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + dd->dma_buf_out, 1, FLAGS_CBC, false); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + } + + while (total) { + dev_dbg(dd->dev, "remain: %d\n", total); + ret = dma_map_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); + if (!ret) { + dev_err(dd->dev, "dma_map_sg() error\n"); + goto out; + } + + ret = dma_map_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); + if (!ret) { + dev_err(dd->dev, "dma_map_sg() error\n"); + dma_unmap_sg(dd->dev, dd->in_sg, + 1, DMA_TO_DEVICE); + goto out; + } + + addr_in = sg_dma_address(in_sg); + addr_out = sg_dma_address(out_sg); + dd->flags |= FLAGS_FAST; + count = min_t(int, sg_dma_len(in_sg), dma_max); + WARN_ON(sg_dma_len(in_sg) != sg_dma_len(out_sg)); + nblocks = DIV_ROUND_UP(count, AES_BLOCK_SIZE); + + ret = aes_start_crypt(dd, addr_in, addr_out, nblocks, + dd->flags, true); + + dma_unmap_sg(dd->dev, out_sg, 1, DMA_FROM_DEVICE); + dma_unmap_sg(dd->dev, in_sg, 1, DMA_TO_DEVICE); + + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + dd->flags &= ~FLAGS_FAST; + + dev_dbg(dd->dev, "out: copied %d\n", count); + total -= count; + in_sg = sg_next(in_sg); + out_sg = sg_next(out_sg); + WARN_ON(((total != 0) && (!in_sg || !out_sg))); + } + +out: + mutex_unlock(&aes_lock); + + dd->total = total; + + if (dd->req->base.complete) + dd->req->base.complete(&dd->req->base, ret); + + dev_dbg(dd->dev, "%s: exit\n", __func__); + return ret; +} + +static int tegra_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct tegra_aes_ctx *ctx = crypto_ablkcipher_ctx(tfm); + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_slot *key_slot; + + if ((keylen != AES_KEYSIZE_128) && (keylen != AES_KEYSIZE_192) && + (keylen != AES_KEYSIZE_256)) { + dev_err(dd->dev, "unsupported key size\n"); + crypto_ablkcipher_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + dev_dbg(dd->dev, "keylen: %d\n", keylen); + + ctx->dd = dd; + + if (key) { + if (!ctx->slot) { + key_slot = aes_find_key_slot(); + if (!key_slot) { + dev_err(dd->dev, "no empty slot\n"); + return -ENOMEM; + } + + ctx->slot = key_slot; + } + + memcpy(ctx->key, key, keylen); + ctx->keylen = keylen; + } + + ctx->flags |= FLAGS_NEW_KEY; + dev_dbg(dd->dev, "done\n"); + return 0; +} + +static void aes_workqueue_handler(struct work_struct *work) +{ + struct tegra_aes_dev *dd = aes_dev; + int ret; + + ret = clk_enable(dd->aes_clk); + if (ret) + BUG_ON("clock enable failed"); + + /* empty the crypto queue and then return */ + do { + ret = tegra_aes_handle_req(dd); + } while (!ret); + + clk_disable(dd->aes_clk); +} + +static irqreturn_t aes_irq(int irq, void *dev_id) +{ + struct tegra_aes_dev *dd = (struct tegra_aes_dev *)dev_id; + u32 value = aes_readl(dd, TEGRA_AES_INTR_STATUS); + int busy = test_bit(FLAGS_BUSY, &dd->flags); + + if (!busy) { + dev_dbg(dd->dev, "spurious interrupt\n"); + return IRQ_NONE; + } + + dev_dbg(dd->dev, "irq_stat: 0x%x\n", value); + if (value & TEGRA_AES_INT_ERROR_MASK) + aes_writel(dd, TEGRA_AES_INT_ERROR_MASK, TEGRA_AES_INTR_STATUS); + + if (!(value & TEGRA_AES_ENGINE_BUSY_FIELD)) + complete(&dd->op_complete); + else + return IRQ_NONE; + + return IRQ_HANDLED; +} + +static int tegra_aes_crypt(struct ablkcipher_request *req, unsigned long mode) +{ + struct tegra_aes_reqctx *rctx = ablkcipher_request_ctx(req); + struct tegra_aes_dev *dd = aes_dev; + unsigned long flags; + int err = 0; + int busy; + + dev_dbg(dd->dev, "nbytes: %d, enc: %d, cbc: %d, ofb: %d\n", + req->nbytes, !!(mode & FLAGS_ENCRYPT), + !!(mode & FLAGS_CBC), !!(mode & FLAGS_OFB)); + + rctx->mode = mode; + + spin_lock_irqsave(&dd->lock, flags); + err = ablkcipher_enqueue_request(&dd->queue, req); + busy = test_and_set_bit(FLAGS_BUSY, &dd->flags); + spin_unlock_irqrestore(&dd->lock, flags); + + if (!busy) + queue_work(aes_wq, &aes_work); + + return err; +} + +static int tegra_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT); +} + +static int tegra_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, 0); +} + +static int tegra_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_CBC); +} + +static int tegra_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_CBC); +} + +static int tegra_aes_ofb_encrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_ENCRYPT | FLAGS_OFB); +} + +static int tegra_aes_ofb_decrypt(struct ablkcipher_request *req) +{ + return tegra_aes_crypt(req, FLAGS_OFB); +} + +static int tegra_aes_get_random(struct crypto_rng *tfm, u8 *rdata, + unsigned int dlen) +{ + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_ctx *ctx = &rng_ctx; + int ret, i; + u8 *dest = rdata, *dt = dd->dt; + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + ret = clk_enable(dd->aes_clk); + if (ret) + return ret; + + ctx->dd = dd; + dd->ctx = ctx; + dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; + + memcpy(dd->buf_in, dt, DEFAULT_RNG_BLK_SZ); + + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + (u32)dd->dma_buf_out, 1, dd->flags, true); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + dlen = ret; + goto out; + } + memcpy(dest, dd->buf_out, dlen); + + /* update the DT */ + for (i = DEFAULT_RNG_BLK_SZ - 1; i >= 0; i--) { + dt[i] += 1; + if (dt[i] != 0) + break; + } + +out: + clk_disable(dd->aes_clk); + mutex_unlock(&aes_lock); + + dev_dbg(dd->dev, "%s: done\n", __func__); + return dlen; +} + +static int tegra_aes_rng_reset(struct crypto_rng *tfm, u8 *seed, + unsigned int slen) +{ + struct tegra_aes_dev *dd = aes_dev; + struct tegra_aes_ctx *ctx = &rng_ctx; + struct tegra_aes_slot *key_slot; + struct timespec ts; + int ret = 0; + u64 nsec, tmp[2]; + u8 *dt; + + if (!ctx || !dd) { + dev_err(dd->dev, "ctx=0x%x, dd=0x%x\n", + (unsigned int)ctx, (unsigned int)dd); + return -EINVAL; + } + + if (slen < (DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { + dev_err(dd->dev, "seed size invalid"); + return -ENOMEM; + } + + /* take mutex to access the aes hw */ + mutex_lock(&aes_lock); + + if (!ctx->slot) { + key_slot = aes_find_key_slot(); + if (!key_slot) { + dev_err(dd->dev, "no empty slot\n"); + mutex_unlock(&aes_lock); + return -ENOMEM; + } + ctx->slot = key_slot; + } + + ctx->dd = dd; + dd->ctx = ctx; + dd->ctr = 0; + + ctx->keylen = AES_KEYSIZE_128; + ctx->flags |= FLAGS_NEW_KEY; + + /* copy the key to the key slot */ + memcpy(dd->ivkey_base, seed + DEFAULT_RNG_BLK_SZ, AES_KEYSIZE_128); + memset(dd->ivkey_base + AES_KEYSIZE_128, 0, AES_HW_KEY_TABLE_LENGTH_BYTES - AES_KEYSIZE_128); + + dd->iv = seed; + dd->ivlen = slen; + + dd->flags = FLAGS_ENCRYPT | FLAGS_RNG; + + ret = clk_enable(dd->aes_clk); + if (ret) + return ret; + + aes_set_key(dd); + + /* set seed to the aes hw slot */ + memcpy(dd->buf_in, dd->iv, DEFAULT_RNG_BLK_SZ); + ret = aes_start_crypt(dd, (u32)dd->dma_buf_in, + dd->dma_buf_out, 1, FLAGS_CBC, false); + if (ret < 0) { + dev_err(dd->dev, "aes_start_crypt fail(%d)\n", ret); + goto out; + } + + if (dd->ivlen >= (2 * DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128)) { + dt = dd->iv + DEFAULT_RNG_BLK_SZ + AES_KEYSIZE_128; + } else { + getnstimeofday(&ts); + nsec = timespec_to_ns(&ts); + do_div(nsec, 1000); + nsec ^= dd->ctr << 56; + dd->ctr++; + tmp[0] = nsec; + tmp[1] = tegra_chip_uid(); + dt = (u8 *)tmp; + } + memcpy(dd->dt, dt, DEFAULT_RNG_BLK_SZ); + +out: + clk_disable(dd->aes_clk); + mutex_unlock(&aes_lock); + + dev_dbg(dd->dev, "%s: done\n", __func__); + return ret; +} + +static int tegra_aes_cra_init(struct crypto_tfm *tfm) +{ + tfm->crt_ablkcipher.reqsize = sizeof(struct tegra_aes_reqctx); + + return 0; +} + +void tegra_aes_cra_exit(struct crypto_tfm *tfm) +{ + struct tegra_aes_ctx *ctx = + crypto_ablkcipher_ctx((struct crypto_ablkcipher *)tfm); + + if (ctx && ctx->slot) + aes_release_key_slot(ctx->slot); +} + +static struct crypto_alg algs[] = { + { + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_ecb_encrypt, + .decrypt = tegra_aes_ecb_decrypt, + }, + }, { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_MIN_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_cbc_encrypt, + .decrypt = tegra_aes_cbc_decrypt, + } + }, { + .cra_name = "ofb(aes)", + .cra_driver_name = "ofb-aes-tegra", + .cra_priority = 300, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_alignmask = 3, + .cra_type = &crypto_ablkcipher_type, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .ivsize = AES_MIN_KEY_SIZE, + .setkey = tegra_aes_setkey, + .encrypt = tegra_aes_ofb_encrypt, + .decrypt = tegra_aes_ofb_decrypt, + } + }, { + .cra_name = "ansi_cprng", + .cra_driver_name = "rng-aes-tegra", + .cra_flags = CRYPTO_ALG_TYPE_RNG, + .cra_ctxsize = sizeof(struct tegra_aes_ctx), + .cra_type = &crypto_rng_type, + .cra_u.rng = { + .rng_make_random = tegra_aes_get_random, + .rng_reset = tegra_aes_rng_reset, + .seedsize = AES_KEYSIZE_128 + (2 * DEFAULT_RNG_BLK_SZ), + } + } +}; + +static int tegra_aes_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra_aes_dev *dd; + struct resource *res; + int err = -ENOMEM, i = 0, j; + + dd = devm_kzalloc(dev, sizeof(struct tegra_aes_dev), GFP_KERNEL); + if (dd == NULL) { + dev_err(dev, "unable to alloc data struct.\n"); + return err; + } + + dd->dev = dev; + platform_set_drvdata(pdev, dd); + + dd->slots = devm_kzalloc(dev, sizeof(struct tegra_aes_slot) * + AES_NR_KEYSLOTS, GFP_KERNEL); + if (dd->slots == NULL) { + dev_err(dev, "unable to alloc slot struct.\n"); + goto out; + } + + spin_lock_init(&dd->lock); + crypto_init_queue(&dd->queue, TEGRA_AES_QUEUE_LENGTH); + + /* Get the module base address */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "invalid resource type: base\n"); + err = -ENODEV; + goto out; + } + + if (!devm_request_mem_region(&pdev->dev, res->start, + resource_size(res), + dev_name(&pdev->dev))) { + dev_err(&pdev->dev, "Couldn't request MEM resource\n"); + return -ENODEV; + } + + dd->io_base = devm_ioremap(dev, res->start, resource_size(res)); + if (!dd->io_base) { + dev_err(dev, "can't ioremap register space\n"); + err = -ENOMEM; + goto out; + } + + /* Initialize the vde clock */ + dd->aes_clk = clk_get(dev, "vde"); + if (IS_ERR(dd->aes_clk)) { + dev_err(dev, "iclock intialization failed.\n"); + err = -ENODEV; + goto out; + } + + err = clk_set_rate(dd->aes_clk, ULONG_MAX); + if (err) { + dev_err(dd->dev, "iclk set_rate fail(%d)\n", err); + goto out; + } + + /* + * the foll contiguous memory is allocated as follows - + * - hardware key table + * - key schedule + */ + dd->ivkey_base = dma_alloc_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + &dd->ivkey_phys_base, + GFP_KERNEL); + if (!dd->ivkey_base) { + dev_err(dev, "can not allocate iv/key buffer\n"); + err = -ENOMEM; + goto out; + } + + dd->buf_in = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + &dd->dma_buf_in, GFP_KERNEL); + if (!dd->buf_in) { + dev_err(dev, "can not allocate dma-in buffer\n"); + err = -ENOMEM; + goto out; + } + + dd->buf_out = dma_alloc_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + &dd->dma_buf_out, GFP_KERNEL); + if (!dd->buf_out) { + dev_err(dev, "can not allocate dma-out buffer\n"); + err = -ENOMEM; + goto out; + } + + init_completion(&dd->op_complete); + aes_wq = alloc_workqueue("tegra_aes_wq", WQ_HIGHPRI | WQ_UNBOUND, 1); + if (!aes_wq) { + dev_err(dev, "alloc_workqueue failed\n"); + goto out; + } + + /* get the irq */ + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(dev, "invalid resource type: base\n"); + err = -ENODEV; + goto out; + } + dd->irq = res->start; + + err = devm_request_irq(dev, dd->irq, aes_irq, IRQF_TRIGGER_HIGH | + IRQF_SHARED, "tegra-aes", dd); + if (err) { + dev_err(dev, "request_irq failed\n"); + goto out; + } + + mutex_init(&aes_lock); + INIT_LIST_HEAD(&dev_list); + + spin_lock_init(&list_lock); + spin_lock(&list_lock); + for (i = 0; i < AES_NR_KEYSLOTS; i++) { + if (i == SSK_SLOT_NUM) + continue; + dd->slots[i].slot_num = i; + INIT_LIST_HEAD(&dd->slots[i].node); + list_add_tail(&dd->slots[i].node, &dev_list); + } + spin_unlock(&list_lock); + + aes_dev = dd; + for (i = 0; i < ARRAY_SIZE(algs); i++) { + INIT_LIST_HEAD(&algs[i].cra_list); + + algs[i].cra_priority = 300; + algs[i].cra_ctxsize = sizeof(struct tegra_aes_ctx); + algs[i].cra_module = THIS_MODULE; + algs[i].cra_init = tegra_aes_cra_init; + algs[i].cra_exit = tegra_aes_cra_exit; + + err = crypto_register_alg(&algs[i]); + if (err) + goto out; + } + + dev_info(dev, "registered"); + return 0; + +out: + for (j = 0; j < i; j++) + crypto_unregister_alg(&algs[j]); + if (dd->ivkey_base) + dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + dd->ivkey_base, dd->ivkey_phys_base); + if (dd->buf_in) + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_in, dd->dma_buf_in); + if (dd->buf_out) + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_out, dd->dma_buf_out); + if (IS_ERR(dd->aes_clk)) + clk_put(dd->aes_clk); + if (aes_wq) + destroy_workqueue(aes_wq); + spin_lock(&list_lock); + list_del(&dev_list); + spin_unlock(&list_lock); + + aes_dev = NULL; + + dev_err(dev, "%s: initialization failed.\n", __func__); + return err; +} + +static int __devexit tegra_aes_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct tegra_aes_dev *dd = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(algs); i++) + crypto_unregister_alg(&algs[i]); + + cancel_work_sync(&aes_work); + destroy_workqueue(aes_wq); + spin_lock(&list_lock); + list_del(&dev_list); + spin_unlock(&list_lock); + + dma_free_coherent(dev, AES_HW_KEY_TABLE_LENGTH_BYTES, + dd->ivkey_base, dd->ivkey_phys_base); + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_in, dd->dma_buf_in); + dma_free_coherent(dev, AES_HW_DMA_BUFFER_SIZE_BYTES, + dd->buf_out, dd->dma_buf_out); + clk_put(dd->aes_clk); + aes_dev = NULL; + + return 0; +} + +static struct of_device_id tegra_aes_of_match[] __devinitdata = { + { .compatible = "nvidia,tegra20-aes", }, + { .compatible = "nvidia,tegra30-aes", }, + { }, +}; + +static struct platform_driver tegra_aes_driver = { + .probe = tegra_aes_probe, + .remove = __devexit_p(tegra_aes_remove), + .driver = { + .name = "tegra-aes", + .owner = THIS_MODULE, + .of_match_table = tegra_aes_of_match, + }, +}; + +module_platform_driver(tegra_aes_driver); + +MODULE_DESCRIPTION("Tegra AES/OFB/CPRNG hw acceleration support."); +MODULE_AUTHOR("NVIDIA Corporation"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/crypto/tegra-aes.h b/drivers/crypto/tegra-aes.h new file mode 100644 index 00000000000..6006333a893 --- /dev/null +++ b/drivers/crypto/tegra-aes.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2010, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef __CRYPTODEV_TEGRA_AES_H +#define __CRYPTODEV_TEGRA_AES_H + +#define TEGRA_AES_ICMDQUE_WR 0x1000 +#define TEGRA_AES_CMDQUE_CONTROL 0x1008 +#define TEGRA_AES_INTR_STATUS 0x1018 +#define TEGRA_AES_INT_ENB 0x1040 +#define TEGRA_AES_CONFIG 0x1044 +#define TEGRA_AES_IRAM_ACCESS_CFG 0x10A0 +#define TEGRA_AES_SECURE_DEST_ADDR 0x1100 +#define TEGRA_AES_SECURE_INPUT_SELECT 0x1104 +#define TEGRA_AES_SECURE_CONFIG 0x1108 +#define TEGRA_AES_SECURE_CONFIG_EXT 0x110C +#define TEGRA_AES_SECURE_SECURITY 0x1110 +#define TEGRA_AES_SECURE_HASH_RESULT0 0x1120 +#define TEGRA_AES_SECURE_HASH_RESULT1 0x1124 +#define TEGRA_AES_SECURE_HASH_RESULT2 0x1128 +#define TEGRA_AES_SECURE_HASH_RESULT3 0x112C +#define TEGRA_AES_SECURE_SEC_SEL0 0x1140 +#define TEGRA_AES_SECURE_SEC_SEL1 0x1144 +#define TEGRA_AES_SECURE_SEC_SEL2 0x1148 +#define TEGRA_AES_SECURE_SEC_SEL3 0x114C +#define TEGRA_AES_SECURE_SEC_SEL4 0x1150 +#define TEGRA_AES_SECURE_SEC_SEL5 0x1154 +#define TEGRA_AES_SECURE_SEC_SEL6 0x1158 +#define TEGRA_AES_SECURE_SEC_SEL7 0x115C + +/* interrupt status reg masks and shifts */ +#define TEGRA_AES_ENGINE_BUSY_FIELD BIT(0) +#define TEGRA_AES_ICQ_EMPTY_FIELD BIT(3) +#define TEGRA_AES_DMA_BUSY_FIELD BIT(23) + +/* secure select reg masks and shifts */ +#define TEGRA_AES_SECURE_SEL0_KEYREAD_ENB0_FIELD BIT(0) + +/* secure config ext masks and shifts */ +#define TEGRA_AES_SECURE_KEY_SCH_DIS_FIELD BIT(15) + +/* secure config masks and shifts */ +#define TEGRA_AES_SECURE_KEY_INDEX_SHIFT 20 +#define TEGRA_AES_SECURE_KEY_INDEX_FIELD (0x1F << TEGRA_AES_SECURE_KEY_INDEX_SHIFT) +#define TEGRA_AES_SECURE_BLOCK_CNT_SHIFT 0 +#define TEGRA_AES_SECURE_BLOCK_CNT_FIELD (0xFFFFF << TEGRA_AES_SECURE_BLOCK_CNT_SHIFT) + +/* stream interface select masks and shifts */ +#define TEGRA_AES_CMDQ_CTRL_UCMDQEN_FIELD BIT(0) +#define TEGRA_AES_CMDQ_CTRL_ICMDQEN_FIELD BIT(1) +#define TEGRA_AES_CMDQ_CTRL_SRC_STM_SEL_FIELD BIT(4) +#define TEGRA_AES_CMDQ_CTRL_DST_STM_SEL_FIELD BIT(5) + +/* config register masks and shifts */ +#define TEGRA_AES_CONFIG_ENDIAN_ENB_FIELD BIT(10) +#define TEGRA_AES_CONFIG_MODE_SEL_SHIFT 0 +#define TEGRA_AES_CONFIG_MODE_SEL_FIELD (0x1F << TEGRA_AES_CONFIG_MODE_SEL_SHIFT) + +/* extended config */ +#define TEGRA_AES_SECURE_OFFSET_CNT_SHIFT 24 +#define TEGRA_AES_SECURE_OFFSET_CNT_FIELD (0xFF << TEGRA_AES_SECURE_OFFSET_CNT_SHIFT) +#define TEGRA_AES_SECURE_KEYSCHED_GEN_FIELD BIT(15) + +/* init vector select */ +#define TEGRA_AES_SECURE_IV_SELECT_SHIFT 10 +#define TEGRA_AES_SECURE_IV_SELECT_FIELD BIT(10) + +/* secure engine input */ +#define TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT 28 +#define TEGRA_AES_SECURE_INPUT_ALG_SEL_FIELD (0xF << TEGRA_AES_SECURE_INPUT_ALG_SEL_SHIFT) +#define TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT 16 +#define TEGRA_AES_SECURE_INPUT_KEY_LEN_FIELD (0xFFF << TEGRA_AES_SECURE_INPUT_KEY_LEN_SHIFT) +#define TEGRA_AES_SECURE_RNG_ENB_FIELD BIT(11) +#define TEGRA_AES_SECURE_CORE_SEL_SHIFT 9 +#define TEGRA_AES_SECURE_CORE_SEL_FIELD BIT(9) +#define TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT 7 +#define TEGRA_AES_SECURE_VCTRAM_SEL_FIELD (0x3 << TEGRA_AES_SECURE_VCTRAM_SEL_SHIFT) +#define TEGRA_AES_SECURE_INPUT_SEL_SHIFT 5 +#define TEGRA_AES_SECURE_INPUT_SEL_FIELD (0x3 << TEGRA_AES_SECURE_INPUT_SEL_SHIFT) +#define TEGRA_AES_SECURE_XOR_POS_SHIFT 3 +#define TEGRA_AES_SECURE_XOR_POS_FIELD (0x3 << TEGRA_AES_SECURE_XOR_POS_SHIFT) +#define TEGRA_AES_SECURE_HASH_ENB_FIELD BIT(2) +#define TEGRA_AES_SECURE_ON_THE_FLY_FIELD BIT(0) + +/* interrupt error mask */ +#define TEGRA_AES_INT_ERROR_MASK 0xFFF000 + +#endif -- cgit v1.2.3-70-g09d2 From d0b03c5fe469ed0f3d7d94372c8bf77c64fcfce8 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 27 Dec 2011 15:01:30 +0100 Subject: hwrng: tx4939 - use devm_request_and_ioremap Reimplement a call to devm_request_mem_region followed by a call to ioremap or ioremap_nocache by a call to devm_request_and_ioremap. The semantic patch that makes this transformation is as follows: (http://coccinelle.lip6.fr/) // @nm@ expression myname; identifier i; @@ struct platform_driver i = { .driver = { .name = myname } }; @@ expression dev,res,size; expression nm.myname; @@ -if (!devm_request_mem_region(dev, res->start, size, - \(res->name\|dev_name(dev)\|myname\))) { - ... - return ...; -} ... when != res->start ( -devm_ioremap(dev,res->start,size) +devm_request_and_ioremap(dev,res) | -devm_ioremap_nocache(dev,res->start,size) +devm_request_and_ioremap(dev,res) ) ... when any when != res->start // Signed-off-by: Julia Lawall Signed-off-by: Herbert Xu --- drivers/char/hw_random/tx4939-rng.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/tx4939-rng.c b/drivers/char/hw_random/tx4939-rng.c index 0bc0cb70210..de473ef3882 100644 --- a/drivers/char/hw_random/tx4939-rng.c +++ b/drivers/char/hw_random/tx4939-rng.c @@ -115,10 +115,7 @@ static int __init tx4939_rng_probe(struct platform_device *dev) rngdev = devm_kzalloc(&dev->dev, sizeof(*rngdev), GFP_KERNEL); if (!rngdev) return -ENOMEM; - if (!devm_request_mem_region(&dev->dev, r->start, resource_size(r), - dev_name(&dev->dev))) - return -EBUSY; - rngdev->base = devm_ioremap(&dev->dev, r->start, resource_size(r)); + rngdev->base = devm_request_and_ioremap(&dev->dev, r); if (!rngdev->base) return -EBUSY; -- cgit v1.2.3-70-g09d2 From d912bb7677f46d78a3cde8a4afd45a3fca4b34e9 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 1 Nov 2011 13:39:56 +0100 Subject: crypto: Add CRYPTO_ALG_KERN_DRIVER_ONLY flag The added CRYPTO_ALG_KERN_DRIVER_ONLY indicates whether a cipher is only available via a kernel driver. If the cipher implementation might be available by using an instruction set or by porting the kernel code, then it must not be set. Signed-off-by: Nikos Mavrogiannopoulos Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 3 ++- drivers/crypto/geode-aes.c | 6 +++-- drivers/crypto/hifn_795x.c | 3 ++- drivers/crypto/ixp4xx_crypto.c | 2 ++ drivers/crypto/mv_cesa.c | 12 ++++++---- drivers/crypto/n2_core.c | 7 ++++-- drivers/crypto/omap-aes.c | 8 +++++-- drivers/crypto/omap-sham.c | 4 ++++ drivers/crypto/picoxcell_crypto.c | 46 +++++++++++++++++++++++++++++---------- drivers/crypto/s5p-sss.c | 6 +++-- drivers/crypto/talitos.c | 1 + include/linux/crypto.h | 5 +++++ 12 files changed, 78 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index e73cf2e8110..e9acadbb1d3 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2205,7 +2205,8 @@ static struct caam_crypto_alg *caam_alg_alloc(struct device *ctrldev, alg->cra_blocksize = template->blocksize; alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct caam_ctx); - alg->cra_flags = CRYPTO_ALG_ASYNC | template->type; + alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + template->type; switch (template->type) { case CRYPTO_ALG_TYPE_ABLKCIPHER: alg->cra_type = &crypto_ablkcipher_type; diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index 219d09cbb0d..f3e36c86b6c 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -393,7 +393,8 @@ static struct crypto_alg geode_cbc_alg = { .cra_driver_name = "cbc-aes-geode", .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_init = fallback_init_blk, .cra_exit = fallback_exit_blk, .cra_blocksize = AES_MIN_BLOCK_SIZE, @@ -479,7 +480,8 @@ static struct crypto_alg geode_ecb_alg = { .cra_driver_name = "ecb-aes-geode", .cra_priority = 400, .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | - CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_init = fallback_init_blk, .cra_exit = fallback_exit_blk, .cra_blocksize = AES_MIN_BLOCK_SIZE, diff --git a/drivers/crypto/hifn_795x.c b/drivers/crypto/hifn_795x.c index fe765f49de5..6bd9d176820 100644 --- a/drivers/crypto/hifn_795x.c +++ b/drivers/crypto/hifn_795x.c @@ -2494,7 +2494,8 @@ static int hifn_alg_alloc(struct hifn_device *dev, struct hifn_alg_template *t) t->drv_name, dev->name); alg->alg.cra_priority = 300; - alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + alg->alg.cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; alg->alg.cra_blocksize = t->bsize; alg->alg.cra_ctxsize = sizeof(struct hifn_context); alg->alg.cra_alignmask = 0; diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 4c20c5bf605..a82c11af9f4 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -1449,6 +1449,7 @@ static int __init ixp_module_init(void) /* block ciphers */ cra->cra_type = &crypto_ablkcipher_type; cra->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; if (!cra->cra_ablkcipher.setkey) cra->cra_ablkcipher.setkey = ablk_setkey; @@ -1461,6 +1462,7 @@ static int __init ixp_module_init(void) /* authenc */ cra->cra_type = &crypto_aead_type; cra->cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; cra->cra_aead.setkey = aead_setkey; cra->cra_aead.setauthsize = aead_setauthsize; diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c index 597235a2f8f..8ad2883505a 100644 --- a/drivers/crypto/mv_cesa.c +++ b/drivers/crypto/mv_cesa.c @@ -898,7 +898,8 @@ struct crypto_alg mv_aes_alg_ecb = { .cra_name = "ecb(aes)", .cra_driver_name = "mv-ecb-aes", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC, .cra_blocksize = 16, .cra_ctxsize = sizeof(struct mv_ctx), .cra_alignmask = 0, @@ -920,7 +921,8 @@ struct crypto_alg mv_aes_alg_cbc = { .cra_name = "cbc(aes)", .cra_driver_name = "mv-cbc-aes", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_ctx), .cra_alignmask = 0, @@ -952,7 +954,8 @@ struct ahash_alg mv_sha1_alg = { .cra_driver_name = "mv-sha1", .cra_priority = 300, .cra_flags = - CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), .cra_init = mv_cra_hash_sha1_init, @@ -976,7 +979,8 @@ struct ahash_alg mv_hmac_sha1_alg = { .cra_driver_name = "mv-hmac-sha1", .cra_priority = 300, .cra_flags = - CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, + CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct mv_tfm_hash_ctx), .cra_init = mv_cra_hash_hmac_sha1_init, diff --git a/drivers/crypto/n2_core.c b/drivers/crypto/n2_core.c index 8944dabc0e3..67b97c5fd85 100644 --- a/drivers/crypto/n2_core.c +++ b/drivers/crypto/n2_core.c @@ -1402,7 +1402,8 @@ static int __devinit __n2_register_one_cipher(const struct n2_cipher_tmpl *tmpl) snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->drv_name); alg->cra_priority = N2_CRA_PRIORITY; - alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC; + alg->cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC; alg->cra_blocksize = tmpl->block_size; p->enc_type = tmpl->enc_type; alg->cra_ctxsize = sizeof(struct n2_cipher_context); @@ -1493,7 +1494,9 @@ static int __devinit __n2_register_one_ahash(const struct n2_hash_tmpl *tmpl) snprintf(base->cra_name, CRYPTO_MAX_ALG_NAME, "%s", tmpl->name); snprintf(base->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s-n2", tmpl->name); base->cra_priority = N2_CRA_PRIORITY; - base->cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK; + base->cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_NEED_FALLBACK; base->cra_blocksize = tmpl->block_size; base->cra_ctxsize = sizeof(struct n2_hash_ctx); base->cra_module = THIS_MODULE; diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 5b970d9e995..63e57b57a12 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -756,7 +756,9 @@ static struct crypto_alg algs[] = { .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-omap", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), .cra_alignmask = 0, @@ -776,7 +778,9 @@ static struct crypto_alg algs[] = { .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-omap", .cra_priority = 100, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | + CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), .cra_alignmask = 0, diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 6399a8f1938..a3fd6fc504b 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -953,6 +953,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-sha1", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -975,6 +976,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-md5", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -998,6 +1000,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-hmac-sha1", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, @@ -1022,6 +1025,7 @@ static struct ahash_alg algs[] = { .cra_driver_name = "omap-hmac-md5", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, diff --git a/drivers/crypto/picoxcell_crypto.c b/drivers/crypto/picoxcell_crypto.c index 58480d00932..410a03c01ca 100644 --- a/drivers/crypto/picoxcell_crypto.c +++ b/drivers/crypto/picoxcell_crypto.c @@ -1322,6 +1322,7 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_driver_name = "cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, @@ -1349,6 +1350,7 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_driver_name = "ecb-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_KERN_DRIVER_ONLY | CRYPTO_ALG_ASYNC | CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), @@ -1373,7 +1375,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "cbc(des)", .cra_driver_name = "cbc-des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1398,7 +1402,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "ecb(des)", .cra_driver_name = "ecb-des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1422,7 +1428,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "cbc(des3_ede)", .cra_driver_name = "cbc-des3-ede-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1447,7 +1455,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "ecb(des3_ede)", .cra_driver_name = "ecb-des3-ede-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, @@ -1472,7 +1482,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha1),cbc(aes))", .cra_driver_name = "authenc-hmac-sha1-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1500,7 +1512,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha256),cbc(aes))", .cra_driver_name = "authenc-hmac-sha256-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1527,7 +1541,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(md5),cbc(aes))", .cra_driver_name = "authenc-hmac-md5-cbc-aes-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1554,7 +1570,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha1),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha1-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1582,7 +1600,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(sha256),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-sha256-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1609,7 +1629,9 @@ static struct spacc_alg ipsec_engine_algs[] = { .cra_name = "authenc(hmac(md5),cbc(des3_ede))", .cra_driver_name = "authenc-hmac-md5-cbc-3des-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = DES3_EDE_BLOCK_SIZE, .cra_ctxsize = sizeof(struct spacc_aead_ctx), .cra_type = &crypto_aead_type, @@ -1639,7 +1661,9 @@ static struct spacc_alg l2_engine_algs[] = { .cra_name = "f8(kasumi)", .cra_driver_name = "f8-kasumi-picoxcell", .cra_priority = SPACC_CRYPTO_ALG_PRIORITY, - .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_TYPE_GIVCIPHER | + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = 8, .cra_ctxsize = sizeof(struct spacc_ablk_ctx), .cra_type = &crypto_ablkcipher_type, diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index 3376bca200f..bc986f80608 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c @@ -518,7 +518,8 @@ static struct crypto_alg algs[] = { .cra_driver_name = "ecb-aes-s5p", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | - CRYPTO_ALG_ASYNC, + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s5p_aes_ctx), .cra_alignmask = 0x0f, @@ -538,7 +539,8 @@ static struct crypto_alg algs[] = { .cra_driver_name = "cbc-aes-s5p", .cra_priority = 100, .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | - CRYPTO_ALG_ASYNC, + CRYPTO_ALG_ASYNC | + CRYPTO_ALG_KERN_DRIVER_ONLY, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct s5p_aes_ctx), .cra_alignmask = 0x0f, diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 2d8c7890168..dc641c79652 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -2648,6 +2648,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, alg->cra_priority = TALITOS_CRA_PRIORITY; alg->cra_alignmask = 0; alg->cra_ctxsize = sizeof(struct talitos_ctx); + alg->cra_flags |= CRYPTO_ALG_KERN_DRIVER_ONLY; t_alg->dev = dev; diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 8a94217b298..a8fa6541b86 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -75,6 +75,11 @@ */ #define CRYPTO_ALG_INSTANCE 0x00000800 +/* Set this bit if the algorithm provided is hardware accelerated but + * not available to userspace via instruction set or so. + */ +#define CRYPTO_ALG_KERN_DRIVER_ONLY 0x00001000 + /* * Transform masks and values (for crt_flags). */ -- cgit v1.2.3-70-g09d2 From e7a2577a410a066ae409f805618f7e84748a537d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 9 Jan 2012 10:40:49 +0100 Subject: crypto: ixp4xx - convert GFP_KERNEL to GFP_ATOMIC The function is called with locks held and thus should not use GFP_KERNEL. The semantic patch that makes this report is available in scripts/coccinelle/locks/call_kern.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Julia Lawall Signed-off-by: Herbert Xu --- drivers/crypto/ixp4xx_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index a82c11af9f4..0053d7ebb5c 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c @@ -265,7 +265,7 @@ static int setup_crypt_desc(void) BUILD_BUG_ON(sizeof(struct crypt_ctl) != 64); crypt_virt = dma_alloc_coherent(dev, NPE_QLEN * sizeof(struct crypt_ctl), - &crypt_phys, GFP_KERNEL); + &crypt_phys, GFP_ATOMIC); if (!crypt_virt) return -ENOMEM; memset(crypt_virt, 0, NPE_QLEN * sizeof(struct crypt_ctl)); -- cgit v1.2.3-70-g09d2 From e863f9ccc7658883be7b42eb63851aef9da7630c Mon Sep 17 00:00:00 2001 From: Hemant Agrawal Date: Mon, 9 Jan 2012 18:26:44 -0600 Subject: crypto: caam - add sha224 and sha384 variants to existing AEAD algorithms Signed-off-by: Hemant Agrawal Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 115 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index e9acadbb1d3..4cd2d84a2a1 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1843,6 +1843,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(aes))", + .driver_name = "authenc-hmac-sha224-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(aes))", .driver_name = "authenc-hmac-sha256-cbc-aes-caam", @@ -1863,6 +1882,26 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(aes))", + .driver_name = "authenc-hmac-sha384-cbc-aes-caam", + .blocksize = AES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = AES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, + { .name = "authenc(hmac(sha512),cbc(aes))", .driver_name = "authenc-hmac-sha512-cbc-aes-caam", @@ -1921,6 +1960,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha224-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(des3_ede))", .driver_name = "authenc-hmac-sha256-cbc-des3_ede-caam", @@ -1941,6 +1999,25 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(des3_ede))", + .driver_name = "authenc-hmac-sha384-cbc-des3_ede-caam", + .blocksize = DES3_EDE_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES3_EDE_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha512),cbc(des3_ede))", .driver_name = "authenc-hmac-sha512-cbc-des3_ede-caam", @@ -1999,6 +2076,25 @@ static struct caam_alg_template driver_algs[] = { .class2_alg_type = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha224),cbc(des))", + .driver_name = "authenc-hmac-sha224-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA224_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA224 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha256),cbc(des))", .driver_name = "authenc-hmac-sha256-cbc-des-caam", @@ -2019,6 +2115,25 @@ static struct caam_alg_template driver_algs[] = { OP_ALG_AAI_HMAC_PRECOMP, .alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC, }, + { + .name = "authenc(hmac(sha384),cbc(des))", + .driver_name = "authenc-hmac-sha384-cbc-des-caam", + .blocksize = DES_BLOCK_SIZE, + .template_aead = { + .setkey = aead_setkey, + .setauthsize = aead_setauthsize, + .encrypt = aead_encrypt, + .decrypt = aead_decrypt, + .givencrypt = aead_givencrypt, + .geniv = "", + .ivsize = DES_BLOCK_SIZE, + .maxauthsize = SHA384_DIGEST_SIZE, + }, + .class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC, + .class2_alg_type = OP_ALG_ALGSEL_SHA384 | + OP_ALG_AAI_HMAC_PRECOMP, + .alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC, + }, { .name = "authenc(hmac(sha512),cbc(des))", .driver_name = "authenc-hmac-sha512-cbc-des-caam", -- cgit v1.2.3-70-g09d2 From 0113529f37bcd17399403c68736b8ba59c7397b7 Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Mon, 9 Jan 2012 18:26:49 -0600 Subject: crypto: caam - be less noisy on startup sha224 and 384 support extends caam noise to 21 lines. Do the same as commit 5b859b6 "crypto: talitos - be less noisy on startup", but for caam, and display: caam ffe300000.crypto: fsl,sec-v4.0 algorithms registered in /proc/crypto Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index 4cd2d84a2a1..534a36469d5 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -2401,12 +2401,12 @@ static int __init caam_algapi_init(void) dev_warn(ctrldev, "%s alg registration failed\n", t_alg->crypto_alg.cra_driver_name); kfree(t_alg); - } else { + } else list_add_tail(&t_alg->entry, &priv->alg_list); - dev_info(ctrldev, "%s\n", - t_alg->crypto_alg.cra_driver_name); - } } + if (!list_empty(&priv->alg_list)) + dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n", + (char *)of_get_property(dev_node, "compatible", NULL)); return err; } -- cgit v1.2.3-70-g09d2 From c1762a3fe196483981f91b926f5f6ee18af757f2 Mon Sep 17 00:00:00 2001 From: Thirumalai Pachamuthu Date: Thu, 12 Jan 2012 18:21:39 +0530 Subject: ath6kl: Add support for uAPSD * A new APSD power save queue is added in the station structure. * When a station has APSD capability and goes to power save, the frame designated to the station will be buffered in APSD queue. * When the host receives a frame which the firmware marked as trigger, host delivers the buffered frame from the APSD power save queue. Number of frames to deliver is decided by MAX SP length. * When a station moves from sleep to awake state, all frames buffered in APSD power save queue are sent to the firmware. * When a station is disconnected, all frames bufferes in APSD power save queue are dropped. * When the host queues the first frame to the APSD queue or removes the last frame from the APSD queue, it is indicated to the firmware using WMI_AP_APSD_BUFFERED_TRAFFIC_CMD. kvalo: fix buggy handling of sks queues, made it more obvious the user priority when wmm is disabled, remove unneed else block and combined some variable declarations Signed-off-by: Thirumalai Pachamuthu Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 6 + drivers/net/wireless/ath/ath6kl/core.h | 10 +- drivers/net/wireless/ath/ath6kl/main.c | 9 +- drivers/net/wireless/ath/ath6kl/txrx.c | 249 ++++++++++++++++++++++++----- drivers/net/wireless/ath/ath6kl/wmi.c | 62 ++++++- drivers/net/wireless/ath/ath6kl/wmi.h | 41 ++++- 6 files changed, 324 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1a98c9256c6..a13ecec0070 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2253,6 +2253,11 @@ static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev, p.dot11_auth_mode = vif->dot11_auth_mode; p.ch = cpu_to_le16(vif->next_chan); + /* Enable uAPSD support by default */ + res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true); + if (res < 0) + return res; + if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) { p.nw_subtype = SUBTYPE_P2PGO; } else { @@ -2740,6 +2745,7 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { spin_lock_init(&ar->sta_list[ctr].psq_lock); skb_queue_head_init(&ar->sta_list[ctr].psq); + skb_queue_head_init(&ar->sta_list[ctr].apsdq); } skb_queue_head_init(&ar->mcastpsq); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index f4da5e19a36..ba3953918e4 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -44,6 +44,10 @@ #define ATH6KL_MAX_ENDPOINTS 4 #define MAX_NODE_NUM 15 +#define ATH6KL_APSD_ALL_FRAME 0xFFFF +#define ATH6KL_APSD_NUM_OF_AC 0x4 +#define ATH6KL_APSD_FRAME_MASK 0xF + /* Extra bytes for htc header alignment */ #define ATH6KL_HTC_ALIGN_BYTES 3 @@ -146,6 +150,8 @@ struct ath6kl_fw_ie { #define STA_PS_AWAKE BIT(0) #define STA_PS_SLEEP BIT(1) #define STA_PS_POLLED BIT(2) +#define STA_PS_APSD_TRIGGER BIT(3) +#define STA_PS_APSD_EOSP BIT(4) /* HTC TX packet tagging definitions */ #define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED @@ -282,6 +288,8 @@ struct ath6kl_sta { u8 wpa_ie[ATH6KL_MAX_IE]; struct sk_buff_head psq; spinlock_t psq_lock; + u8 apsd_info; + struct sk_buff_head apsdq; }; struct ath6kl_version { @@ -714,7 +722,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel); void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info); + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info); void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, u8 assoc_resp_len, u8 *assoc_info, u16 prot_reason_status); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 4c26572214c..53f97db4a7a 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -53,7 +53,8 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) } static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - size_t ielen, u8 keymgmt, u8 ucipher, u8 auth) + size_t ielen, u8 keymgmt, u8 ucipher, u8 auth, + u8 apsd_info) { struct ath6kl_sta *sta; u8 free_slot; @@ -68,6 +69,7 @@ static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, sta->keymgmt = keymgmt; sta->ucipher = ucipher; sta->auth = auth; + sta->apsd_info = apsd_info; ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); @@ -80,6 +82,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) /* empty the queued pkts in the PS queue if any */ spin_lock_bh(&sta->psq_lock); skb_queue_purge(&sta->psq); + skb_queue_purge(&sta->apsdq); spin_unlock_bh(&sta->psq_lock); memset(&ar->ap_stats.sta[sta->aid - 1], 0, @@ -425,7 +428,7 @@ void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel) void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, - u8 assoc_req_len, u8 *assoc_info) + u8 assoc_req_len, u8 *assoc_info, u8 apsd_info) { struct ath6kl *ar = vif->ar; u8 *ies = NULL, *wpa_ie = NULL, *pos; @@ -483,7 +486,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, wpa_ie ? 2 + wpa_ie[1] : 0, - keymgmt, ucipher, auth); + keymgmt, ucipher, auth, apsd_info); /* send event to application */ memset(&sinfo, 0, sizeof(sinfo)); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index fcea82479cd..91bbc1ffa49 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -77,12 +77,120 @@ static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, return ar->node_map[ep_map].ep_id; } +static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty = false; + struct ethhdr *datap = (struct ethhdr *) skb->data; + u8 up, traffic_class, *ip_hdr; + u16 ether_type; + struct ath6kl_llc_snap_hdr *llc_hdr; + + if (conn->sta_flags & STA_PS_APSD_TRIGGER) { + /* + * This tx is because of a uAPSD trigger, determine + * more and EOSP bit. Set EOSP if queue is empty + * or sufficient frames are delivered for this trigger. + */ + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->apsdq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + else if (conn->sta_flags & STA_PS_APSD_EOSP) + *flags |= WMI_DATA_HDR_FLAGS_EOSP; + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + spin_unlock_bh(&conn->psq_lock); + return false; + } else if (!conn->apsd_info) + return false; + + if (test_bit(WMM_ENABLED, &vif->flags)) { + ether_type = be16_to_cpu(datap->h_proto); + if (is_ethertype(ether_type)) { + /* packet is in DIX format */ + ip_hdr = (u8 *)(datap + 1); + } else { + /* packet is in 802.3 format */ + llc_hdr = (struct ath6kl_llc_snap_hdr *) + (datap + 1); + ether_type = be16_to_cpu(llc_hdr->eth_type); + ip_hdr = (u8 *)(llc_hdr + 1); + } + + if (ether_type == IP_ETHERTYPE) + up = ath6kl_wmi_determine_user_priority( + ip_hdr, 0); + } else { + up = 0; + } + + traffic_class = ath6kl_wmi_get_traffic_class(up); + + if ((conn->apsd_info & (1 << traffic_class)) == 0) + return false; + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + skb_queue_tail(&conn->apsdq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this STA + */ + if (is_apsdq_empty) { + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1, 0); + } + *flags |= WMI_DATA_HDR_FLAGS_UAPSD; + + return true; +} + +static bool ath6kl_process_psq(struct ath6kl_sta *conn, + struct ath6kl_vif *vif, + struct sk_buff *skb, + u32 *flags) +{ + bool is_psq_empty = false; + struct ath6kl *ar = vif->ar; + + if (conn->sta_flags & STA_PS_POLLED) { + spin_lock_bh(&conn->psq_lock); + if (!skb_queue_empty(&conn->psq)) + *flags |= WMI_DATA_HDR_FLAGS_MORE; + spin_unlock_bh(&conn->psq_lock); + return false; + } + + /* Queue the frames if the STA is sleeping */ + spin_lock_bh(&conn->psq_lock); + is_psq_empty = skb_queue_empty(&conn->psq); + skb_queue_tail(&conn->psq, skb); + spin_unlock_bh(&conn->psq_lock); + + /* + * If this is the first pkt getting queued + * for this STA, update the PVB for this + * STA. + */ + if (is_psq_empty) + ath6kl_wmi_set_pvb_cmd(ar->wmi, + vif->fw_vif_idx, + conn->aid, 1); + return true; +} + static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, - bool *more_data) + u32 *flags) { struct ethhdr *datap = (struct ethhdr *) skb->data; struct ath6kl_sta *conn = NULL; - bool ps_queued = false, is_psq_empty = false; + bool ps_queued = false; struct ath6kl *ar = vif->ar; if (is_multicast_ether_addr(datap->h_dest)) { @@ -128,7 +236,7 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, */ spin_lock_bh(&ar->mcastpsq_lock); if (!skb_queue_empty(&ar->mcastpsq)) - *more_data = true; + *flags |= WMI_DATA_HDR_FLAGS_MORE; spin_unlock_bh(&ar->mcastpsq_lock); } } @@ -142,37 +250,13 @@ static bool ath6kl_powersave_ap(struct ath6kl_vif *vif, struct sk_buff *skb, } if (conn->sta_flags & STA_PS_SLEEP) { - if (!(conn->sta_flags & STA_PS_POLLED)) { - /* Queue the frames if the STA is sleeping */ - spin_lock_bh(&conn->psq_lock); - is_psq_empty = skb_queue_empty(&conn->psq); - skb_queue_tail(&conn->psq, skb); - spin_unlock_bh(&conn->psq_lock); - - /* - * If this is the first pkt getting queued - * for this STA, update the PVB for this - * STA. - */ - if (is_psq_empty) - ath6kl_wmi_set_pvb_cmd(ar->wmi, - vif->fw_vif_idx, - conn->aid, 1); - - ps_queued = true; - } else { - /* - * This tx is because of a PsPoll. - * Determine if MoreData bit has to be set. - */ - spin_lock_bh(&conn->psq_lock); - if (!skb_queue_empty(&conn->psq)) - *more_data = true; - spin_unlock_bh(&conn->psq_lock); - } + ps_queued = ath6kl_process_uapsdq(conn, + vif, skb, flags); + if (!(*flags & WMI_DATA_HDR_FLAGS_UAPSD)) + ps_queued = ath6kl_process_psq(conn, + vif, skb, flags); } } - return ps_queued; } @@ -242,12 +326,13 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) u32 map_no = 0; u16 htc_tag = ATH6KL_DATA_PKT_TAG; u8 ac = 99 ; /* initialize to unmapped ac */ - bool chk_adhoc_ps_mapping = false, more_data = false; + bool chk_adhoc_ps_mapping = false; int ret; struct wmi_tx_meta_v2 meta_v2; void *meta; u8 csum_start = 0, csum_dest = 0, csum = skb->ip_summed; u8 meta_ver = 0; + u32 flags = 0; ath6kl_dbg(ATH6KL_DBG_WLAN_TX, "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__, @@ -264,7 +349,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) /* AP mode Power saving processing */ if (vif->nw_type == AP_NETWORK) { - if (ath6kl_powersave_ap(vif, skb, &more_data)) + if (ath6kl_powersave_ap(vif, skb, &flags)) return 0; } @@ -308,7 +393,7 @@ int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev) } ret = ath6kl_wmi_data_hdr_add(ar->wmi, skb, - DATA_MSGTYPE, more_data, 0, + DATA_MSGTYPE, flags, 0, meta_ver, meta, vif->fw_vif_idx); @@ -1093,6 +1178,76 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, return is_queued; } +static void ath6kl_uapsd_trigger_frame_rx(struct ath6kl_vif *vif, + struct ath6kl_sta *conn) +{ + struct ath6kl *ar = vif->ar; + bool is_apsdq_empty, is_apsdq_empty_at_start; + u32 num_frames_to_deliver, flags; + struct sk_buff *skb = NULL; + + /* + * If the APSD q for this STA is not empty, dequeue and + * send a pkt from the head of the q. Also update the + * More data bit in the WMI_DATA_HDR if there are + * more pkts for this STA in the APSD q. + * If there are no more pkts for this STA, + * update the APSD bitmap for this STA. + */ + + num_frames_to_deliver = (conn->apsd_info >> ATH6KL_APSD_NUM_OF_AC) & + ATH6KL_APSD_FRAME_MASK; + /* + * Number of frames to send in a service period is + * indicated by the station + * in the QOS_INFO of the association request + * If it is zero, send all frames + */ + if (!num_frames_to_deliver) + num_frames_to_deliver = ATH6KL_APSD_ALL_FRAME; + + spin_lock_bh(&conn->psq_lock); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + is_apsdq_empty_at_start = is_apsdq_empty; + + while ((!is_apsdq_empty) && (num_frames_to_deliver)) { + + spin_lock_bh(&conn->psq_lock); + skb = skb_dequeue(&conn->apsdq); + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + spin_unlock_bh(&conn->psq_lock); + + /* + * Set the STA flag to Trigger delivery, + * so that the frame will go out + */ + conn->sta_flags |= STA_PS_APSD_TRIGGER; + num_frames_to_deliver--; + + /* Last frame in the service period, set EOSP or queue empty */ + if ((is_apsdq_empty) || (!num_frames_to_deliver)) + conn->sta_flags |= STA_PS_APSD_EOSP; + + ath6kl_data_tx(skb, vif->ndev); + conn->sta_flags &= ~(STA_PS_APSD_TRIGGER); + conn->sta_flags &= ~(STA_PS_APSD_EOSP); + } + + if (is_apsdq_empty) { + if (is_apsdq_empty_at_start) + flags = WMI_AP_APSD_NO_DELIVERY_FRAMES; + else + flags = 0; + + ath6kl_wmi_set_apsd_bfrd_traf(ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, flags); + } + + return; +} + void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) { struct ath6kl *ar = target->dev->ar; @@ -1104,6 +1259,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) int status = packet->status; enum htc_endpoint_id ept = packet->endpoint; bool is_amsdu, prev_ps, ps_state = false; + bool trig_state = false; struct ath6kl_sta *conn = NULL; struct sk_buff *skb1 = NULL; struct ethhdr *datap = NULL; @@ -1197,6 +1353,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) WMI_DATA_HDR_PS_MASK); offset = sizeof(struct wmi_data_hdr); + trig_state = !!(le16_to_cpu(dhdr->info3) & WMI_DATA_HDR_TRIG); switch (meta_type) { case 0: @@ -1235,18 +1392,36 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) else conn->sta_flags &= ~STA_PS_SLEEP; + /* Accept trigger only when the station is in sleep */ + if ((conn->sta_flags & STA_PS_SLEEP) && trig_state) + ath6kl_uapsd_trigger_frame_rx(vif, conn); + if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) { if (!(conn->sta_flags & STA_PS_SLEEP)) { struct sk_buff *skbuff = NULL; + bool is_apsdq_empty; spin_lock_bh(&conn->psq_lock); - while ((skbuff = skb_dequeue(&conn->psq)) - != NULL) { + while ((skbuff = skb_dequeue(&conn->psq))) { + spin_unlock_bh(&conn->psq_lock); + ath6kl_data_tx(skbuff, vif->ndev); + spin_lock_bh(&conn->psq_lock); + } + + is_apsdq_empty = skb_queue_empty(&conn->apsdq); + while ((skbuff = skb_dequeue(&conn->apsdq))) { spin_unlock_bh(&conn->psq_lock); ath6kl_data_tx(skbuff, vif->ndev); spin_lock_bh(&conn->psq_lock); } spin_unlock_bh(&conn->psq_lock); + + if (!is_apsdq_empty) + ath6kl_wmi_set_apsd_bfrd_traf( + ar->wmi, + vif->fw_vif_idx, + conn->aid, 0, 0); + /* Clear the PVB for this STA */ ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 08fbd9a9be4..c2420f886ed 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -180,7 +180,7 @@ static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb, } int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx) { @@ -204,17 +204,19 @@ int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT; data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT; - if (more_data) - data_hdr->info |= - WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT; + if (flags & WMI_DATA_HDR_FLAGS_MORE) + data_hdr->info |= WMI_DATA_HDR_MORE; - data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); - data_hdr->info3 = cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); + if (flags & WMI_DATA_HDR_FLAGS_EOSP) + data_hdr->info3 |= cpu_to_le16(WMI_DATA_HDR_EOSP); + + data_hdr->info2 |= cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT); + data_hdr->info3 |= cpu_to_le16(if_idx & WMI_DATA_HDR_IF_IDX_MASK); return 0; } -static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) { struct iphdr *ip_hdr = (struct iphdr *) pkt; u8 ip_pri; @@ -236,6 +238,11 @@ static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri) return ip_pri; } +u8 ath6kl_wmi_get_traffic_class(u8 user_priority) +{ + return up_to_ac[user_priority & 0x7]; +} + int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, u8 if_idx, struct sk_buff *skb, u32 layer2_priority, bool wmm_enabled, @@ -786,12 +793,14 @@ static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.apsd_info); + ath6kl_connect_ap_mode_sta( vif, ev->u.ap_sta.aid, ev->u.ap_sta.mac_addr, ev->u.ap_sta.keymgmt, le16_to_cpu(ev->u.ap_sta.cipher), ev->u.ap_sta.auth, ev->assoc_req_len, - ev->assoc_info + ev->beacon_ie_len); + ev->assoc_info + ev->beacon_ie_len, + ev->u.ap_sta.apsd_info); } return 0; } @@ -2993,6 +3002,43 @@ int ath6kl_wmi_ap_set_mlme(struct wmi *wmip, u8 if_idx, u8 cmd, const u8 *mac, NO_SYNC_WMIFLAG); } +/* This command will be used to enable/disable AP uAPSD feature */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable) +{ + struct wmi_ap_set_apsd_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_set_apsd_cmd *)skb->data; + cmd->enable = enable; + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_AP_SET_APSD_CMDID, + NO_SYNC_WMIFLAG); +} + +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, u8 if_idx, + u16 aid, u16 bitmap, u32 flags) +{ + struct wmi_ap_apsd_buffered_traffic_cmd *cmd; + struct sk_buff *skb; + + skb = ath6kl_wmi_get_new_buf(sizeof(*cmd)); + if (!skb) + return -ENOMEM; + + cmd = (struct wmi_ap_apsd_buffered_traffic_cmd *)skb->data; + cmd->aid = cpu_to_le16(aid); + cmd->bitmap = cpu_to_le16(bitmap); + cmd->flags = cpu_to_le32(flags); + + return ath6kl_wmi_cmd_send(wmi, if_idx, skb, + WMI_AP_APSD_BUFFERED_TRAFFIC_CMDID, + NO_SYNC_WMIFLAG); +} + static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len, struct ath6kl_vif *vif) { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index eae0e4e065c..48e9d2641d6 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -149,8 +149,7 @@ enum wmi_msg_type { #define WMI_DATA_HDR_PS_MASK 0x1 #define WMI_DATA_HDR_PS_SHIFT 5 -#define WMI_DATA_HDR_MORE_MASK 0x1 -#define WMI_DATA_HDR_MORE_SHIFT 5 +#define WMI_DATA_HDR_MORE 0x20 enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_802_3 = 0, @@ -160,6 +159,13 @@ enum wmi_data_hdr_data_type { WMI_DATA_HDR_DATA_TYPE_ACL, }; +/* Bitmap of data header flags */ +enum wmi_data_hdr_flags { + WMI_DATA_HDR_FLAGS_MORE = 0x1, + WMI_DATA_HDR_FLAGS_EOSP = 0x2, + WMI_DATA_HDR_FLAGS_UAPSD = 0x4, +}; + #define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 #define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 @@ -173,8 +179,12 @@ enum wmi_data_hdr_data_type { #define WMI_DATA_HDR_META_MASK 0x7 #define WMI_DATA_HDR_META_SHIFT 13 +/* Macros for operating on WMI_DATA_HDR (info3) field */ #define WMI_DATA_HDR_IF_IDX_MASK 0xF +#define WMI_DATA_HDR_TRIG 0x10 +#define WMI_DATA_HDR_EOSP 0x10 + struct wmi_data_hdr { s8 rssi; @@ -203,7 +213,8 @@ struct wmi_data_hdr { /* * usage of info3, 16-bit: * b3:b0 - Interface index - * b15:b4 - Reserved + * b4 - uAPSD trigger in rx & EOSP in tx + * b15:b5 - Reserved */ __le16 info3; } __packed; @@ -2116,6 +2127,19 @@ struct wmi_rx_frame_format_cmd { } __packed; /* AP mode events */ +struct wmi_ap_set_apsd_cmd { + u8 enable; +} __packed; + +enum wmi_ap_apsd_buffered_traffic_flags { + WMI_AP_APSD_NO_DELIVERY_FRAMES = 0x1, +}; + +struct wmi_ap_apsd_buffered_traffic_cmd { + __le16 aid; + __le16 bitmap; + __le32 flags; +} __packed; /* WMI_PS_POLL_EVENT */ struct wmi_pspoll_event { @@ -2332,7 +2356,7 @@ enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi); void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id); int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb); int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb, - u8 msg_type, bool more_data, + u8 msg_type, u32 flags, enum wmi_data_hdr_data_type data_type, u8 meta_ver, void *tx_meta_info, u8 if_idx); @@ -2446,7 +2470,16 @@ int ath6kl_wmi_set_roam_mode_cmd(struct wmi *wmi, enum wmi_roam_mode mode); int ath6kl_wmi_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, bool mc_all_on); int ath6kl_wmi_add_del_mcast_filter_cmd(struct wmi *wmi, u8 if_idx, u8 *filter, bool add_filter); +/* AP mode uAPSD */ +int ath6kl_wmi_ap_set_apsd(struct wmi *wmi, u8 if_idx, u8 enable); + +int ath6kl_wmi_set_apsd_bfrd_traf(struct wmi *wmi, + u8 if_idx, u16 aid, + u16 bitmap, u32 flags); + +u8 ath6kl_wmi_get_traffic_class(u8 user_priority); +u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri); /* AP mode */ int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, u8 if_idx, struct wmi_connect_cmd *p); -- cgit v1.2.3-70-g09d2 From e80ec84d9352419a7c0482edfbf1b96eaa4c8b95 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Thu, 12 Jan 2012 15:01:48 +0530 Subject: ath6kl: Remove useless initialization in ath6kl_read_fwlogs() ath6kl_read_fwlogs() assigns the value zero to the variable 'ret' at the time of declaration. Later, return value of ath6kl_diag_read32() repalces the init value. Hence removing useless zero assignment. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 53f97db4a7a..0a6d6e2be6e 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -255,7 +255,7 @@ int ath6kl_read_fwlogs(struct ath6kl *ar) struct ath6kl_dbglog_hdr debug_hdr; struct ath6kl_dbglog_buf debug_buf; u32 address, length, dropped, firstbuf, debug_hdr_addr; - int ret = 0, loop; + int ret, loop; u8 *buf; buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL); -- cgit v1.2.3-70-g09d2 From 210762268466634ddbfaddb48fdf5181ce4b5f2d Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 27 Aug 2011 18:53:03 +0200 Subject: firewire: move fw_device reference counting from drivers to core fw_unit device drivers invariably need to talk to the fw_unit's parent (an fw_device) and grandparent (an fw_card). firewire-core already maintains an fw_card reference for the entire lifetime of an fw_device. Likewise, let firewire-core maintain an fw_device reference for the entire lifetime of an fw_unit so that fw_unit drivers don't have to. Signed-off-by: Stefan Richter --- drivers/firewire/core-device.c | 2 ++ drivers/firewire/core.h | 13 +++++++++++++ include/linux/firewire.h | 12 ------------ sound/firewire/isight.c | 4 +--- sound/firewire/speakers.c | 4 ---- 5 files changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index f3b890da1e8..4c6c7d8cdaf 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -641,6 +641,7 @@ static void fw_unit_release(struct device *dev) { struct fw_unit *unit = fw_unit(dev); + fw_device_put(fw_parent_device(unit)); kfree(unit); } @@ -692,6 +693,7 @@ static void create_units(struct fw_device *device) if (device_register(&unit->device) < 0) goto skip_unit; + fw_device_get(device); continue; skip_unit: diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index b45be576752..b5b34952cf1 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -1,6 +1,7 @@ #ifndef _FIREWIRE_CORE_H #define _FIREWIRE_CORE_H +#include #include #include #include @@ -141,6 +142,18 @@ extern struct rw_semaphore fw_device_rwsem; extern struct idr fw_device_idr; extern int fw_cdev_major; +static inline struct fw_device *fw_device_get(struct fw_device *device) +{ + get_device(&device->device); + + return device; +} + +static inline void fw_device_put(struct fw_device *device) +{ + put_device(&device->device); +} + struct fw_device *fw_device_get_by_devt(dev_t devt); int fw_device_set_broadcast_channel(struct device *dev, void *gen); void fw_node_event(struct fw_card *card, struct fw_node *node, int event); diff --git a/include/linux/firewire.h b/include/linux/firewire.h index 84ccf8e04fa..6f1d7385e05 100644 --- a/include/linux/firewire.h +++ b/include/linux/firewire.h @@ -203,18 +203,6 @@ static inline int fw_device_is_shutdown(struct fw_device *device) return atomic_read(&device->state) == FW_DEVICE_SHUTDOWN; } -static inline struct fw_device *fw_device_get(struct fw_device *device) -{ - get_device(&device->device); - - return device; -} - -static inline void fw_device_put(struct fw_device *device) -{ - put_device(&device->device); -} - int fw_device_enable_phys_dma(struct fw_device *device); /* diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c index 440030818db..412b65f740d 100644 --- a/sound/firewire/isight.c +++ b/sound/firewire/isight.c @@ -612,7 +612,6 @@ static void isight_card_free(struct snd_card *card) fw_iso_resources_destroy(&isight->resources); fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); } @@ -645,7 +644,7 @@ static int isight_probe(struct device *unit_dev) isight->card = card; mutex_init(&isight->mutex); isight->unit = fw_unit_get(unit); - isight->device = fw_device_get(fw_dev); + isight->device = fw_dev; isight->audio_base = get_unit_base(unit); if (!isight->audio_base) { dev_err(&unit->device, "audio unit base not found\n"); @@ -682,7 +681,6 @@ static int isight_probe(struct device *unit_dev) err_unit: fw_unit_put(isight->unit); - fw_device_put(isight->device); mutex_destroy(&isight->mutex); error: snd_card_free(card); diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c index 3fc257da180..18b9b5607f3 100644 --- a/sound/firewire/speakers.c +++ b/sound/firewire/speakers.c @@ -656,12 +656,10 @@ static u32 fwspk_read_firmware_version(struct fw_unit *unit) static void fwspk_card_free(struct snd_card *card) { struct fwspk *fwspk = card->private_data; - struct fw_device *dev = fw_parent_device(fwspk->unit); amdtp_out_stream_destroy(&fwspk->stream); cmp_connection_destroy(&fwspk->connection); fw_unit_put(fwspk->unit); - fw_device_put(dev); mutex_destroy(&fwspk->mutex); } @@ -718,7 +716,6 @@ static int __devinit fwspk_probe(struct device *unit_dev) fwspk = card->private_data; fwspk->card = card; mutex_init(&fwspk->mutex); - fw_device_get(fw_dev); fwspk->unit = fw_unit_get(unit); fwspk->device_info = fwspk_detect(fw_dev); if (!fwspk->device_info) { @@ -767,7 +764,6 @@ err_connection: cmp_connection_destroy(&fwspk->connection); err_unit: fw_unit_put(fwspk->unit); - fw_device_put(fw_dev); mutex_destroy(&fwspk->mutex); error: snd_card_free(card); -- cgit v1.2.3-70-g09d2 From 64d2172019dcfe46508593c561c9906de95df567 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 20 Dec 2011 21:32:46 +0100 Subject: firewire: ohci: use dev_printk API All messages are uniformly prefixed by driver name and device name now. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 185 +++++++++++++++++++++++++++--------------------- 1 file changed, 106 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 6628feaa762..68b3c1b635f 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -345,7 +345,7 @@ MODULE_PARM_DESC(debug, "Verbose logging (default = 0" ", busReset events = " __stringify(OHCI_PARAM_DEBUG_BUSRESETS) ", or a combination, or all = -1)"); -static void log_irqs(u32 evt) +static void log_irqs(struct fw_ohci *ohci, u32 evt) { if (likely(!(param_debug & (OHCI_PARAM_DEBUG_IRQS | OHCI_PARAM_DEBUG_BUSRESETS)))) @@ -355,7 +355,8 @@ static void log_irqs(u32 evt) !(evt & OHCI1394_busReset)) return; - fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, + dev_notice(ohci->card.device, + "IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, evt & OHCI1394_selfIDComplete ? " selfID" : "", evt & OHCI1394_RQPkt ? " AR_req" : "", evt & OHCI1394_RSPkt ? " AR_resp" : "", @@ -394,24 +395,29 @@ static char _p(u32 *s, int shift) return port[*s >> shift & 3]; } -static void log_selfids(int node_id, int generation, int self_id_count, u32 *s) +static void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count) { + u32 *s; + if (likely(!(param_debug & OHCI_PARAM_DEBUG_SELFIDS))) return; - fw_notify("%d selfIDs, generation %d, local node ID %04x\n", - self_id_count, generation, node_id); + dev_notice(ohci->card.device, + "%d selfIDs, generation %d, local node ID %04x\n", + self_id_count, generation, ohci->node_id); - for (; self_id_count--; ++s) + for (s = ohci->self_id_buffer; self_id_count--; ++s) if ((*s & 1 << 23) == 0) - fw_notify("selfID 0: %08x, phy %d [%c%c%c] " + dev_notice(ohci->card.device, + "selfID 0: %08x, phy %d [%c%c%c] " "%s gc=%d %s %s%s%s\n", *s, *s >> 24 & 63, _p(s, 6), _p(s, 4), _p(s, 2), speed[*s >> 14 & 3], *s >> 16 & 63, power[*s >> 8 & 7], *s >> 22 & 1 ? "L" : "", *s >> 11 & 1 ? "c" : "", *s & 2 ? "i" : ""); else - fw_notify("selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n", + dev_notice(ohci->card.device, + "selfID n: %08x, phy %d [%c%c%c%c%c%c%c%c]\n", *s, *s >> 24 & 63, _p(s, 16), _p(s, 14), _p(s, 12), _p(s, 10), _p(s, 8), _p(s, 6), _p(s, 4), _p(s, 2)); @@ -447,7 +453,8 @@ static const char *tcodes[] = { [0xe] = "link internal", [0xf] = "-reserved-", }; -static void log_ar_at_event(char dir, int speed, u32 *header, int evt) +static void log_ar_at_event(struct fw_ohci *ohci, + char dir, int speed, u32 *header, int evt) { int tcode = header[0] >> 4 & 0xf; char specific[12]; @@ -459,8 +466,9 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) evt = 0x1f; if (evt == OHCI1394_evt_bus_reset) { - fw_notify("A%c evt_bus_reset, generation %d\n", - dir, (header[2] >> 16) & 0xff); + dev_notice(ohci->card.device, + "A%c evt_bus_reset, generation %d\n", + dir, (header[2] >> 16) & 0xff); return; } @@ -479,36 +487,41 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) switch (tcode) { case 0xa: - fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]); + dev_notice(ohci->card.device, + "A%c %s, %s\n", + dir, evts[evt], tcodes[tcode]); break; case 0xe: - fw_notify("A%c %s, PHY %08x %08x\n", - dir, evts[evt], header[1], header[2]); + dev_notice(ohci->card.device, + "A%c %s, PHY %08x %08x\n", + dir, evts[evt], header[1], header[2]); break; case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: - fw_notify("A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s, %04x%08x%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], header[1] & 0xffff, header[2], specific); + dev_notice(ohci->card.device, + "A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s, %04x%08x%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], header[1] & 0xffff, header[2], specific); break; default: - fw_notify("A%c spd %x tl %02x, " - "%04x -> %04x, %s, " - "%s%s\n", - dir, speed, header[0] >> 10 & 0x3f, - header[1] >> 16, header[0] >> 16, evts[evt], - tcodes[tcode], specific); + dev_notice(ohci->card.device, + "A%c spd %x tl %02x, " + "%04x -> %04x, %s, " + "%s%s\n", + dir, speed, header[0] >> 10 & 0x3f, + header[1] >> 16, header[0] >> 16, evts[evt], + tcodes[tcode], specific); } } #else #define param_debug 0 -static inline void log_irqs(u32 evt) {} -static inline void log_selfids(int node_id, int generation, int self_id_count, u32 *s) {} -static inline void log_ar_at_event(char dir, int speed, u32 *header, int evt) {} +static inline void log_irqs(struct fw_ohci *ohci, u32 evt) {} +static inline void log_selfids(struct fw_ohci *ohci, int generation, int self_id_count) {} +static inline void log_ar_at_event(struct fw_ohci *ohci, char dir, int speed, u32 *header, int evt) {} #endif /* CONFIG_FIREWIRE_OHCI_DEBUG */ @@ -555,7 +568,7 @@ static int read_phy_reg(struct fw_ohci *ohci, int addr) if (i >= 3) msleep(1); } - fw_error("failed to read phy reg\n"); + dev_err(ohci->card.device, "failed to read phy reg\n"); return -EBUSY; } @@ -577,7 +590,7 @@ static int write_phy_reg(const struct fw_ohci *ohci, int addr, u32 val) if (i >= 3) msleep(1); } - fw_error("failed to write phy reg\n"); + dev_err(ohci->card.device, "failed to write phy reg\n"); return -EBUSY; } @@ -676,11 +689,14 @@ static void ar_context_release(struct ar_context *ctx) static void ar_context_abort(struct ar_context *ctx, const char *error_msg) { - if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { - reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); - flush_writes(ctx->ohci); + struct fw_ohci *ohci = ctx->ohci; - fw_error("AR error: %s; DMA stopped\n", error_msg); + if (reg_read(ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { + reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); + flush_writes(ohci); + + dev_err(ohci->card.device, "AR error: %s; DMA stopped\n", + error_msg); } /* FIXME: restart? */ } @@ -850,7 +866,7 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) p.timestamp = status & 0xffff; p.generation = ohci->request_generation; - log_ar_at_event('R', p.speed, p.header, evt); + log_ar_at_event(ohci, 'R', p.speed, p.header, evt); /* * Several controllers, notably from NEC and VIA, forget to @@ -1222,21 +1238,22 @@ static void context_append(struct context *ctx, static void context_stop(struct context *ctx) { + struct fw_ohci *ohci = ctx->ohci; u32 reg; int i; - reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); + reg_write(ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); ctx->running = false; for (i = 0; i < 1000; i++) { - reg = reg_read(ctx->ohci, CONTROL_SET(ctx->regs)); + reg = reg_read(ohci, CONTROL_SET(ctx->regs)); if ((reg & CONTEXT_ACTIVE) == 0) return; if (i) udelay(10); } - fw_error("Error: DMA context still active (0x%08x)\n", reg); + dev_err(ohci->card.device, "DMA context still active (0x%08x)\n", reg); } struct driver_data { @@ -1416,7 +1433,7 @@ static int handle_at_packet(struct context *context, evt = le16_to_cpu(last->transfer_status) & 0x1f; packet->timestamp = le16_to_cpu(last->res_count); - log_ar_at_event('T', packet->speed, packet->header, evt); + log_ar_at_event(ohci, 'T', packet->speed, packet->header, evt); switch (evt) { case OHCI1394_evt_timeout: @@ -1545,7 +1562,7 @@ static void handle_local_lock(struct fw_ohci *ohci, goto out; } - fw_error("swap not done (CSR lock timeout)\n"); + dev_err(ohci->card.device, "swap not done (CSR lock timeout)\n"); fw_fill_response(&response, packet->header, RCODE_BUSY, NULL, 0); out: @@ -1621,11 +1638,13 @@ static void detect_dead_context(struct fw_ohci *ohci, ctl = reg_read(ohci, CONTROL_SET(regs)); if (ctl & CONTEXT_DEAD) { #ifdef CONFIG_FIREWIRE_OHCI_DEBUG - fw_error("DMA context %s has stopped, error code: %s\n", - name, evts[ctl & 0x1f]); + dev_err(ohci->card.device, + "DMA context %s has stopped, error code: %s\n", + name, evts[ctl & 0x1f]); #else - fw_error("DMA context %s has stopped, error code: %#x\n", - name, ctl & 0x1f); + dev_err(ohci->card.device, + "DMA context %s has stopped, error code: %#x\n", + name, ctl & 0x1f); #endif } } @@ -1777,7 +1796,8 @@ static int find_and_insert_self_id(struct fw_ohci *ohci, int self_id_count) reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { - fw_notify("node ID not valid, new bus reset in progress\n"); + dev_notice(ohci->card.device, + "node ID not valid, new bus reset in progress\n"); return -EBUSY; } self_id |= ((reg & 0x3f) << 24); /* phy ID */ @@ -1823,11 +1843,12 @@ static void bus_reset_work(struct work_struct *work) reg = reg_read(ohci, OHCI1394_NodeID); if (!(reg & OHCI1394_NodeID_idValid)) { - fw_notify("node ID not valid, new bus reset in progress\n"); + dev_notice(ohci->card.device, + "node ID not valid, new bus reset in progress\n"); return; } if ((reg & OHCI1394_NodeID_nodeNumber) == 63) { - fw_notify("malconfigured bus\n"); + dev_notice(ohci->card.device, "malconfigured bus\n"); return; } ohci->node_id = reg & (OHCI1394_NodeID_busNumber | @@ -1841,7 +1862,7 @@ static void bus_reset_work(struct work_struct *work) reg = reg_read(ohci, OHCI1394_SelfIDCount); if (reg & OHCI1394_SelfIDCount_selfIDError) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } /* @@ -1853,7 +1874,7 @@ static void bus_reset_work(struct work_struct *work) self_id_count = (reg >> 3) & 0xff; if (self_id_count > 252) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } @@ -1871,11 +1892,13 @@ static void bus_reset_work(struct work_struct *work) */ if (cond_le32_to_cpu(ohci->self_id_cpu[i]) == 0xffff008f) { - fw_notify("ignoring spurious self IDs\n"); + dev_notice(ohci->card.device, + "ignoring spurious self IDs\n"); self_id_count = j; break; } else { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, + "inconsistent self IDs\n"); return; } } @@ -1886,13 +1909,14 @@ static void bus_reset_work(struct work_struct *work) if (ohci->quirks & QUIRK_TI_SLLZ059) { self_id_count = find_and_insert_self_id(ohci, self_id_count); if (self_id_count < 0) { - fw_notify("could not construct local self ID\n"); + dev_notice(ohci->card.device, + "could not construct local self ID\n"); return; } } if (self_id_count == 0) { - fw_notify("inconsistent self IDs\n"); + dev_notice(ohci->card.device, "inconsistent self IDs\n"); return; } rmb(); @@ -1913,8 +1937,8 @@ static void bus_reset_work(struct work_struct *work) new_generation = (reg_read(ohci, OHCI1394_SelfIDCount) >> 16) & 0xff; if (new_generation != generation) { - fw_notify("recursive bus reset detected, " - "discarding self ids\n"); + dev_notice(ohci->card.device, + "new bus reset, discarding self ids\n"); return; } @@ -1985,8 +2009,7 @@ static void bus_reset_work(struct work_struct *work) dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, free_rom, free_rom_bus); - log_selfids(ohci->node_id, generation, - self_id_count, ohci->self_id_buffer); + log_selfids(ohci, generation, self_id_count); fw_core_handle_bus_reset(&ohci->card, ohci->node_id, generation, self_id_count, ohci->self_id_buffer, @@ -2011,7 +2034,7 @@ static irqreturn_t irq_handler(int irq, void *data) */ reg_write(ohci, OHCI1394_IntEventClear, event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); - log_irqs(event); + log_irqs(ohci, event); if (event & OHCI1394_selfIDComplete) queue_work(fw_workqueue, &ohci->bus_reset_work); @@ -2053,8 +2076,8 @@ static irqreturn_t irq_handler(int irq, void *data) } if (unlikely(event & OHCI1394_regAccessFail)) - fw_error("Register access failure - " - "please notify linux1394-devel@lists.sf.net\n"); + dev_err(ohci->card.device, + "register access failure - please notify linux1394-devel@lists.sf.net\n"); if (unlikely(event & OHCI1394_postedWriteErr)) { reg_read(ohci, OHCI1394_PostedWriteAddressHi); @@ -2062,12 +2085,13 @@ static irqreturn_t irq_handler(int irq, void *data) reg_write(ohci, OHCI1394_IntEventClear, OHCI1394_postedWriteErr); if (printk_ratelimit()) - fw_error("PCI posted write error\n"); + dev_err(ohci->card.device, "PCI posted write error\n"); } if (unlikely(event & OHCI1394_cycleTooLong)) { if (printk_ratelimit()) - fw_notify("isochronous cycle too long\n"); + dev_notice(ohci->card.device, + "isochronous cycle too long\n"); reg_write(ohci, OHCI1394_LinkControlSet, OHCI1394_LinkControl_cycleMaster); } @@ -2080,7 +2104,8 @@ static irqreturn_t irq_handler(int irq, void *data) * them at least two cycles later. (FIXME?) */ if (printk_ratelimit()) - fw_notify("isochronous cycle inconsistent\n"); + dev_notice(ohci->card.device, + "isochronous cycle inconsistent\n"); } if (unlikely(event & OHCI1394_unrecoverableError)) @@ -2207,7 +2232,7 @@ static int ohci_enable(struct fw_card *card, int i, ret; if (software_reset(ohci)) { - fw_error("Failed to reset ohci card.\n"); + dev_err(card->device, "failed to reset ohci card\n"); return -EBUSY; } @@ -2231,7 +2256,7 @@ static int ohci_enable(struct fw_card *card, } if (!lps) { - fw_error("Failed to set Link Power Status\n"); + dev_err(card->device, "failed to set Link Power Status\n"); return -EIO; } @@ -2240,7 +2265,7 @@ static int ohci_enable(struct fw_card *card, if (ret < 0) return ret; if (ret) - fw_notify("local TSB41BA3D phy\n"); + dev_notice(card->device, "local TSB41BA3D phy\n"); else ohci->quirks &= ~QUIRK_TI_SLLZ059; } @@ -2340,7 +2365,8 @@ static int ohci_enable(struct fw_card *card, if (request_irq(dev->irq, irq_handler, pci_dev_msi_enabled(dev) ? 0 : IRQF_SHARED, ohci_driver_name, ohci)) { - fw_error("Failed to allocate interrupt %d.\n", dev->irq); + dev_err(card->device, "failed to allocate interrupt %d\n", + dev->irq); pci_disable_msi(dev); if (config_rom) { @@ -2505,7 +2531,7 @@ static int ohci_cancel_packet(struct fw_card *card, struct fw_packet *packet) dma_unmap_single(ohci->card.device, packet->payload_bus, packet->payload_length, DMA_TO_DEVICE); - log_ar_at_event('T', packet->speed, packet->header, 0x20); + log_ar_at_event(ohci, 'T', packet->speed, packet->header, 0x20); driver_data->packet = NULL; packet->ack = RCODE_CANCELLED; packet->callback(packet, &ohci->card, packet->ack); @@ -3459,7 +3485,7 @@ static int __devinit pci_probe(struct pci_dev *dev, err = pci_enable_device(dev); if (err) { - fw_error("Failed to enable OHCI hardware\n"); + dev_err(&dev->dev, "failed to enable OHCI hardware\n"); goto fail_free; } @@ -3474,13 +3500,13 @@ static int __devinit pci_probe(struct pci_dev *dev, err = pci_request_region(dev, 0, ohci_driver_name); if (err) { - fw_error("MMIO resource unavailable\n"); + dev_err(&dev->dev, "MMIO resource unavailable\n"); goto fail_disable; } ohci->registers = pci_iomap(dev, 0, OHCI1394_REGISTER_SIZE); if (ohci->registers == NULL) { - fw_error("Failed to remap registers\n"); + dev_err(&dev->dev, "failed to remap registers\n"); err = -ENXIO; goto fail_iomem; } @@ -3569,9 +3595,10 @@ static int __devinit pci_probe(struct pci_dev *dev, goto fail_contexts; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; - fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " + dev_notice(&dev->dev, + "added OHCI v%x.%x device as card %d, " "%d IR + %d IT contexts, quirks 0x%x\n", - dev_name(&dev->dev), version >> 16, version & 0xff, + version >> 16, version & 0xff, ohci->card.index, ohci->n_ir, ohci->n_it, ohci->quirks); return 0; @@ -3600,7 +3627,7 @@ static int __devinit pci_probe(struct pci_dev *dev, pmac_ohci_off(dev); fail: if (err == -ENOMEM) - fw_error("Out of memory\n"); + dev_err(&dev->dev, "out of memory\n"); return err; } @@ -3644,7 +3671,7 @@ static void pci_remove(struct pci_dev *dev) kfree(ohci); pmac_ohci_off(dev); - fw_notify("Removed fw-ohci device.\n"); + dev_notice(&dev->dev, "removed fw-ohci device\n"); } #ifdef CONFIG_PM @@ -3658,12 +3685,12 @@ static int pci_suspend(struct pci_dev *dev, pm_message_t state) pci_disable_msi(dev); err = pci_save_state(dev); if (err) { - fw_error("pci_save_state failed\n"); + dev_err(&dev->dev, "pci_save_state failed\n"); return err; } err = pci_set_power_state(dev, pci_choose_state(dev, state)); if (err) - fw_error("pci_set_power_state failed with %d\n", err); + dev_err(&dev->dev, "pci_set_power_state failed with %d\n", err); pmac_ohci_off(dev); return 0; @@ -3679,7 +3706,7 @@ static int pci_resume(struct pci_dev *dev) pci_restore_state(dev); err = pci_enable_device(dev); if (err) { - fw_error("pci_enable_device failed\n"); + dev_err(&dev->dev, "pci_enable_device failed\n"); return err; } -- cgit v1.2.3-70-g09d2 From eba9ebaaa26d60e07bc0aea585c13bc1d5a728c1 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 20 Dec 2011 21:34:12 +0100 Subject: firewire: sbp2: use dev_printk API All messages are uniformly prefixed by driver name and device name now. Signed-off-by: Stefan Richter --- drivers/firewire/sbp2.c | 93 +++++++++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c index 68375bc3aef..32b3296a1c5 100644 --- a/drivers/firewire/sbp2.c +++ b/drivers/firewire/sbp2.c @@ -165,7 +165,6 @@ static void sbp2_queue_work(struct sbp2_logical_unit *lu, unsigned long delay) */ struct sbp2_target { struct fw_unit *unit; - const char *bus_id; struct list_head lu_list; u64 management_agent_address; @@ -181,11 +180,21 @@ struct sbp2_target { int blocked; /* ditto */ }; -static struct fw_device *target_device(struct sbp2_target *tgt) +static struct fw_device *target_parent_device(struct sbp2_target *tgt) { return fw_parent_device(tgt->unit); } +static const struct device *tgt_dev(const struct sbp2_target *tgt) +{ + return &tgt->unit->device; +} + +static const struct device *lu_dev(const struct sbp2_logical_unit *lu) +{ + return &lu->tgt->unit->device; +} + /* Impossible login_id, to detect logout attempt before successful login */ #define INVALID_LOGIN_ID 0x10000 @@ -430,7 +439,8 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, memcpy(status.data, payload + 8, length - 8); if (STATUS_GET_SOURCE(status) == 2 || STATUS_GET_SOURCE(status) == 3) { - fw_notify("non-orb related status write, not handled\n"); + dev_notice(lu_dev(lu), + "non-ORB related status write, not handled\n"); fw_send_response(card, request, RCODE_COMPLETE); return; } @@ -451,7 +461,7 @@ static void sbp2_status_write(struct fw_card *card, struct fw_request *request, orb->callback(orb, &status); kref_put(&orb->kref, free_orb); /* orb callback reference */ } else { - fw_error("status write for unknown orb\n"); + dev_err(lu_dev(lu), "status write for unknown ORB\n"); } fw_send_response(card, request, RCODE_COMPLETE); @@ -492,7 +502,7 @@ static void complete_transaction(struct fw_card *card, int rcode, static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, int node_id, int generation, u64 offset) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_pointer orb_pointer; unsigned long flags; @@ -513,7 +523,7 @@ static void sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, static int sbp2_cancel_orbs(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_orb *orb, *next; struct list_head list; unsigned long flags; @@ -552,7 +562,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, int generation, int function, int lun_or_login_id, void *response) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_management_orb *orb; unsigned int timeout; int retval = -ENOMEM; @@ -612,20 +622,20 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, retval = -EIO; if (sbp2_cancel_orbs(lu) == 0) { - fw_error("%s: orb reply timed out, rcode=0x%02x\n", - lu->tgt->bus_id, orb->base.rcode); + dev_err(lu_dev(lu), "ORB reply timed out, rcode 0x%02x\n", + orb->base.rcode); goto out; } if (orb->base.rcode != RCODE_COMPLETE) { - fw_error("%s: management write failed, rcode 0x%02x\n", - lu->tgt->bus_id, orb->base.rcode); + dev_err(lu_dev(lu), "management write failed, rcode 0x%02x\n", + orb->base.rcode); goto out; } if (STATUS_GET_RESPONSE(orb->status) != 0 || STATUS_GET_SBP_STATUS(orb->status) != 0) { - fw_error("%s: error status: %d:%d\n", lu->tgt->bus_id, + dev_err(lu_dev(lu), "error status: %d:%d\n", STATUS_GET_RESPONSE(orb->status), STATUS_GET_SBP_STATUS(orb->status)); goto out; @@ -648,7 +658,7 @@ static int sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, static void sbp2_agent_reset(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); __be32 d = 0; fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, @@ -665,7 +675,7 @@ static void complete_agent_reset_write_no_wait(struct fw_card *card, static void sbp2_agent_reset_no_wait(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct fw_transaction *t; static __be32 d; @@ -704,7 +714,7 @@ static inline void sbp2_allow_block(struct sbp2_logical_unit *lu) static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) { struct sbp2_target *tgt = lu->tgt; - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -728,7 +738,7 @@ static void sbp2_conditionally_block(struct sbp2_logical_unit *lu) static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) { struct sbp2_target *tgt = lu->tgt; - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -753,7 +763,7 @@ static void sbp2_conditionally_unblock(struct sbp2_logical_unit *lu) */ static void sbp2_unblock(struct sbp2_target *tgt) { - struct fw_card *card = target_device(tgt)->card; + struct fw_card *card = target_parent_device(tgt)->card; struct Scsi_Host *shost = container_of((void *)tgt, struct Scsi_Host, hostdata[0]); unsigned long flags; @@ -794,7 +804,7 @@ static int sbp2_lun2int(u16 lun) */ static void sbp2_set_busy_timeout(struct sbp2_logical_unit *lu) { - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); __be32 d = cpu_to_be32(SBP2_CYCLE_LIMIT | SBP2_RETRY_LIMIT); fw_run_transaction(device->card, TCODE_WRITE_QUADLET_REQUEST, @@ -809,7 +819,7 @@ static void sbp2_login(struct work_struct *work) struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); struct sbp2_target *tgt = lu->tgt; - struct fw_device *device = target_device(tgt); + struct fw_device *device = target_parent_device(tgt); struct Scsi_Host *shost; struct scsi_device *sdev; struct sbp2_login_response response; @@ -833,8 +843,8 @@ static void sbp2_login(struct work_struct *work) if (lu->retries++ < 5) { sbp2_queue_work(lu, DIV_ROUND_UP(HZ, 5)); } else { - fw_error("%s: failed to login to LUN %04x\n", - tgt->bus_id, lu->lun); + dev_err(tgt_dev(tgt), "failed to login to LUN %04x\n", + lu->lun); /* Let any waiting I/O fail from now on. */ sbp2_unblock(lu->tgt); } @@ -851,8 +861,8 @@ static void sbp2_login(struct work_struct *work) << 32) | be32_to_cpu(response.command_block_agent.low); lu->login_id = be32_to_cpu(response.misc) & 0xffff; - fw_notify("%s: logged in to LUN %04x (%d retries)\n", - tgt->bus_id, lu->lun, lu->retries); + dev_notice(tgt_dev(tgt), "logged in to LUN %04x (%d retries)\n", + lu->lun, lu->retries); /* set appropriate retry limit(s) in BUSY_TIMEOUT register */ sbp2_set_busy_timeout(lu); @@ -919,7 +929,7 @@ static void sbp2_reconnect(struct work_struct *work) struct sbp2_logical_unit *lu = container_of(work, struct sbp2_logical_unit, work.work); struct sbp2_target *tgt = lu->tgt; - struct fw_device *device = target_device(tgt); + struct fw_device *device = target_parent_device(tgt); int generation, node_id, local_node_id; if (fw_device_is_shutdown(device)) @@ -943,7 +953,7 @@ static void sbp2_reconnect(struct work_struct *work) smp_rmb(); /* get current card generation */ if (generation == device->card->generation || lu->retries++ >= 5) { - fw_error("%s: failed to reconnect\n", tgt->bus_id); + dev_err(tgt_dev(tgt), "failed to reconnect\n"); lu->retries = 0; PREPARE_DELAYED_WORK(&lu->work, sbp2_login); } @@ -957,8 +967,8 @@ static void sbp2_reconnect(struct work_struct *work) smp_wmb(); /* node IDs must not be older than generation */ lu->generation = generation; - fw_notify("%s: reconnected to LUN %04x (%d retries)\n", - tgt->bus_id, lu->lun, lu->retries); + dev_notice(tgt_dev(tgt), "reconnected to LUN %04x (%d retries)\n", + lu->lun, lu->retries); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); @@ -1068,8 +1078,8 @@ static void sbp2_clamp_management_orb_timeout(struct sbp2_target *tgt) unsigned int timeout = tgt->mgt_orb_timeout; if (timeout > 40000) - fw_notify("%s: %ds mgt_ORB_timeout limited to 40s\n", - tgt->bus_id, timeout / 1000); + dev_notice(tgt_dev(tgt), "%ds mgt_ORB_timeout limited to 40s\n", + timeout / 1000); tgt->mgt_orb_timeout = clamp_val(timeout, 5000, 40000); } @@ -1081,9 +1091,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, unsigned int w = sbp2_param_workarounds; if (w) - fw_notify("Please notify linux1394-devel@lists.sourceforge.net " - "if you need the workarounds parameter for %s\n", - tgt->bus_id); + dev_notice(tgt_dev(tgt), + "Please notify linux1394-devel@lists.sf.net " + "if you need the workarounds parameter\n"); if (w & SBP2_WORKAROUND_OVERRIDE) goto out; @@ -1103,9 +1113,9 @@ static void sbp2_init_workarounds(struct sbp2_target *tgt, u32 model, } out: if (w) - fw_notify("Workarounds for %s: 0x%x " - "(firmware_revision 0x%06x, model_id 0x%06x)\n", - tgt->bus_id, w, firmware_revision, model); + dev_notice(tgt_dev(tgt), "workarounds 0x%x " + "(firmware_revision 0x%06x, model_id 0x%06x)\n", + w, firmware_revision, model); tgt->workarounds = w; } @@ -1133,7 +1143,6 @@ static int sbp2_probe(struct device *dev) dev_set_drvdata(&unit->device, tgt); tgt->unit = unit; INIT_LIST_HEAD(&tgt->lu_list); - tgt->bus_id = dev_name(&unit->device); tgt->guid = (u64)device->config_rom[3] << 32 | device->config_rom[4]; if (fw_device_enable_phys_dma(device) < 0) @@ -1239,7 +1248,7 @@ static int sbp2_remove(struct device *dev) kfree(lu); } scsi_remove_host(shost); - fw_notify("released %s, target %d:0:0\n", tgt->bus_id, shost->host_no); + dev_notice(dev, "released target %d:0:0\n", shost->host_no); scsi_host_put(shost); return 0; @@ -1325,7 +1334,7 @@ static void complete_command_orb(struct sbp2_orb *base_orb, { struct sbp2_command_orb *orb = container_of(base_orb, struct sbp2_command_orb, base); - struct fw_device *device = target_device(orb->lu->tgt); + struct fw_device *device = target_parent_device(orb->lu->tgt); int result; if (status != NULL) { @@ -1433,7 +1442,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - struct fw_device *device = target_device(lu->tgt); + struct fw_device *device = target_parent_device(lu->tgt); struct sbp2_command_orb *orb; int generation, retval = SCSI_MLQUEUE_HOST_BUSY; @@ -1442,7 +1451,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, * transfer direction not handled. */ if (cmd->sc_data_direction == DMA_BIDIRECTIONAL) { - fw_error("Can't handle DMA_BIDIRECTIONAL, rejecting command\n"); + dev_err(lu_dev(lu), "cannot handle bidirectional command\n"); cmd->result = DID_ERROR << 16; cmd->scsi_done(cmd); return 0; @@ -1450,7 +1459,7 @@ static int sbp2_scsi_queuecommand(struct Scsi_Host *shost, orb = kzalloc(sizeof(*orb), GFP_ATOMIC); if (orb == NULL) { - fw_notify("failed to alloc orb\n"); + dev_notice(lu_dev(lu), "failed to alloc ORB\n"); return SCSI_MLQUEUE_HOST_BUSY; } @@ -1550,7 +1559,7 @@ static int sbp2_scsi_abort(struct scsi_cmnd *cmd) { struct sbp2_logical_unit *lu = cmd->device->hostdata; - fw_notify("%s: sbp2_scsi_abort\n", lu->tgt->bus_id); + dev_notice(lu_dev(lu), "sbp2_scsi_abort\n"); sbp2_agent_reset(lu); sbp2_cancel_orbs(lu); -- cgit v1.2.3-70-g09d2 From 0b8ecdda1943a05c8e7896f0b5f1addf39269927 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 13 Sep 2011 14:11:09 -0400 Subject: drm/i915: Silence _DSM errors <@ajax> mjg59: how concerned should i be about [drm:intel_dsm_pci_probe] *ERROR* failed to get supported _DSM functions ? <@mjg59> ajax: Entirely unconcerned Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index cb912106d1a..bae3edf956a 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c @@ -208,7 +208,7 @@ static bool intel_dsm_pci_probe(struct pci_dev *pdev) ret = intel_dsm(dhandle, INTEL_DSM_FN_SUPPORTED_FUNCTIONS, 0); if (ret < 0) { - DRM_ERROR("failed to get supported _DSM functions\n"); + DRM_DEBUG_KMS("failed to get supported _DSM functions\n"); return false; } -- cgit v1.2.3-70-g09d2 From cec2f356d59d9e070413e5966a3c5a1af136d948 Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Tue, 10 Jan 2012 15:09:36 -0800 Subject: drm/i915: Only look for matching clocks for LVDS downclock This patch enforces that the downclock clock source is the same as the preferred clock source for LVDS. This fixes a bug where the driver chooses a downclock clock source with a different P than the preferred mode clock source. This happened even if the preferred clock source implemented an acceptable rate for the downclock. The result of this bug is that downclock is disabled. Signed-off-by: Sean Paul Reviewed-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 29743dee54c..15f2b52ea70 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -75,7 +75,7 @@ struct intel_limit { intel_range_t dot, vco, n, m, m1, m2, p, p1; intel_p2_t p2; bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, - int, int, intel_clock_t *); + int, int, intel_clock_t *, intel_clock_t *); }; /* FDI */ @@ -83,17 +83,21 @@ struct intel_limit { static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static bool intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock); + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock); static inline u32 /* units of 100MHz */ intel_fdi_link_freq(struct drm_device *dev) @@ -515,7 +519,8 @@ static bool intel_PLL_is_valid(struct drm_device *dev, static bool intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; @@ -562,6 +567,9 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, if (!intel_PLL_is_valid(dev, limit, &clock)) continue; + if (match_clock && + clock.p != match_clock->p) + continue; this_err = abs(clock.dot - target); if (this_err < err) { @@ -578,7 +586,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -625,6 +634,9 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, if (!intel_PLL_is_valid(dev, limit, &clock)) continue; + if (match_clock && + clock.p != match_clock->p) + continue; this_err = abs(clock.dot - target); if (this_err < err_most) { @@ -642,7 +654,8 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, static bool intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { struct drm_device *dev = crtc->dev; intel_clock_t clock; @@ -668,7 +681,8 @@ intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, /* DisplayPort has only two frequencies, 162MHz and 270MHz */ static bool intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, - int target, int refclk, intel_clock_t *best_clock) + int target, int refclk, intel_clock_t *match_clock, + intel_clock_t *best_clock) { intel_clock_t clock; if (target < 200000) { @@ -5038,7 +5052,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); + ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, + &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; @@ -5048,21 +5063,17 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, intel_crtc_update_cursor(crtc, true); if (is_lvds && dev_priv->lvds_downclock_avail) { + /* + * Ensure we match the reduced clock's P to the target clock. + * If the clocks don't match, we can't switch the display clock + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ has_reduced_clock = limit->find_pll(limit, crtc, dev_priv->lvds_downclock, refclk, + &clock, &reduced_clock); - if (has_reduced_clock && (clock.p != reduced_clock.p)) { - /* - * If the different P is found, it means that we can't - * switch the display clock by using the FP0/FP1. - * In such case we will disable the LVDS downclock - * feature. - */ - DRM_DEBUG_KMS("Different P is found for " - "LVDS clock/downclock\n"); - has_reduced_clock = 0; - } } /* SDVO TV has fixed PLL values depend on its clock range, this mirrors vbios setting. */ @@ -5583,7 +5594,8 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ limit = intel_limit(crtc, refclk); - ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); + ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, NULL, + &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); return -EINVAL; @@ -5593,21 +5605,17 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc, intel_crtc_update_cursor(crtc, true); if (is_lvds && dev_priv->lvds_downclock_avail) { + /* + * Ensure we match the reduced clock's P to the target clock. + * If the clocks don't match, we can't switch the display clock + * by using the FP0/FP1. In such case we will disable the LVDS + * downclock feature. + */ has_reduced_clock = limit->find_pll(limit, crtc, dev_priv->lvds_downclock, refclk, + &clock, &reduced_clock); - if (has_reduced_clock && (clock.p != reduced_clock.p)) { - /* - * If the different P is found, it means that we can't - * switch the display clock by using the FP0/FP1. - * In such case we will disable the LVDS downclock - * feature. - */ - DRM_DEBUG_KMS("Different P is found for " - "LVDS clock/downclock\n"); - has_reduced_clock = 0; - } } /* SDVO TV has fixed PLL values depend on its clock range, this mirrors vbios setting. */ -- cgit v1.2.3-70-g09d2 From 5a117db77e47e3946d1aaa7ce8deafafd9d76746 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Thu, 5 Jan 2012 09:34:29 -0200 Subject: drm/i915: there is no pipe CxSR on ironlake After checking the specs and discussing with Jesse, turns out CxSR is not available on Ironlake and gen5, and its advertisement on the device description is misleading. Acked-by: Jesse Barnes Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8f7187915b0..057c2722594 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -198,7 +198,7 @@ static const struct intel_device_info intel_pineview_info = { static const struct intel_device_info intel_ironlake_d_info = { .gen = 5, - .need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, + .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, }; -- cgit v1.2.3-70-g09d2 From 6b2d590540d219064a53638f485b75203131dfce Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 4 Jan 2012 14:04:33 -0800 Subject: agp/intel: Add pci id for hostbridge from has/qemu This is needed to run the simulator. Cc: Jesse Barnes Signed-off-by: Ben Widawsky [danvet: added a comment in case people wonder what it's for.] Signed-off-by: Daniel Vetter --- drivers/char/agp/intel-agp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b427711be4b..962e75dc478 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -850,6 +850,7 @@ static struct pci_device_id agp_intel_pci_table[] = { .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ } + ID(PCI_DEVICE_ID_INTEL_82441), /* for HAS2 support */ ID(PCI_DEVICE_ID_INTEL_82443LX_0), ID(PCI_DEVICE_ID_INTEL_82443BX_0), ID(PCI_DEVICE_ID_INTEL_82443GX_0), -- cgit v1.2.3-70-g09d2 From c65d77d83ccffc60f8729b2e7806cac2564ee1b1 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 15 Dec 2011 12:30:36 -0800 Subject: drm/i915: split 9xx refclk & sdvo tv code out Makes the mode set routine a little cleaner and easier to extend. Signed-off-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 74 ++++++++++++++++++++++-------------- 1 file changed, 46 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 15f2b52ea70..b050a778516 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4982,6 +4982,48 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, return display_bpc != bpc; } +static int i9xx_get_refclk(struct drm_crtc *crtc, int num_connectors) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int refclk; + + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + intel_panel_use_ssc(dev_priv) && num_connectors < 2) { + refclk = dev_priv->lvds_ssc_freq * 1000; + DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", + refclk / 1000); + } else if (!IS_GEN2(dev)) { + refclk = 96000; + } else { + refclk = 48000; + } + + return refclk; +} + +static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, + intel_clock_t *clock) +{ + /* SDVO TV has fixed PLL values depend on its clock range, + this mirrors vbios setting. */ + if (adjusted_mode->clock >= 100000 + && adjusted_mode->clock < 140500) { + clock->p1 = 2; + clock->p2 = 10; + clock->n = 3; + clock->m1 = 16; + clock->m2 = 8; + } else if (adjusted_mode->clock >= 140500 + && adjusted_mode->clock <= 200000) { + clock->p1 = 1; + clock->p2 = 10; + clock->n = 6; + clock->m1 = 12; + clock->m2 = 8; + } +} + static int i9xx_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -5036,15 +5078,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, num_connectors++; } - if (is_lvds && intel_panel_use_ssc(dev_priv) && num_connectors < 2) { - refclk = dev_priv->lvds_ssc_freq * 1000; - DRM_DEBUG_KMS("using SSC reference clock of %d MHz\n", - refclk / 1000); - } else if (!IS_GEN2(dev)) { - refclk = 96000; - } else { - refclk = 48000; - } + refclk = i9xx_get_refclk(crtc, num_connectors); /* * Returns a set of divisors for the desired target clock with the given @@ -5075,25 +5109,9 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, &clock, &reduced_clock); } - /* SDVO TV has fixed PLL values depend on its clock range, - this mirrors vbios setting. */ - if (is_sdvo && is_tv) { - if (adjusted_mode->clock >= 100000 - && adjusted_mode->clock < 140500) { - clock.p1 = 2; - clock.p2 = 10; - clock.n = 3; - clock.m1 = 16; - clock.m2 = 8; - } else if (adjusted_mode->clock >= 140500 - && adjusted_mode->clock <= 200000) { - clock.p1 = 1; - clock.p2 = 10; - clock.n = 6; - clock.m1 = 12; - clock.m2 = 8; - } - } + + if (is_sdvo && is_tv) + i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); if (IS_PINEVIEW(dev)) { fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; -- cgit v1.2.3-70-g09d2 From a7516a05311d0e2deb8ce8ae8b8c12a513ca8ca2 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Thu, 15 Dec 2011 12:30:37 -0800 Subject: drm/i915: split out pll divider code This cleans up the mode set path a little further, making it easier to extend for future platforms. Signed-off-by: Jesse Barnes [danvet: shut up stupid gcc warning about potential use of un-initlized fp2] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 62 +++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b050a778516..f3e706c2bd3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5024,6 +5024,40 @@ static void i9xx_adjust_sdvo_tv_clock(struct drm_display_mode *adjusted_mode, } } +static void i9xx_update_pll_dividers(struct drm_crtc *crtc, + intel_clock_t *clock, + intel_clock_t *reduced_clock) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + u32 fp, fp2 = 0; + + if (IS_PINEVIEW(dev)) { + fp = (1 << clock->n) << 16 | clock->m1 << 8 | clock->m2; + if (reduced_clock) + fp2 = (1 << reduced_clock->n) << 16 | + reduced_clock->m1 << 8 | reduced_clock->m2; + } else { + fp = clock->n << 16 | clock->m1 << 8 | clock->m2; + if (reduced_clock) + fp2 = reduced_clock->n << 16 | reduced_clock->m1 << 8 | + reduced_clock->m2; + } + + I915_WRITE(FP0(pipe), fp); + + intel_crtc->lowfreq_avail = false; + if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && + reduced_clock && i915_powersave) { + I915_WRITE(FP1(pipe), fp2); + intel_crtc->lowfreq_avail = true; + } else { + I915_WRITE(FP1(pipe), fp); + } +} + static int i9xx_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, struct drm_display_mode *adjusted_mode, @@ -5037,7 +5071,7 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, int plane = intel_crtc->plane; int refclk, num_connectors = 0; intel_clock_t clock, reduced_clock; - u32 dpll, fp = 0, fp2 = 0, dspcntr, pipeconf; + u32 dpll, dspcntr, pipeconf; bool ok, has_reduced_clock = false, is_sdvo = false, is_dvo = false; bool is_crt = false, is_lvds = false, is_tv = false, is_dp = false; struct drm_mode_config *mode_config = &dev->mode_config; @@ -5113,17 +5147,8 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, if (is_sdvo && is_tv) i9xx_adjust_sdvo_tv_clock(adjusted_mode, &clock); - if (IS_PINEVIEW(dev)) { - fp = (1 << clock.n) << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = (1 << reduced_clock.n) << 16 | - reduced_clock.m1 << 8 | reduced_clock.m2; - } else { - fp = clock.n << 16 | clock.m1 << 8 | clock.m2; - if (has_reduced_clock) - fp2 = reduced_clock.n << 16 | reduced_clock.m1 << 8 | - reduced_clock.m2; - } + i9xx_update_pll_dividers(crtc, &clock, has_reduced_clock ? + &reduced_clock : NULL); dpll = DPLL_VGA_MODE_DIS; @@ -5233,7 +5258,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, DRM_DEBUG_KMS("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B'); drm_mode_debug_printmodeline(mode); - I915_WRITE(FP0(pipe), fp); I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE); POSTING_READ(DPLL(pipe)); @@ -5320,17 +5344,11 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, I915_WRITE(DPLL(pipe), dpll); } - intel_crtc->lowfreq_avail = false; - if (is_lvds && has_reduced_clock && i915_powersave) { - I915_WRITE(FP1(pipe), fp2); - intel_crtc->lowfreq_avail = true; - if (HAS_PIPE_CXSR(dev)) { + if (HAS_PIPE_CXSR(dev)) { + if (intel_crtc->lowfreq_avail) { DRM_DEBUG_KMS("enabling CxSR downclocking\n"); pipeconf |= PIPECONF_CXSR_DOWNCLOCK; - } - } else { - I915_WRITE(FP1(pipe), fp); - if (HAS_PIPE_CXSR(dev)) { + } else { DRM_DEBUG_KMS("disabling CxSR downclocking\n"); pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; } -- cgit v1.2.3-70-g09d2 From f3953dcb98bad1c3badf451bcf41bf83ae2ce542 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 28 Nov 2011 16:15:17 -0200 Subject: drm/i915: fix typo in function name Fix function name in comments, a left-over from when i965_reset was renamed to i915_reset. Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 057c2722594..7578c08110f 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -603,7 +603,7 @@ static int gen6_do_reset(struct drm_device *dev, u8 flags) } /** - * i965_reset - reset chip after a hang + * i915_reset - reset chip after a hang * @dev: drm device to reset * @flags: reset domains * -- cgit v1.2.3-70-g09d2 From 931872fceabacf2d4f8b6fbd51611c167e83164c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 16 Jan 2012 23:01:13 +0000 Subject: drm/i915: Check that plane/pipe is disabled before removing the fb Staring at an error state such as: PGTBL_ER: 0x00000400 Display B: Invalid tiling fence[0] = 05001001 valid, x-tiled, pitch: 512, start: 0x05000000, size: 1048576 Pinned [2]: 00000000 131072 0001 0001 00000000 P uncached 00020000 4096000 0041 0000 00000000 P uncached (name: 1) Plane [1]: CNTR: c0000000 # enabled | gamma STRIDE: 00001400 SIZE: 03ff04ff POS: 00000000 ADDR: 05000000 Suggests that we did not clear the DSPBCNTR prior to unpinning the framebuffer and reusing the GTT space. Impossible! Unless our DPMS bookkeeping ran afoul again... In the meantime add an assertion that the plane is decoupled from the framebuffer prior to release. Signed-off-by: Chris Wilson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f3e706c2bd3..5fa1476cbfc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -944,19 +944,24 @@ void assert_pipe(struct drm_i915_private *dev_priv, pipe_name(pipe), state_string(state), state_string(cur_state)); } -static void assert_plane_enabled(struct drm_i915_private *dev_priv, - enum plane plane) +static void assert_plane(struct drm_i915_private *dev_priv, + enum plane plane, bool state) { int reg; u32 val; + bool cur_state; reg = DSPCNTR(plane); val = I915_READ(reg); - WARN(!(val & DISPLAY_PLANE_ENABLE), - "plane %c assertion failure, should be active but is disabled\n", - plane_name(plane)); + cur_state = !!(val & DISPLAY_PLANE_ENABLE); + WARN(cur_state != state, + "plane %c assertion failure (expected %s, current %s)\n", + plane_name(plane), state_string(state), state_string(cur_state)); } +#define assert_plane_enabled(d, p) assert_plane(d, p, true) +#define assert_plane_disabled(d, p) assert_plane(d, p, false) + static void assert_planes_disabled(struct drm_i915_private *dev_priv, enum pipe pipe) { @@ -3335,6 +3340,8 @@ static void intel_crtc_disable(struct drm_crtc *crtc) struct drm_device *dev = crtc->dev; crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); + assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); + assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); if (crtc->fb) { mutex_lock(&dev->struct_mutex); -- cgit v1.2.3-70-g09d2 From 2aded1b6bb83cabe3ee5763e5c3834e36bf4a61f Mon Sep 17 00:00:00 2001 From: Simon Que Date: Thu, 10 Nov 2011 17:50:26 -0800 Subject: drivers: i915: Fix BLC PWM register setup There is an error in i915_read_blc_pwm_ctl, where the register values are not being copied correctly. BLC_PWM_CTL and BLC_PWM_CTL2 are getting mixed up. This patch fixes that so that saveBLC_PWM_CTL2 and not saveBLC_PWM_CTL is copied to the BLC_PWM_CTL2 register. Signed-off-by: Simon Que Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 04d79fd1dc9..c935cdaa215 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -141,8 +141,8 @@ static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) dev_priv->saveBLC_PWM_CTL2 = val; } else if (val == 0) { I915_WRITE(BLC_PWM_PCH_CTL2, - dev_priv->saveBLC_PWM_CTL); - val = dev_priv->saveBLC_PWM_CTL; + dev_priv->saveBLC_PWM_CTL2); + val = dev_priv->saveBLC_PWM_CTL2; } } else { val = I915_READ(BLC_PWM_CTL); -- cgit v1.2.3-70-g09d2 From 28c057945ef5d164925db4fccc64207ee58c8681 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:42 -0400 Subject: drm/i915: Implement plane-disabled assertion for PCH too Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5fa1476cbfc..d775f954c1b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -970,8 +970,14 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, int cur_pipe; /* Planes are fixed to pipes on ILK+ */ - if (HAS_PCH_SPLIT(dev_priv->dev)) + if (HAS_PCH_SPLIT(dev_priv->dev)) { + reg = DSPCNTR(pipe); + val = I915_READ(reg); + WARN((val & DISPLAY_PLANE_ENABLE), + "plane %c assertion failure, should be disabled but not\n", + plane_name(pipe)); return; + } /* Need to check both planes against the pipe */ for (i = 0; i < 2; i++) { -- cgit v1.2.3-70-g09d2 From 23c99e775d14f01ba45a5affd2fb51af4328359c Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:43 -0400 Subject: drm/i915: Fix assert_pch_hdmi_disabled to mention HDMI (not DP) Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d775f954c1b..3e21f3cb787 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1096,7 +1096,7 @@ static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, { u32 val = I915_READ(reg); WARN(hdmi_pipe_enabled(dev_priv, val, pipe), - "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", + "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", reg, pipe_name(pipe)); } -- cgit v1.2.3-70-g09d2 From 1f182b27d50ae9f5efeb28be5b65302c8a81e711 Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Fri, 7 Oct 2011 14:38:46 -0400 Subject: drm/i915: Remove a comment about PCH from the non-PCH path Signed-off-by: Adam Jackson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3e21f3cb787..ebe71eda954 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5235,8 +5235,6 @@ static int i9xx_crtc_mode_set(struct drm_crtc *crtc, /* Set up the display plane register */ dspcntr = DISPPLANE_GAMMA_ENABLE; - /* Ironlake's plane is forced to pipe, bit 24 is to - enable color space conversion */ if (pipe == 0) dspcntr &= ~DISPPLANE_SEL_PIPE_MASK; else -- cgit v1.2.3-70-g09d2 From 6919132e7a307b1f181d7655b3ef64cc7581a5ef Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:44 -0400 Subject: drm/i915/dp: Tweak auxch clock divider for PCH Matches the advice in the Sandybridge documentation. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index db3b461ad41..add871911a6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -378,7 +378,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = 225; /* eDP input clock at 450Mhz */ } else if (HAS_PCH_SPLIT(dev)) - aux_clock_divider = 62; /* IRL input clock fixed at 125Mhz */ + aux_clock_divider = 63; /* IRL input clock fixed at 125Mhz */ else aux_clock_divider = intel_hrawclk(dev) / 2; -- cgit v1.2.3-70-g09d2 From 092945e11c5b84f66dd08f0b87fb729715d377bc Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:45 -0400 Subject: drm/i915/dp: Use auxch precharge value of 5 everywhere The default in the Sandybridge docs is 5, as on Ironlake, and I have no reason to believe 3 would work any better. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index add871911a6..2f476638579 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -362,7 +362,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, int recv_bytes; uint32_t status; uint32_t aux_clock_divider; - int try, precharge; + int try, precharge = 5; intel_dp_check_edp(intel_dp); /* The clock divider is based off the hrawclk, @@ -382,11 +382,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, else aux_clock_divider = intel_hrawclk(dev) / 2; - if (IS_GEN6(dev)) - precharge = 3; - else - precharge = 5; - /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ(ch_ctl); -- cgit v1.2.3-70-g09d2 From d7e96feab83d29e27d14c60f1fa7c716ef7880cd Mon Sep 17 00:00:00 2001 From: Adam Jackson Date: Tue, 26 Jul 2011 15:39:46 -0400 Subject: drm/i915/dp: Check for AUXCH error before checking for success This is paranoid, but I am entirely willing to believe the hardware could come up with a condition where I get a status with both the 'done' and 'receive error' bits set. Signed-off-by: Adam Jackson Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 2f476638579..8f1148c0410 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -426,6 +426,10 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, DP_AUX_CH_CTL_DONE | DP_AUX_CH_CTL_TIME_OUT_ERROR | DP_AUX_CH_CTL_RECEIVE_ERROR); + + if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | + DP_AUX_CH_CTL_RECEIVE_ERROR)) + continue; if (status & DP_AUX_CH_CTL_DONE) break; } -- cgit v1.2.3-70-g09d2 From 493dea2876df144ec57a6a9efbe55db43c7a729e Mon Sep 17 00:00:00 2001 From: Thomas Meyer Date: Tue, 29 Nov 2011 22:08:00 +0100 Subject: drm/i915: Use kcalloc instead of kzalloc to allocate array The advantage of kcalloc is, that will prevent integer overflows which could result from the multiplication of number of elements and size and it is also a bit nicer to read. The semantic patch that makes this change is available in https://lkml.org/lkml/2011/11/25/107 Signed-off-by: Thomas Meyer Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_bios.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c index 63880e2e5cf..50656339d92 100644 --- a/drivers/gpu/drm/i915/intel_bios.c +++ b/drivers/gpu/drm/i915/intel_bios.c @@ -572,7 +572,7 @@ parse_device_mapping(struct drm_i915_private *dev_priv, DRM_DEBUG_KMS("no child dev is parsed from VBT\n"); return; } - dev_priv->child_dev = kzalloc(sizeof(*p_child) * count, GFP_KERNEL); + dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL); if (!dev_priv->child_dev) { DRM_DEBUG_KMS("No memory space for child device\n"); return; -- cgit v1.2.3-70-g09d2 From b2c606fe1defd1fb79612b48b528b2568c97def7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 17 Jan 2012 12:50:12 +0100 Subject: drm/i915: kill i915_mem.c Some decent history digging indicates that this was to be used for the GLX_MESA_allocate_memory extension but never actually implemented for any released i915 userspace code. So just rip it out. v2: Fixup the Makefile. Acked-by: Dave Airlie Cc: Keith Whitwell Reviewed-by: Eric Anholt Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/drm_ioctl.c | 2 + drivers/gpu/drm/i915/Makefile | 2 +- drivers/gpu/drm/i915/i915_dma.c | 14 +- drivers/gpu/drm/i915/i915_drv.h | 13 -- drivers/gpu/drm/i915/i915_mem.c | 387 ---------------------------------------- 5 files changed, 7 insertions(+), 411 deletions(-) delete mode 100644 drivers/gpu/drm/i915/i915_mem.c (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 956fd38d7c9..2300ab1a2a7 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c @@ -37,6 +37,7 @@ #include "drm_core.h" #include "linux/pci.h" +#include "linux/export.h" /** * Get the bus id. @@ -346,3 +347,4 @@ int drm_noop(struct drm_device *dev, void *data, DRM_DEBUG("\n"); return 0; } +EXPORT_SYMBOL(drm_noop); diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 808b255d7fc..ce7fc77678b 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -3,7 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm -i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ +i915-y := i915_drv.o i915_dma.o i915_irq.o \ i915_debugfs.o \ i915_suspend.o \ i915_gem.o \ diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 5f4d5893e98..2484c8ff0b8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2246,18 +2246,12 @@ void i915_driver_lastclose(struct drm_device * dev) i915_gem_lastclose(dev); - if (dev_priv->agp_heap) - i915_mem_takedown(&(dev_priv->agp_heap)); - i915_dma_cleanup(dev); } void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) { - drm_i915_private_t *dev_priv = dev->dev_private; i915_gem_release(dev, file_priv); - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_mem_release(dev, file_priv, dev_priv->agp_heap); } void i915_driver_postclose(struct drm_device *dev, struct drm_file *file) @@ -2276,11 +2270,11 @@ struct drm_ioctl_desc i915_ioctls[] = { DRM_IOCTL_DEF_DRV(I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_GETPARAM, i915_getparam, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(I915_ALLOC, i915_mem_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_FREE, i915_mem_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_ALLOC, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_FREE, drm_noop, DRM_AUTH), + DRM_IOCTL_DEF_DRV(I915_INIT_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH), - DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(I915_DESTROY_HEAP, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH), DRM_IOCTL_DEF_DRV(I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH), diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 602bc80baab..3cb88c3e056 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -329,7 +329,6 @@ typedef struct drm_i915_private { int tex_lru_log_granularity; int allow_batchbuffer; - struct mem_block *agp_heap; unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds; int vblank_pipe; int num_pipe; @@ -1075,18 +1074,6 @@ extern void i915_destroy_error_state(struct drm_device *dev); #endif -/* i915_mem.c */ -extern int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern int i915_mem_destroy_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv); -extern void i915_mem_takedown(struct mem_block **heap); -extern void i915_mem_release(struct drm_device * dev, - struct drm_file *file_priv, struct mem_block *heap); /* i915_gem.c */ int i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/i915/i915_mem.c b/drivers/gpu/drm/i915/i915_mem.c deleted file mode 100644 index cc8f6d49cf2..00000000000 --- a/drivers/gpu/drm/i915/i915_mem.c +++ /dev/null @@ -1,387 +0,0 @@ -/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*- - */ -/* - * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "drmP.h" -#include "drm.h" -#include "i915_drm.h" -#include "i915_drv.h" - -/* This memory manager is integrated into the global/local lru - * mechanisms used by the clients. Specifically, it operates by - * setting the 'in_use' fields of the global LRU to indicate whether - * this region is privately allocated to a client. - * - * This does require the client to actually respect that field. - * - * Currently no effort is made to allocate 'private' memory in any - * clever way - the LRU information isn't used to determine which - * block to allocate, and the ring is drained prior to allocations -- - * in other words allocation is expensive. - */ -static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - drm_i915_sarea_t *sarea_priv = master_priv->sarea_priv; - struct drm_tex_region *list; - unsigned shift, nr; - unsigned start; - unsigned end; - unsigned i; - int age; - - shift = dev_priv->tex_lru_log_granularity; - nr = I915_NR_TEX_REGIONS; - - start = p->start >> shift; - end = (p->start + p->size - 1) >> shift; - - age = ++sarea_priv->texAge; - list = sarea_priv->texList; - - /* Mark the regions with the new flag and update their age. Move - * them to head of list to preserve LRU semantics. - */ - for (i = start; i <= end; i++) { - list[i].in_use = in_use; - list[i].age = age; - - /* remove_from_list(i) - */ - list[(unsigned)list[i].next].prev = list[i].prev; - list[(unsigned)list[i].prev].next = list[i].next; - - /* insert_at_head(list, i) - */ - list[i].prev = nr; - list[i].next = list[nr].next; - list[(unsigned)list[nr].next].prev = i; - list[nr].next = i; - } -} - -/* Very simple allocator for agp memory, working on a static range - * already mapped into each client's address space. - */ - -static struct mem_block *split_block(struct mem_block *p, int start, int size, - struct drm_file *file_priv) -{ - /* Maybe cut off the start of an existing block */ - if (start > p->start) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start; - newblock->size = p->size - (start - p->start); - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size -= newblock->size; - p = newblock; - } - - /* Maybe cut off the end of an existing block */ - if (size < p->size) { - struct mem_block *newblock = kmalloc(sizeof(*newblock), - GFP_KERNEL); - if (!newblock) - goto out; - newblock->start = start + size; - newblock->size = p->size - size; - newblock->file_priv = NULL; - newblock->next = p->next; - newblock->prev = p; - p->next->prev = newblock; - p->next = newblock; - p->size = size; - } - - out: - /* Our block is in the middle */ - p->file_priv = file_priv; - return p; -} - -static struct mem_block *alloc_block(struct mem_block *heap, int size, - int align2, struct drm_file *file_priv) -{ - struct mem_block *p; - int mask = (1 << align2) - 1; - - for (p = heap->next; p != heap; p = p->next) { - int start = (p->start + mask) & ~mask; - if (p->file_priv == NULL && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); - } - - return NULL; -} - -static struct mem_block *find_block(struct mem_block *heap, int start) -{ - struct mem_block *p; - - for (p = heap->next; p != heap; p = p->next) - if (p->start == start) - return p; - - return NULL; -} - -static void free_block(struct mem_block *p) -{ - p->file_priv = NULL; - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - if (p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - - if (p->prev->file_priv == NULL) { - struct mem_block *q = p->prev; - q->size += p->size; - q->next = p->next; - q->next->prev = q; - kfree(p); - } -} - -/* Initialize. How to check for an uninitialized heap? - */ -static int init_heap(struct mem_block **heap, int start, int size) -{ - struct mem_block *blocks = kmalloc(sizeof(*blocks), GFP_KERNEL); - - if (!blocks) - return -ENOMEM; - - *heap = kmalloc(sizeof(**heap), GFP_KERNEL); - if (!*heap) { - kfree(blocks); - return -ENOMEM; - } - - blocks->start = start; - blocks->size = size; - blocks->file_priv = NULL; - blocks->next = blocks->prev = *heap; - - memset(*heap, 0, sizeof(**heap)); - (*heap)->file_priv = (struct drm_file *) -1; - (*heap)->next = (*heap)->prev = blocks; - return 0; -} - -/* Free all blocks associated with the releasing file. - */ -void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv, - struct mem_block *heap) -{ - struct mem_block *p; - - if (!heap || !heap->next) - return; - - for (p = heap->next; p != heap; p = p->next) { - if (p->file_priv == file_priv) { - p->file_priv = NULL; - mark_block(dev, p, 0); - } - } - - /* Assumes a single contiguous range. Needs a special file_priv in - * 'heap' to stop it being subsumed. - */ - for (p = heap->next; p != heap; p = p->next) { - while (p->file_priv == NULL && p->next->file_priv == NULL) { - struct mem_block *q = p->next; - p->size += q->size; - p->next = q->next; - p->next->prev = p; - kfree(q); - } - } -} - -/* Shutdown. - */ -void i915_mem_takedown(struct mem_block **heap) -{ - struct mem_block *p; - - if (!*heap) - return; - - for (p = (*heap)->next; p != *heap;) { - struct mem_block *q = p; - p = p->next; - kfree(q); - } - - kfree(*heap); - *heap = NULL; -} - -static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region) -{ - switch (region) { - case I915_MEM_REGION_AGP: - return &dev_priv->agp_heap; - default: - return NULL; - } -} - -/* IOCTL HANDLERS */ - -int i915_mem_alloc(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_alloc_t *alloc = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, alloc->region); - if (!heap || !*heap) - return -EFAULT; - - /* Make things easier on ourselves: all allocations at least - * 4k aligned. - */ - if (alloc->alignment < 12) - alloc->alignment = 12; - - block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv); - - if (!block) - return -ENOMEM; - - mark_block(dev, block, 1); - - if (DRM_COPY_TO_USER(alloc->region_offset, &block->start, - sizeof(int))) { - DRM_ERROR("copy_to_user\n"); - return -EFAULT; - } - - return 0; -} - -int i915_mem_free(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_free_t *memfree = data; - struct mem_block *block, **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, memfree->region); - if (!heap || !*heap) - return -EFAULT; - - block = find_block(*heap, memfree->region_offset); - if (!block) - return -EFAULT; - - if (block->file_priv != file_priv) - return -EPERM; - - mark_block(dev, block, 0); - free_block(block); - return 0; -} - -int i915_mem_init_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_init_heap_t *initheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, initheap->region); - if (!heap) - return -EFAULT; - - if (*heap) { - DRM_ERROR("heap already initialized?"); - return -EFAULT; - } - - return init_heap(heap, initheap->start, initheap->size); -} - -int i915_mem_destroy_heap(struct drm_device *dev, void *data, - struct drm_file *file_priv) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - drm_i915_mem_destroy_heap_t *destroyheap = data; - struct mem_block **heap; - - if (!dev_priv) { - DRM_ERROR("called with no initialization\n"); - return -EINVAL; - } - - heap = get_heap(dev_priv, destroyheap->region); - if (!heap) { - DRM_ERROR("get_heap failed"); - return -EFAULT; - } - - if (!*heap) { - DRM_ERROR("heap not initialized?"); - return -EFAULT; - } - - i915_mem_takedown(heap); - return 0; -} -- cgit v1.2.3-70-g09d2 From 3d29b842e58fbca2c13a9f458fddbaa535c6e578 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Tue, 17 Jan 2012 14:43:53 -0200 Subject: drm/i915: add a LLC feature flag in device description LLC is not SNB/IVB-specific, so we should check for it in a more generic way. Reviewed-by: Chris Wilson Reviewed-by: Eric Anholt Reviewed-by: Kenneth Graunke Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 1 + drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/i915_drv.c | 4 ++++ drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 4 ++-- include/drm/i915_drm.h | 1 + 6 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 11807989f91..6c3be86274e 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -83,6 +83,7 @@ static int i915_capabilities(struct seq_file *m, void *data) B(supports_tv); B(has_bsd_ring); B(has_blt_ring); + B(has_llc); #undef B return 0; diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2484c8ff0b8..8122738db91 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -784,6 +784,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_GEN7_SOL_RESET: value = 1; break; + case I915_PARAM_HAS_LLC: + value = HAS_LLC(dev); + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 7578c08110f..1658cfd85aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -214,6 +214,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_sandybridge_m_info = { @@ -222,6 +223,7 @@ static const struct intel_device_info intel_sandybridge_m_info = { .has_fbc = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_ivybridge_d_info = { @@ -229,6 +231,7 @@ static const struct intel_device_info intel_ivybridge_d_info = { .need_gfx_hws = 1, .has_hotplug = 1, .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct intel_device_info intel_ivybridge_m_info = { @@ -237,6 +240,7 @@ static const struct intel_device_info intel_ivybridge_m_info = { .has_fbc = 0, /* FBC is not enabled on Ivybridge mobile yet */ .has_bsd_ring = 1, .has_blt_ring = 1, + .has_llc = 1, }; static const struct pci_device_id pciidlist[] = { /* aka */ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3cb88c3e056..f02a5f525f0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -255,6 +255,7 @@ struct intel_device_info { u8 supports_tv:1; u8 has_bsd_ring:1; u8 has_blt_ring:1; + u8 has_llc:1; }; enum no_fbc_reason { @@ -969,6 +970,7 @@ struct drm_i915_file_private { #define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) +#define HAS_LLC(dev) (INTEL_INFO(dev)->has_llc) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) #define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e55badb2d86..eb98a7f55cf 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3619,8 +3619,8 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->base.write_domain = I915_GEM_DOMAIN_CPU; obj->base.read_domains = I915_GEM_DOMAIN_CPU; - if (IS_GEN6(dev) || IS_GEN7(dev)) { - /* On Gen6, we can have the GPU use the LLC (the CPU + if (HAS_LLC(dev)) { + /* On some devices, we can have the GPU use the LLC (the CPU * cache) for about a 10% performance improvement * compared to uncached. Graphics requests other than * display scanout are coherent with the CPU in diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 924f6a454fe..da929bb5b78 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -296,6 +296,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXEC_CONSTANTS 14 #define I915_PARAM_HAS_RELAXED_DELTA 15 #define I915_PARAM_HAS_GEN7_SOL_RESET 16 +#define I915_PARAM_HAS_LLC 17 typedef struct drm_i915_getparam { int param; -- cgit v1.2.3-70-g09d2 From d6f802612af55cc1b3699d119a04dfa2fc8812a0 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:19 +0200 Subject: ath6kl: use netdev_features_t Commit c8f44affb7 ("net: introduce and use netdev_features_t for device features sets") added netdev_features_t to ndo_set_features. Change ath6kl to use the new type. This fixes a warning: ath6kl/main.c:1170: warning: initialization from incompatible pointer type Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 0a6d6e2be6e..3a3b2cc9940 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -1021,7 +1021,8 @@ static struct net_device_stats *ath6kl_get_stats(struct net_device *dev) return &vif->net_stats; } -static int ath6kl_set_features(struct net_device *dev, u32 features) +static int ath6kl_set_features(struct net_device *dev, + netdev_features_t features) { struct ath6kl_vif *vif = netdev_priv(dev); struct ath6kl *ar = vif->ar; -- cgit v1.2.3-70-g09d2 From 3462735dadb90efd5bed9d2b81222ed7da1390a0 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:32 +0200 Subject: ath6kl: remove -D__CHECK_ENDIAN__ from Makefile As drivers/net/wireless/ath/Makefile contains the flag to enable endian checks there's no need to have it in ath6kl makefile anymore. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 70706930355..e24b6179915 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -33,5 +33,3 @@ ath6kl-y += txrx.o ath6kl-y += wmi.o ath6kl-y += sdio.o ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o - -ccflags-y += -D__CHECK_ENDIAN__ -- cgit v1.2.3-70-g09d2 From e572602884c4f979cbba4fed413af24797fd01d9 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 15:05:46 +0200 Subject: ath6kl: fix uninitialized warning in ath6kl_process_uapsdq() Before I commited patch c1762a3fe ("ath6kl: Add support for uAPSD") I did a minor change how up variable is initialised in ath6kl_process_uapsdq(). But I was sloppy and caused this compiler warning: txrx.c:88:5: warning: 'up' may be used uninitialized in this function Revert my change to fix the warning. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 91bbc1ffa49..dd633714260 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -85,7 +85,7 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, struct ath6kl *ar = vif->ar; bool is_apsdq_empty = false; struct ethhdr *datap = (struct ethhdr *) skb->data; - u8 up, traffic_class, *ip_hdr; + u8 up = 0, traffic_class, *ip_hdr; u16 ether_type; struct ath6kl_llc_snap_hdr *llc_hdr; @@ -122,8 +122,6 @@ static bool ath6kl_process_uapsdq(struct ath6kl_sta *conn, if (ether_type == IP_ETHERTYPE) up = ath6kl_wmi_determine_user_priority( ip_hdr, 0); - } else { - up = 0; } traffic_class = ath6kl_wmi_get_traffic_class(up); -- cgit v1.2.3-70-g09d2 From cd23c1c9b8a2de64477a795ab5a9cd5278397f24 Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Tue, 17 Jan 2012 15:32:29 +0200 Subject: ath6kl: add testmode 2 for 6003 ART Add testmode 2 for 6003 ART. When you insmod ath6kl_sdio.ko testmode=2, ath6kl will load ART firmware utf.bin and testscript nullTestFlow.bin. These files should be put in the firmware folder. kvalo: add "ath6kl:" to the title, word wrap the commit log and remove extra line in the code Signed-off-by: Alex Yang Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 8 +++ drivers/net/wireless/ath/ath6kl/init.c | 108 +++++++++++++++++++++++++++++++-- 2 files changed, 110 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ba3953918e4..f53594f2e53 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -125,6 +125,8 @@ struct ath6kl_fw_ie { #define AR6003_HW_2_1_1_OTP_FILE "otp.bin" #define AR6003_HW_2_1_1_FIRMWARE_FILE "athwlan.bin" #define AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE "athtcmd_ram.bin" +#define AR6003_HW_2_1_1_UTF_FIRMWARE_FILE "utf.bin" +#define AR6003_HW_2_1_1_TESTSCRIPT_FILE "nullTestFlow.bin" #define AR6003_HW_2_1_1_PATCH_FILE "data.patch.bin" #define AR6003_HW_2_1_1_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin" #define AR6003_HW_2_1_1_DEFAULT_BOARD_DATA_FILE \ @@ -592,6 +594,7 @@ struct ath6kl { u32 board_addr; u32 refclk_hz; u32 uarttx_pin; + u32 testscript_addr; struct ath6kl_hw_fw { const char *dir; @@ -599,6 +602,8 @@ struct ath6kl { const char *fw; const char *tcmd; const char *patch; + const char *utf; + const char *testscript; } fw; const char *fw_board; @@ -624,6 +629,9 @@ struct ath6kl { u8 *fw_patch; size_t fw_patch_len; + u8 *fw_testscript; + size_t fw_testscript_len; + unsigned int fw_api; unsigned long fw_capabilities[ATH6KL_CAPABILITY_LEN]; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index e5969c14630..b88f41dc3df 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -69,6 +69,7 @@ static const struct ath6kl_hw hw_list[] = { .reserved_ram_size = 512, .refclk_hz = 26000000, .uarttx_pin = 8, + .testscript_addr = 0x57ef74, .fw = { .dir = AR6003_HW_2_1_1_FW_DIR, @@ -76,6 +77,8 @@ static const struct ath6kl_hw hw_list[] = { .fw = AR6003_HW_2_1_1_FIRMWARE_FILE, .tcmd = AR6003_HW_2_1_1_TCMD_FIRMWARE_FILE, .patch = AR6003_HW_2_1_1_PATCH_FILE, + .utf = AR6003_HW_2_1_1_UTF_FIRMWARE_FILE, + .testscript = AR6003_HW_2_1_1_TESTSCRIPT_FILE, }, .fw_board = AR6003_HW_2_1_1_BOARD_DATA_FILE, @@ -620,6 +623,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar) kfree(ar->fw_otp); kfree(ar->fw); kfree(ar->fw_patch); + kfree(ar->fw_testscript); ath6kl_deinit_ieee80211_hw(ar); } @@ -771,14 +775,25 @@ static int ath6kl_fetch_fw_file(struct ath6kl *ar) return 0; if (testmode) { - if (ar->hw.fw.tcmd == NULL) { - ath6kl_warn("testmode not supported\n"); - return -EOPNOTSUPP; - } + ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", + testmode); + if (testmode == 2) { + if (ar->hw.fw.utf == NULL) { + ath6kl_warn("testmode 2 not supported\n"); + return -EOPNOTSUPP; + } - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.tcmd); + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.utf); + } else { + if (ar->hw.fw.tcmd == NULL) { + ath6kl_warn("testmode 1 not supported\n"); + return -EOPNOTSUPP; + } + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); + } set_bit(TESTMODE, &ar->flag); goto get_fw; @@ -827,6 +842,34 @@ static int ath6kl_fetch_patch_file(struct ath6kl *ar) return 0; } +static int ath6kl_fetch_testscript_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (testmode != 2) + return 0; + + if (ar->fw_testscript != NULL) + return 0; + + if (ar->hw.fw.testscript == NULL) + return 0; + + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.testscript); + + ret = ath6kl_get_fw(ar, filename, &ar->fw_testscript, + &ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to get testscript file %s: %d\n", + filename, ret); + return ret; + } + + return 0; +} + static int ath6kl_fetch_fw_api1(struct ath6kl *ar) { int ret; @@ -843,6 +886,10 @@ static int ath6kl_fetch_fw_api1(struct ath6kl *ar) if (ret) return ret; + ret = ath6kl_fetch_testscript_file(ar); + if (ret) + return ret; + return 0; } @@ -1266,6 +1313,50 @@ static int ath6kl_upload_patch(struct ath6kl *ar) return 0; } +static int ath6kl_upload_testscript(struct ath6kl *ar) +{ + u32 address, param; + int ret; + + if (testmode != 2) + return 0; + + if (ar->fw_testscript == NULL) + return 0; + + address = ar->hw.testscript_addr; + + ath6kl_dbg(ATH6KL_DBG_BOOT, "writing testscript to 0x%x (%zd B)\n", + address, ar->fw_testscript_len); + + ret = ath6kl_bmi_write(ar, address, ar->fw_testscript, + ar->fw_testscript_len); + if (ret) { + ath6kl_err("Failed to write testscript file: %d\n", ret); + return ret; + } + + param = address; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_ota_testscript)), + (unsigned char *) ¶m, 4); + + param = 4096; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_end_ram_reserve_sz)), + (unsigned char *) ¶m, 4); + + param = 1; + ath6kl_bmi_write(ar, + ath6kl_get_hi_item_addr(ar, + HI_ITEM(hi_test_apps_related)), + (unsigned char *) ¶m, 4); + + return 0; +} + static int ath6kl_init_upload(struct ath6kl *ar) { u32 param, options, sleep, address; @@ -1374,6 +1465,11 @@ static int ath6kl_init_upload(struct ath6kl *ar) if (status) return status; + /* Download the test script */ + status = ath6kl_upload_testscript(ar); + if (status) + return status; + /* Restore system sleep */ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; status = ath6kl_bmi_reg_write(ar, address, sleep); -- cgit v1.2.3-70-g09d2 From c25889e8a6fdfc54618b192a80c94419ddb7949d Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:27 +0200 Subject: ath6kl: rename vif init and cleanup functions ath6kl_cfg80211_vif_init/cleanup() follow more closely the style used elsewhere in ath6kl. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 9 ++++----- drivers/net/wireless/ath/ath6kl/cfg80211.h | 2 ++ drivers/net/wireless/ath/ath6kl/core.h | 1 - drivers/net/wireless/ath/ath6kl/init.c | 5 +++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index a13ecec0070..7e92dc9799a 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1401,7 +1401,7 @@ static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy, ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); return 0; } @@ -2806,7 +2806,7 @@ int ath6kl_register_ieee80211_hw(struct ath6kl *ar) return 0; } -static int ath6kl_init_if_data(struct ath6kl_vif *vif) +static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); if (!vif->aggr_cntxt) { @@ -2827,7 +2827,7 @@ static int ath6kl_init_if_data(struct ath6kl_vif *vif) return 0; } -void ath6kl_deinit_if_data(struct ath6kl_vif *vif) +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) { struct ath6kl *ar = vif->ar; struct ath6kl_mc_filter *mc_filter, *tmp; @@ -2880,8 +2880,7 @@ struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, ath6kl_init_control_info(vif); - /* TODO: Pass interface specific pointer instead of ar */ - if (ath6kl_init_if_data(vif)) + if (ath6kl_cfg80211_vif_init(vif)) goto err; if (register_netdevice(ndev)) diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 81f20a57231..aa961694cf9 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -53,6 +53,8 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, int ath6kl_cfg80211_resume(struct ath6kl *ar); +void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif); + void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop_all(struct ath6kl *ar); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index f53594f2e53..bdeb254c259 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -753,7 +753,6 @@ void ath6kl_wakeup_event(void *dev); void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); -void ath6kl_deinit_if_data(struct ath6kl_vif *vif); void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index b88f41dc3df..3cc4e0842ad 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1811,7 +1811,7 @@ err_rxbuf_cleanup: ath6kl_htc_flush_rx_buf(ar->htc_target); ath6kl_cleanup_amsdu_rxbufs(ar); rtnl_lock(); - ath6kl_deinit_if_data(netdev_priv(ndev)); + ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); rtnl_unlock(); wiphy_unregister(ar->wiphy); err_debug_init: @@ -1832,6 +1832,7 @@ err_wq: return ret; } +/* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) { static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; @@ -1877,7 +1878,7 @@ void ath6kl_stop_txrx(struct ath6kl *ar) spin_unlock_bh(&ar->list_lock); ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag)); rtnl_lock(); - ath6kl_deinit_if_data(vif); + ath6kl_cfg80211_vif_cleanup(vif); rtnl_unlock(); spin_lock_bh(&ar->list_lock); } -- cgit v1.2.3-70-g09d2 From 46d33a21cfa531f4271c3f0b7b87a295f30f9e6a Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:40 +0200 Subject: ath6kl: unify cfg80211 init/cleanup functions Group them together and change the naming to follow the common style in ath6kl. No functional changes. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 109 +++++++++++++++-------------- drivers/net/wireless/ath/ath6kl/cfg80211.h | 6 +- drivers/net/wireless/ath/ath6kl/init.c | 4 +- 3 files changed, 62 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7e92dc9799a..44fdd39e170 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2755,57 +2755,6 @@ struct ath6kl *ath6kl_core_alloc(struct device *dev) return ar; } -int ath6kl_register_ieee80211_hw(struct ath6kl *ar) -{ - struct wiphy *wiphy = ar->wiphy; - int ret; - - wiphy->mgmt_stypes = ath6kl_mgmt_stypes; - - wiphy->max_remain_on_channel_duration = 5000; - - /* set device pointer for wiphy */ - set_wiphy_dev(wiphy, ar->dev); - - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC) | - BIT(NL80211_IFTYPE_AP); - if (ar->p2p) { - wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | - BIT(NL80211_IFTYPE_P2P_CLIENT); - } - - /* max num of ssids that can be probed during scanning */ - wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; - wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ - wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; - wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wiphy->cipher_suites = cipher_suites; - wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | - WIPHY_WOWLAN_DISCONNECT | - WIPHY_WOWLAN_GTK_REKEY_FAILURE | - WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | - WIPHY_WOWLAN_EAP_IDENTITY_REQ | - WIPHY_WOWLAN_4WAY_HANDSHAKE; - wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; - wiphy->wowlan.pattern_min_len = 1; - wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; - - wiphy->max_sched_scan_ssids = 10; - - ret = wiphy_register(wiphy); - if (ret < 0) { - ath6kl_err("couldn't register wiphy device\n"); - return ret; - } - - return 0; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); @@ -2907,8 +2856,64 @@ err: return NULL; } -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar) +int ath6kl_cfg80211_init(struct ath6kl *ar) +{ + struct wiphy *wiphy = ar->wiphy; + int ret; + + wiphy->mgmt_stypes = ath6kl_mgmt_stypes; + + wiphy->max_remain_on_channel_duration = 5000; + + /* set device pointer for wiphy */ + set_wiphy_dev(wiphy, ar->dev); + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | + BIT(NL80211_IFTYPE_ADHOC) | + BIT(NL80211_IFTYPE_AP); + if (ar->p2p) { + wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_CLIENT); + } + + /* max num of ssids that can be probed during scanning */ + wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; + wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */ + wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz; + wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + wiphy->cipher_suites = cipher_suites; + wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); + + wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | + WIPHY_WOWLAN_DISCONNECT | + WIPHY_WOWLAN_GTK_REKEY_FAILURE | + WIPHY_WOWLAN_SUPPORTS_GTK_REKEY | + WIPHY_WOWLAN_EAP_IDENTITY_REQ | + WIPHY_WOWLAN_4WAY_HANDSHAKE; + wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST; + wiphy->wowlan.pattern_min_len = 1; + wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE; + + wiphy->max_sched_scan_ssids = 10; + + ret = wiphy_register(wiphy); + if (ret < 0) { + ath6kl_err("couldn't register wiphy device\n"); + return ret; + } + + return 0; +} + +void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); + + /* + * FIXME: should be removed as we remove wiphy in + * ath6kl_core_free(). Most likely this causes a use after free. + */ wiphy_free(ar->wiphy); } diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index aa961694cf9..08d97691039 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -27,10 +27,7 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -int ath6kl_register_ieee80211_hw(struct ath6kl *ar); struct ath6kl *ath6kl_core_alloc(struct device *dev); -void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar); - void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -58,4 +55,7 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop(struct ath6kl_vif *vif); void ath6kl_cfg80211_stop_all(struct ath6kl *ar); +int ath6kl_cfg80211_init(struct ath6kl *ar); +void ath6kl_cfg80211_cleanup(struct ath6kl *ar); + #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 3cc4e0842ad..7e56a6aa70b 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -625,7 +625,7 @@ void ath6kl_core_cleanup(struct ath6kl *ar) kfree(ar->fw_patch); kfree(ar->fw_testscript); - ath6kl_deinit_ieee80211_hw(ar); + ath6kl_cfg80211_cleanup(ar); } /* firmware upload */ @@ -1722,7 +1722,7 @@ int ath6kl_core_init(struct ath6kl *ar) ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - ret = ath6kl_register_ieee80211_hw(ar); + ret = ath6kl_cfg80211_init(ar); if (ret) goto err_node_cleanup; -- cgit v1.2.3-70-g09d2 From f29af97853599e9537191c4f33f8ac87f3f503a9 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:08:56 +0200 Subject: ath6kl: add ATH6KL_CONF_UART_DEBUG Add ATH6KL_CONF_UART_DEBUG which is set whenever uart_debug module parameter is enabled. This way we can keep the uart_debug parameter static when core.c file is introduced. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index bdeb254c259..78c0402e2d3 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -197,6 +197,7 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) #define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) +#define ATH6KL_CONF_UART_DEBUG BIT(5) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 7e56a6aa70b..2804921d5d8 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -469,7 +469,7 @@ int ath6kl_configure_target(struct ath6kl *ar) u8 fw_iftype, fw_mode = 0, fw_submode = 0; int i, status; - param = uart_debug; + param = !!(ar->conf_flags & ATH6KL_CONF_UART_DEBUG); if (ath6kl_bmi_write(ar, ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_serial_enable)), (u8 *)¶m, 4)) { ath6kl_err("bmi_write_memory for uart debug failed\n"); @@ -1775,6 +1775,9 @@ int ath6kl_core_init(struct ath6kl *ar) if (suspend_cutpower) ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + if (uart_debug) + ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | -- cgit v1.2.3-70-g09d2 From 45eaa78f757b3b3992ca02c753764665e9fba0a4 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:05 +0200 Subject: ath6kl: create core.c Currently core functions are spread between various files, group all the functions into file and rename the functions to follow the style used elsewhere in the driver. This will make it easier to a separate core module. Also fix a bug where wiphy is freed too early. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 1 + drivers/net/wireless/ath/ath6kl/cfg80211.c | 94 +++------- drivers/net/wireless/ath/ath6kl/cfg80211.h | 4 +- drivers/net/wireless/ath/ath6kl/common.h | 3 - drivers/net/wireless/ath/ath6kl/core.c | 292 +++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/core.h | 9 +- drivers/net/wireless/ath/ath6kl/init.c | 213 +-------------------- drivers/net/wireless/ath/ath6kl/sdio.c | 4 +- 8 files changed, 332 insertions(+), 288 deletions(-) create mode 100644 drivers/net/wireless/ath/ath6kl/core.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index e24b6179915..854694b26a4 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -31,5 +31,6 @@ ath6kl-y += init.o ath6kl-y += main.o ath6kl-y += txrx.o ath6kl-y += wmi.o +ath6kl-y += core.o ath6kl-y += sdio.o ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 44fdd39e170..7ff9806de50 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -23,10 +23,6 @@ #include "hif-ops.h" #include "testmode.h" -static unsigned int ath6kl_p2p; - -module_param(ath6kl_p2p, uint, 0644); - #define RATETAB_ENT(_rate, _rateid, _flags) { \ .bitrate = (_rate), \ .flags = (_flags), \ @@ -2693,68 +2689,6 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) ath6kl_cfg80211_stop(vif); } -struct ath6kl *ath6kl_core_alloc(struct device *dev) -{ - struct ath6kl *ar; - struct wiphy *wiphy; - u8 ctr; - - /* create a new wiphy for use with cfg80211 */ - wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); - - if (!wiphy) { - ath6kl_err("couldn't allocate wiphy device\n"); - return NULL; - } - - ar = wiphy_priv(wiphy); - ar->p2p = !!ath6kl_p2p; - ar->wiphy = wiphy; - ar->dev = dev; - - ar->vif_max = 1; - - ar->max_norm_iface = 1; - - spin_lock_init(&ar->lock); - spin_lock_init(&ar->mcastpsq_lock); - spin_lock_init(&ar->list_lock); - - init_waitqueue_head(&ar->event_wq); - sema_init(&ar->sem, 1); - - INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); - INIT_LIST_HEAD(&ar->vif_list); - - clear_bit(WMI_ENABLED, &ar->flag); - clear_bit(SKIP_SCAN, &ar->flag); - clear_bit(DESTROY_IN_PROGRESS, &ar->flag); - - ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; - ar->tx_pwr = 0; - - ar->intra_bss = 1; - ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; - - ar->state = ATH6KL_STATE_OFF; - - memset((u8 *)ar->sta_list, 0, - AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); - - /* Init the PS queues */ - for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { - spin_lock_init(&ar->sta_list[ctr].psq_lock); - skb_queue_head_init(&ar->sta_list[ctr].psq); - skb_queue_head_init(&ar->sta_list[ctr].apsdq); - } - - skb_queue_head_init(&ar->mcastpsq); - - memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); - - return ar; -} - static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { vif->aggr_cntxt = aggr_init(vif->ndev); @@ -2910,10 +2844,30 @@ int ath6kl_cfg80211_init(struct ath6kl *ar) void ath6kl_cfg80211_cleanup(struct ath6kl *ar) { wiphy_unregister(ar->wiphy); +} - /* - * FIXME: should be removed as we remove wiphy in - * ath6kl_core_free(). Most likely this causes a use after free. - */ +struct ath6kl *ath6kl_cfg80211_create(void) +{ + struct ath6kl *ar; + struct wiphy *wiphy; + + /* create a new wiphy for use with cfg80211 */ + wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl)); + + if (!wiphy) { + ath6kl_err("couldn't allocate wiphy device\n"); + return NULL; + } + + ar = wiphy_priv(wiphy); + ar->wiphy = wiphy; + + return ar; +} + +/* Note: ar variable must not be accessed after calling this! */ +void ath6kl_cfg80211_destroy(struct ath6kl *ar) +{ wiphy_free(ar->wiphy); } + diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 08d97691039..3c693b7c0ef 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -27,7 +27,6 @@ enum ath6kl_cfg_suspend_mode { struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); -struct ath6kl *ath6kl_core_alloc(struct device *dev); void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted); void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel, @@ -58,4 +57,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar); int ath6kl_cfg80211_init(struct ath6kl *ar); void ath6kl_cfg80211_cleanup(struct ath6kl *ar); +struct ath6kl *ath6kl_cfg80211_create(void); +void ath6kl_cfg80211_destroy(struct ath6kl *ar); + #endif /* ATH6KL_CFG80211_H */ diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h index bfd6597763d..f89f1e180da 100644 --- a/drivers/net/wireless/ath/ath6kl/common.h +++ b/drivers/net/wireless/ath/ath6kl/common.h @@ -79,8 +79,5 @@ struct ath6kl; enum htc_credit_dist_reason; struct ath6kl_htc_credit_info; -struct ath6kl *ath6kl_core_alloc(struct device *sdev); -int ath6kl_core_init(struct ath6kl *ar); -void ath6kl_core_cleanup(struct ath6kl *ar); struct sk_buff *ath6kl_buf_alloc(int size); #endif /* COMMON_H */ diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c new file mode 100644 index 00000000000..40fad5ec936 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2004-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "core.h" + +#include + +#include "debug.h" +#include "hif-ops.h" +#include "cfg80211.h" + +unsigned int debug_mask; +static bool suspend_cutpower; +static unsigned int uart_debug; +static unsigned int ath6kl_p2p; + +module_param(debug_mask, uint, 0644); +module_param(suspend_cutpower, bool, 0444); +module_param(uart_debug, uint, 0644); +module_param(ath6kl_p2p, uint, 0644); + +int ath6kl_core_init(struct ath6kl *ar) +{ + struct ath6kl_bmi_target_info targ_info; + struct net_device *ndev; + int ret = 0, i; + + ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); + if (!ar->ath6kl_wq) + return -ENOMEM; + + ret = ath6kl_bmi_init(ar); + if (ret) + goto err_wq; + + /* + * Turn on power to get hardware (target) version and leave power + * on delibrately as we will boot the hardware anyway within few + * seconds. + */ + ret = ath6kl_hif_power_on(ar); + if (ret) + goto err_bmi_cleanup; + + ret = ath6kl_bmi_get_target_info(ar, &targ_info); + if (ret) + goto err_power_off; + + ar->version.target_ver = le32_to_cpu(targ_info.version); + ar->target_type = le32_to_cpu(targ_info.type); + ar->wiphy->hw_version = le32_to_cpu(targ_info.version); + + ret = ath6kl_init_hw_params(ar); + if (ret) + goto err_power_off; + + ar->htc_target = ath6kl_htc_create(ar); + + if (!ar->htc_target) { + ret = -ENOMEM; + goto err_power_off; + } + + ret = ath6kl_init_fetch_firmwares(ar); + if (ret) + goto err_htc_cleanup; + + /* FIXME: we should free all firmwares in the error cases below */ + + /* Indicate that WMI is enabled (although not ready yet) */ + set_bit(WMI_ENABLED, &ar->flag); + ar->wmi = ath6kl_wmi_init(ar); + if (!ar->wmi) { + ath6kl_err("failed to initialize wmi\n"); + ret = -EIO; + goto err_htc_cleanup; + } + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); + + ret = ath6kl_cfg80211_init(ar); + if (ret) + goto err_node_cleanup; + + ret = ath6kl_debug_init(ar); + if (ret) { + wiphy_unregister(ar->wiphy); + goto err_node_cleanup; + } + + for (i = 0; i < ar->vif_max; i++) + ar->avail_idx_map |= BIT(i); + + rtnl_lock(); + + /* Add an initial station interface */ + ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, + INFRA_NETWORK); + + rtnl_unlock(); + + if (!ndev) { + ath6kl_err("Failed to instantiate a network device\n"); + ret = -ENOMEM; + wiphy_unregister(ar->wiphy); + goto err_debug_init; + } + + + ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", + __func__, ndev->name, ndev, ar); + + /* setup access class priority mappings */ + ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ + ar->ac_stream_pri_map[WMM_AC_BE] = 1; + ar->ac_stream_pri_map[WMM_AC_VI] = 2; + ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ + + /* give our connected endpoints some buffers */ + ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); + ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); + + /* allocate some buffers that handle larger AMSDU frames */ + ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); + + ath6kl_cookie_init(ar); + + ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | + ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; + + if (suspend_cutpower) + ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + + if (uart_debug) + ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; + + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | + WIPHY_FLAG_HAVE_AP_SME | + WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | + WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; + + if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) + ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; + + ar->wiphy->probe_resp_offload = + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | + NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; + + set_bit(FIRST_BOOT, &ar->flag); + + ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; + + ret = ath6kl_init_hw_start(ar); + if (ret) { + ath6kl_err("Failed to start hardware: %d\n", ret); + goto err_rxbuf_cleanup; + } + + /* + * Set mac address which is received in ready event + * FIXME: Move to ath6kl_interface_add() + */ + memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); + + return ret; + +err_rxbuf_cleanup: + ath6kl_htc_flush_rx_buf(ar->htc_target); + ath6kl_cleanup_amsdu_rxbufs(ar); + rtnl_lock(); + ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); + rtnl_unlock(); + wiphy_unregister(ar->wiphy); +err_debug_init: + ath6kl_debug_cleanup(ar); +err_node_cleanup: + ath6kl_wmi_shutdown(ar->wmi); + clear_bit(WMI_ENABLED, &ar->flag); + ar->wmi = NULL; +err_htc_cleanup: + ath6kl_htc_cleanup(ar->htc_target); +err_power_off: + ath6kl_hif_power_off(ar); +err_bmi_cleanup: + ath6kl_bmi_cleanup(ar); +err_wq: + destroy_workqueue(ar->ath6kl_wq); + + return ret; +} + +struct ath6kl *ath6kl_core_create(struct device *dev) +{ + struct ath6kl *ar; + u8 ctr; + + ar = ath6kl_cfg80211_create(); + if (!ar) + return NULL; + + ar->p2p = !!ath6kl_p2p; + ar->dev = dev; + + ar->vif_max = 1; + + ar->max_norm_iface = 1; + + spin_lock_init(&ar->lock); + spin_lock_init(&ar->mcastpsq_lock); + spin_lock_init(&ar->list_lock); + + init_waitqueue_head(&ar->event_wq); + sema_init(&ar->sem, 1); + + INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue); + INIT_LIST_HEAD(&ar->vif_list); + + clear_bit(WMI_ENABLED, &ar->flag); + clear_bit(SKIP_SCAN, &ar->flag); + clear_bit(DESTROY_IN_PROGRESS, &ar->flag); + + ar->listen_intvl_b = A_DEFAULT_LISTEN_INTERVAL; + ar->tx_pwr = 0; + + ar->intra_bss = 1; + ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD; + + ar->state = ATH6KL_STATE_OFF; + + memset((u8 *)ar->sta_list, 0, + AP_MAX_NUM_STA * sizeof(struct ath6kl_sta)); + + /* Init the PS queues */ + for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { + spin_lock_init(&ar->sta_list[ctr].psq_lock); + skb_queue_head_init(&ar->sta_list[ctr].psq); + skb_queue_head_init(&ar->sta_list[ctr].apsdq); + } + + skb_queue_head_init(&ar->mcastpsq); + + memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); + + return ar; +} + +void ath6kl_core_cleanup(struct ath6kl *ar) +{ + ath6kl_hif_power_off(ar); + + destroy_workqueue(ar->ath6kl_wq); + + if (ar->htc_target) + ath6kl_htc_cleanup(ar->htc_target); + + ath6kl_cookie_cleanup(ar); + + ath6kl_cleanup_amsdu_rxbufs(ar); + + ath6kl_bmi_cleanup(ar); + + ath6kl_debug_cleanup(ar); + + kfree(ar->fw_board); + kfree(ar->fw_otp); + kfree(ar->fw); + kfree(ar->fw_patch); + kfree(ar->fw_testscript); + + ath6kl_cfg80211_cleanup(ar); +} + +void ath6kl_core_destroy(struct ath6kl *ar) +{ + ath6kl_cfg80211_destroy(ar); +} + diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 78c0402e2d3..67b22e4bbcc 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -754,11 +754,18 @@ void ath6kl_wakeup_event(void *dev); void ath6kl_reset_device(struct ath6kl *ar, u32 target_type, bool wait_fot_compltn, bool cold_reset); void ath6kl_init_control_info(struct ath6kl_vif *vif); -void ath6kl_core_free(struct ath6kl *ar); struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar); void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready); int ath6kl_init_hw_start(struct ath6kl *ar); int ath6kl_init_hw_stop(struct ath6kl *ar); +int ath6kl_init_fetch_firmwares(struct ath6kl *ar); +int ath6kl_init_hw_params(struct ath6kl *ar); + void ath6kl_check_wow_status(struct ath6kl *ar); +struct ath6kl *ath6kl_core_create(struct device *dev); +int ath6kl_core_init(struct ath6kl *ar); +void ath6kl_core_cleanup(struct ath6kl *ar); +void ath6kl_core_destroy(struct ath6kl *ar); + #endif /* CORE_H */ diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 2804921d5d8..b8252ced096 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -25,15 +25,9 @@ #include "debug.h" #include "hif-ops.h" -unsigned int debug_mask; static unsigned int testmode; -static bool suspend_cutpower; -static unsigned int uart_debug; -module_param(debug_mask, uint, 0644); module_param(testmode, uint, 0644); -module_param(suspend_cutpower, bool, 0444); -module_param(uart_debug, uint, 0644); static const struct ath6kl_hw hw_list[] = { { @@ -597,37 +591,6 @@ int ath6kl_configure_target(struct ath6kl *ar) return 0; } -void ath6kl_core_free(struct ath6kl *ar) -{ - wiphy_free(ar->wiphy); -} - -void ath6kl_core_cleanup(struct ath6kl *ar) -{ - ath6kl_hif_power_off(ar); - - destroy_workqueue(ar->ath6kl_wq); - - if (ar->htc_target) - ath6kl_htc_cleanup(ar->htc_target); - - ath6kl_cookie_cleanup(ar); - - ath6kl_cleanup_amsdu_rxbufs(ar); - - ath6kl_bmi_cleanup(ar); - - ath6kl_debug_cleanup(ar); - - kfree(ar->fw_board); - kfree(ar->fw_otp); - kfree(ar->fw); - kfree(ar->fw_patch); - kfree(ar->fw_testscript); - - ath6kl_cfg80211_cleanup(ar); -} - /* firmware upload */ static int ath6kl_get_fw(struct ath6kl *ar, const char *filename, u8 **fw, size_t *fw_len) @@ -1065,7 +1028,7 @@ out: return ret; } -static int ath6kl_fetch_firmwares(struct ath6kl *ar) +int ath6kl_init_fetch_firmwares(struct ath6kl *ar) { int ret; @@ -1485,7 +1448,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) return status; } -static int ath6kl_init_hw_params(struct ath6kl *ar) +int ath6kl_init_hw_params(struct ath6kl *ar) { const struct ath6kl_hw *hw; int i; @@ -1663,178 +1626,6 @@ int ath6kl_init_hw_stop(struct ath6kl *ar) return 0; } -int ath6kl_core_init(struct ath6kl *ar) -{ - struct ath6kl_bmi_target_info targ_info; - struct net_device *ndev; - int ret = 0, i; - - ar->ath6kl_wq = create_singlethread_workqueue("ath6kl"); - if (!ar->ath6kl_wq) - return -ENOMEM; - - ret = ath6kl_bmi_init(ar); - if (ret) - goto err_wq; - - /* - * Turn on power to get hardware (target) version and leave power - * on delibrately as we will boot the hardware anyway within few - * seconds. - */ - ret = ath6kl_hif_power_on(ar); - if (ret) - goto err_bmi_cleanup; - - ret = ath6kl_bmi_get_target_info(ar, &targ_info); - if (ret) - goto err_power_off; - - ar->version.target_ver = le32_to_cpu(targ_info.version); - ar->target_type = le32_to_cpu(targ_info.type); - ar->wiphy->hw_version = le32_to_cpu(targ_info.version); - - ret = ath6kl_init_hw_params(ar); - if (ret) - goto err_power_off; - - ar->htc_target = ath6kl_htc_create(ar); - - if (!ar->htc_target) { - ret = -ENOMEM; - goto err_power_off; - } - - ret = ath6kl_fetch_firmwares(ar); - if (ret) - goto err_htc_cleanup; - - /* FIXME: we should free all firmwares in the error cases below */ - - /* Indicate that WMI is enabled (although not ready yet) */ - set_bit(WMI_ENABLED, &ar->flag); - ar->wmi = ath6kl_wmi_init(ar); - if (!ar->wmi) { - ath6kl_err("failed to initialize wmi\n"); - ret = -EIO; - goto err_htc_cleanup; - } - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi); - - ret = ath6kl_cfg80211_init(ar); - if (ret) - goto err_node_cleanup; - - ret = ath6kl_debug_init(ar); - if (ret) { - wiphy_unregister(ar->wiphy); - goto err_node_cleanup; - } - - for (i = 0; i < ar->vif_max; i++) - ar->avail_idx_map |= BIT(i); - - rtnl_lock(); - - /* Add an initial station interface */ - ndev = ath6kl_interface_add(ar, "wlan%d", NL80211_IFTYPE_STATION, 0, - INFRA_NETWORK); - - rtnl_unlock(); - - if (!ndev) { - ath6kl_err("Failed to instantiate a network device\n"); - ret = -ENOMEM; - wiphy_unregister(ar->wiphy); - goto err_debug_init; - } - - - ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n", - __func__, ndev->name, ndev, ar); - - /* setup access class priority mappings */ - ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */ - ar->ac_stream_pri_map[WMM_AC_BE] = 1; - ar->ac_stream_pri_map[WMM_AC_VI] = 2; - ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */ - - /* give our connected endpoints some buffers */ - ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep); - ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]); - - /* allocate some buffers that handle larger AMSDU frames */ - ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS); - - ath6kl_cookie_init(ar); - - ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | - ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; - - if (uart_debug) - ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; - - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM | - WIPHY_FLAG_HAVE_AP_SME | - WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | - WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; - - if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities)) - ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN; - - ar->wiphy->probe_resp_offload = - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P | - NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U; - - set_bit(FIRST_BOOT, &ar->flag); - - ndev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM; - - ret = ath6kl_init_hw_start(ar); - if (ret) { - ath6kl_err("Failed to start hardware: %d\n", ret); - goto err_rxbuf_cleanup; - } - - /* - * Set mac address which is received in ready event - * FIXME: Move to ath6kl_interface_add() - */ - memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN); - - return ret; - -err_rxbuf_cleanup: - ath6kl_htc_flush_rx_buf(ar->htc_target); - ath6kl_cleanup_amsdu_rxbufs(ar); - rtnl_lock(); - ath6kl_cfg80211_vif_cleanup(netdev_priv(ndev)); - rtnl_unlock(); - wiphy_unregister(ar->wiphy); -err_debug_init: - ath6kl_debug_cleanup(ar); -err_node_cleanup: - ath6kl_wmi_shutdown(ar->wmi); - clear_bit(WMI_ENABLED, &ar->flag); - ar->wmi = NULL; -err_htc_cleanup: - ath6kl_htc_cleanup(ar->htc_target); -err_power_off: - ath6kl_hif_power_off(ar); -err_bmi_cleanup: - ath6kl_bmi_cleanup(ar); -err_wq: - destroy_workqueue(ar->ath6kl_wq); - - return ret; -} - /* FIXME: move this to cfg80211.c and rename to ath6kl_cfg80211_vif_stop() */ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) { diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 662b47dc71e..bef32ecea79 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1261,7 +1261,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]); - ar = ath6kl_core_alloc(&ar_sdio->func->dev); + ar = ath6kl_core_create(&ar_sdio->func->dev); if (!ar) { ath6kl_err("Failed to alloc ath6kl core\n"); ret = -ENOMEM; @@ -1291,7 +1291,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, return ret; err_core_alloc: - ath6kl_core_free(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); err_dma: kfree(ar_sdio->dma_buffer); err_hif: -- cgit v1.2.3-70-g09d2 From 5afa5aa79680ee107fef1195c80f5f67c54b6691 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:19 +0200 Subject: ath6kl: get rid of AR_DBG_LVL_CHECK() We don't need it as debug calls already have a log level and compiler should be smart enough to optimise away the code when ath6kl debug code is not enabled. Also it makes it easier to abstract core code to ath6kl_core.ko. In ath6kl_dump_registers() I had to change the debug level from ANY to IRQ as I removed the AR_DBG_LVL_CHECK() check before calling the function. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 35 +++++++++++++++------------------ drivers/net/wireless/ath/ath6kl/debug.h | 2 -- drivers/net/wireless/ath/ath6kl/hif.c | 5 ++--- drivers/net/wireless/ath/ath6kl/wmi.c | 3 --- 4 files changed, 18 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index fa7243b4144..bd2f1fae72a 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -82,31 +82,31 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_enable_reg *irq_enable_reg) { - ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n")); + ath6kl_dbg(ATH6KL_DBG_IRQ, ("<------- Register Table -------->\n")); if (irq_proc_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Host Int status: 0x%x\n", irq_proc_reg->host_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "CPU Int status: 0x%x\n", irq_proc_reg->cpu_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Error Int status: 0x%x\n", irq_proc_reg->error_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status: 0x%x\n", irq_proc_reg->counter_int_status); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Mbox Frame: 0x%x\n", irq_proc_reg->mbox_frame); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead Valid: 0x%x\n", irq_proc_reg->rx_lkahd_valid); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 0: 0x%x\n", irq_proc_reg->rx_lkahd[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Rx Lookahead 1: 0x%x\n", irq_proc_reg->rx_lkahd[1]); @@ -115,16 +115,16 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, * If the target supports GMBOX hardware, dump some * additional state. */ - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX Host Int status 2: 0x%x\n", irq_proc_reg->host_int_status2); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX RX Avail: 0x%x\n", irq_proc_reg->gmbox_rx_avail); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX lookahead alias 0: 0x%x\n", irq_proc_reg->rx_gmbox_lkahd_alias[0]); - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "GMBOX lookahead alias 1: 0x%x\n", irq_proc_reg->rx_gmbox_lkahd_alias[1]); } @@ -132,13 +132,13 @@ void ath6kl_dump_registers(struct ath6kl_device *dev, } if (irq_enable_reg != NULL) { - ath6kl_dbg(ATH6KL_DBG_ANY, + ath6kl_dbg(ATH6KL_DBG_IRQ, "Int status Enable: 0x%x\n", irq_enable_reg->int_status_en); - ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n", + ath6kl_dbg(ATH6KL_DBG_IRQ, "Counter Int status Enable: 0x%x\n", irq_enable_reg->cntr_int_status_en); } - ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n"); + ath6kl_dbg(ATH6KL_DBG_IRQ, "<------------------------------->\n"); } static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist) @@ -175,9 +175,6 @@ void dump_cred_dist_stats(struct htc_target *target) { struct htc_endpoint_credit_dist *ep_list; - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_CREDIT)) - return; - list_for_each_entry(ep_list, &target->cred_dist_list, list) dump_cred_dist(ep_list); diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9853c9c125c..9dc39754a35 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -55,8 +55,6 @@ int ath6kl_printk(const char *level, const char *fmt, ...); #define ath6kl_warn(fmt, ...) \ ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__) -#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask) - enum ath6kl_war { ATH6KL_WAR_INVALID_RATE, }; diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index e57da35e59f..711886860b5 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -429,9 +429,8 @@ static int proc_pending_irqs(struct ath6kl_device *dev, bool *done) if (status) goto out; - if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ)) - ath6kl_dump_registers(dev, &dev->irq_proc_reg, - &dev->irq_en_reg); + ath6kl_dump_registers(dev, &dev->irq_proc_reg, + &dev->irq_en_reg); /* Update only those registers that are enabled */ host_int_status = dev->irq_proc_reg.host_int_status & diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index c2420f886ed..5d678bf372d 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -426,9 +426,6 @@ static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len) ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n", evt->num_msg, evt->msg_len, evt->msg_type); - if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI)) - return 0; - for (index = 0; index < evt->num_msg; index++) { size = sizeof(struct wmi_tx_complete_event) + (index * sizeof(struct tx_complete_msg_v1)); -- cgit v1.2.3-70-g09d2 From 3b1b7d0985fdb26403678e49938a668ef7f772ea Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:27 +0200 Subject: ath6kl: convert ath6kl_dbg() and ath6kl_dbg_dump() into functions That way it's possible to not export debug_mask outside the upcoming ath6kl_core.ko and that makes it easier to ath6kl_core.ko in the following patch. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 30 ++++++++++++++++++++++++++++++ drivers/net/wireless/ath/ath6kl/debug.h | 25 ++++--------------------- 2 files changed, 34 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index bd2f1fae72a..4ba6560f0bf 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -57,6 +57,36 @@ int ath6kl_printk(const char *level, const char *fmt, ...) #ifdef CONFIG_ATH6KL_DEBUG +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + if (!(debug_mask & mask)) + return; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + ath6kl_printk(KERN_DEBUG, "%pV", &vaf); + + va_end(args); +} + +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len) +{ + if (debug_mask & mask) { + if (msg) + ath6kl_dbg(mask, "%s\n", msg); + + print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); + } +} + #define REG_OUTPUT_LEN_PER_LINE 25 #define REGTYPE_STR_LEN 100 diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 9dc39754a35..872a8ce5d8f 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -60,28 +60,11 @@ enum ath6kl_war { }; #ifdef CONFIG_ATH6KL_DEBUG -#define ath6kl_dbg(mask, fmt, ...) \ - ({ \ - int rtn; \ - if (debug_mask & mask) \ - rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \ - else \ - rtn = 0; \ - \ - rtn; \ - }) -static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, - const char *msg, const char *prefix, - const void *buf, size_t len) -{ - if (debug_mask & mask) { - if (msg) - ath6kl_dbg(mask, "%s\n", msg); - - print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); - } -} +void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...); +void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, + const char *msg, const char *prefix, + const void *buf, size_t len); void ath6kl_dump_registers(struct ath6kl_device *dev, struct ath6kl_irq_proc_registers *irq_proc_reg, -- cgit v1.2.3-70-g09d2 From d6a434d60e064a5f2bef1c13ca5ed84bfa6b8b4f Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:36 +0200 Subject: ath6kl: create ath6kl_core.ko Now ath6kl is ready for splitting core code to ath6kl_core.ko module. This also makes it possible to link both sdio and usb code to kernel at the same time, which earlier failed miserably. Reported-by: Stephen Rothwell Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Makefile | 28 +++++++++++++++------------- drivers/net/wireless/ath/ath6kl/cfg80211.c | 3 +++ drivers/net/wireless/ath/ath6kl/core.c | 9 +++++++++ drivers/net/wireless/ath/ath6kl/debug.c | 3 +++ drivers/net/wireless/ath/ath6kl/hif.c | 5 +++++ drivers/net/wireless/ath/ath6kl/init.c | 3 +++ 6 files changed, 38 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index 854694b26a4..cbdc31c603f 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -21,16 +21,18 @@ # Author(s): ="Atheros" #------------------------------------------------------------------------------ -obj-$(CONFIG_ATH6KL) := ath6kl.o -ath6kl-y += debug.o -ath6kl-y += hif.o -ath6kl-y += htc.o -ath6kl-y += bmi.o -ath6kl-y += cfg80211.o -ath6kl-y += init.o -ath6kl-y += main.o -ath6kl-y += txrx.o -ath6kl-y += wmi.o -ath6kl-y += core.o -ath6kl-y += sdio.o -ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o +obj-$(CONFIG_ATH6KL) += ath6kl_core.o +ath6kl_core-y += debug.o +ath6kl_core-y += hif.o +ath6kl_core-y += htc.o +ath6kl_core-y += bmi.o +ath6kl_core-y += cfg80211.o +ath6kl_core-y += init.o +ath6kl_core-y += main.o +ath6kl_core-y += txrx.o +ath6kl_core-y += wmi.o +ath6kl_core-y += core.o +ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o + +obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o +ath6kl_sdio-y += sdio.o diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 7ff9806de50..594d246da8e 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -16,6 +16,7 @@ #include #include +#include #include "core.h" #include "cfg80211.h" @@ -1935,6 +1936,7 @@ int ath6kl_cfg80211_suspend(struct ath6kl *ar, return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_suspend); int ath6kl_cfg80211_resume(struct ath6kl *ar) { @@ -1986,6 +1988,7 @@ int ath6kl_cfg80211_resume(struct ath6kl *ar) return 0; } +EXPORT_SYMBOL(ath6kl_cfg80211_resume); #ifdef CONFIG_PM diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 40fad5ec936..d764afec395 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -16,7 +16,9 @@ #include "core.h" +#include #include +#include #include "debug.h" #include "hif-ops.h" @@ -203,6 +205,7 @@ err_wq: return ret; } +EXPORT_SYMBOL(ath6kl_core_init); struct ath6kl *ath6kl_core_create(struct device *dev) { @@ -258,6 +261,7 @@ struct ath6kl *ath6kl_core_create(struct device *dev) return ar; } +EXPORT_SYMBOL(ath6kl_core_create); void ath6kl_core_cleanup(struct ath6kl *ar) { @@ -284,9 +288,14 @@ void ath6kl_core_cleanup(struct ath6kl *ar) ath6kl_cfg80211_cleanup(ar); } +EXPORT_SYMBOL(ath6kl_core_cleanup); void ath6kl_core_destroy(struct ath6kl *ar) { ath6kl_cfg80211_destroy(ar); } +EXPORT_SYMBOL(ath6kl_core_destroy); +MODULE_AUTHOR("Qualcomm Atheros"); +MODULE_DESCRIPTION("Core module for AR600x SDIO and USB devices."); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 4ba6560f0bf..6b546dc6672 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -54,6 +54,7 @@ int ath6kl_printk(const char *level, const char *fmt, ...) return rtn; } +EXPORT_SYMBOL(ath6kl_printk); #ifdef CONFIG_ATH6KL_DEBUG @@ -74,6 +75,7 @@ void ath6kl_dbg(enum ATH6K_DEBUG_MASK mask, const char *fmt, ...) va_end(args); } +EXPORT_SYMBOL(ath6kl_dbg); void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, const char *msg, const char *prefix, @@ -86,6 +88,7 @@ void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask, print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); } } +EXPORT_SYMBOL(ath6kl_dbg_dump); #define REG_OUTPUT_LEN_PER_LINE 25 #define REGTYPE_STR_LEN 100 diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index 711886860b5..d912da6ab0d 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -15,6 +15,8 @@ */ #include "hif.h" +#include + #include "core.h" #include "target.h" #include "hif-ops.h" @@ -59,6 +61,8 @@ int ath6kl_hif_rw_comp_handler(void *context, int status) return 0; } +EXPORT_SYMBOL(ath6kl_hif_rw_comp_handler); + #define REG_DUMP_COUNT_AR6003 60 #define REGISTER_DUMP_LEN_MAX 60 @@ -560,6 +564,7 @@ int ath6kl_hif_intr_bh_handler(struct ath6kl *ar) return status; } +EXPORT_SYMBOL(ath6kl_hif_intr_bh_handler); static int ath6kl_hif_enable_intrs(struct ath6kl_device *dev) { diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index b8252ced096..167dc41af2d 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -17,8 +17,10 @@ #include #include +#include #include #include + #include "core.h" #include "cfg80211.h" #include "target.h" @@ -1707,3 +1709,4 @@ void ath6kl_stop_txrx(struct ath6kl *ar) clear_bit(WLAN_ENABLED, &ar->flag); } +EXPORT_SYMBOL(ath6kl_stop_txrx); -- cgit v1.2.3-70-g09d2 From 241b128b6b69ad41fc6f12cba45a3c3e64bce673 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 17 Jan 2012 20:09:45 +0200 Subject: ath6kl: add back beginnings of USB support John Linville had to revert the part of USB support which was already in ath6kl due to build problems in commit cb00ec382b ("ath6kl: revert USB support"). Now that I fixed the build problems properly by adding ath6kl_core.ko kernel module it's possible to add back the (incomplete) USB support. This patch is a revert of John's patch and adds back the USB code which as already in ath6kl, only difference being minor changes in Makefile and adapting usb.c to new core function names. Note that USB support in ath6kl is not complete yet. This code only makes it possible to boot firmware but as HTC layer does not yet support USB it's not possible to send any WMI commands nor data packets to the firmware. That will be added soon. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/Kconfig | 25 +- drivers/net/wireless/ath/ath6kl/Makefile | 3 + drivers/net/wireless/ath/ath6kl/bmi.c | 10 +- drivers/net/wireless/ath/ath6kl/debug.h | 1 + drivers/net/wireless/ath/ath6kl/hif.c | 5 + drivers/net/wireless/ath/ath6kl/htc.c | 10 +- drivers/net/wireless/ath/ath6kl/sdio.c | 2 +- drivers/net/wireless/ath/ath6kl/usb.c | 431 +++++++++++++++++++++++++++++++ 8 files changed, 479 insertions(+), 8 deletions(-) create mode 100644 drivers/net/wireless/ath/ath6kl/usb.c (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig index 3d5f8be20ea..d755a5e7ed2 100644 --- a/drivers/net/wireless/ath/ath6kl/Kconfig +++ b/drivers/net/wireless/ath/ath6kl/Kconfig @@ -1,12 +1,29 @@ config ATH6KL - tristate "Atheros ath6kl support" + tristate "Atheros mobile chipsets support" + +config ATH6KL_SDIO + tristate "Atheros ath6kl SDIO support" + depends on ATH6KL depends on MMC depends on CFG80211 ---help--- This module adds support for wireless adapters based on - Atheros AR6003 chipset running over SDIO. If you choose to - build it as a module, it will be called ath6kl. Pls note - that AR6002 and AR6001 are not supported by this driver. + Atheros AR6003 and AR6004 chipsets running over SDIO. If you + choose to build it as a module, it will be called ath6kl_sdio. + Please note that AR6002 and AR6001 are not supported by this + driver. + +config ATH6KL_USB + tristate "Atheros ath6kl USB support" + depends on ATH6KL + depends on USB + depends on CFG80211 + depends on EXPERIMENTAL + ---help--- + This module adds support for wireless adapters based on + Atheros AR6004 chipset running over USB. This is still under + implementation and it isn't functional. If you choose to + build it as a module, it will be called ath6kl_usb. config ATH6KL_DEBUG bool "Atheros ath6kl debugging" diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile index cbdc31c603f..9ba42fa0496 100644 --- a/drivers/net/wireless/ath/ath6kl/Makefile +++ b/drivers/net/wireless/ath/ath6kl/Makefile @@ -36,3 +36,6 @@ ath6kl_core-$(CONFIG_NL80211_TESTMODE) += testmode.o obj-$(CONFIG_ATH6KL_SDIO) += ath6kl_sdio.o ath6kl_sdio-y += sdio.o + +obj-$(CONFIG_ATH6KL_USB) += ath6kl_usb.o +ath6kl_usb-y += usb.o diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c index bce3575c310..aef00d5a143 100644 --- a/drivers/net/wireless/ath/ath6kl/bmi.c +++ b/drivers/net/wireless/ath/ath6kl/bmi.c @@ -57,8 +57,14 @@ int ath6kl_bmi_get_target_info(struct ath6kl *ar, return ret; } - ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, - sizeof(targ_info->version)); + if (ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ret = ath6kl_hif_bmi_read(ar, (u8 *)targ_info, + sizeof(*targ_info)); + } else { + ret = ath6kl_hif_bmi_read(ar, (u8 *)&targ_info->version, + sizeof(targ_info->version)); + } + if (ret) { ath6kl_err("Unable to recv target info: %d\n", ret); return ret; diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h index 872a8ce5d8f..c4be6e50996 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.h +++ b/drivers/net/wireless/ath/ath6kl/debug.h @@ -41,6 +41,7 @@ enum ATH6K_DEBUG_MASK { ATH6KL_DBG_BOOT = BIT(18), /* driver init and fw boot */ ATH6KL_DBG_WMI_DUMP = BIT(19), ATH6KL_DBG_SUSPEND = BIT(20), + ATH6KL_DBG_USB = BIT(21), ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */ }; diff --git a/drivers/net/wireless/ath/ath6kl/hif.c b/drivers/net/wireless/ath/ath6kl/hif.c index d912da6ab0d..e911737ab34 100644 --- a/drivers/net/wireless/ath/ath6kl/hif.c +++ b/drivers/net/wireless/ath/ath6kl/hif.c @@ -693,6 +693,11 @@ int ath6kl_hif_setup(struct ath6kl_device *dev) ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n", dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr); + /* usb doesn't support enabling interrupts */ + /* FIXME: remove check once USB support is implemented */ + if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) + return 0; + status = ath6kl_hif_disable_intrs(dev); fail_setup: diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c index 073ddff3134..2d721903640 100644 --- a/drivers/net/wireless/ath/ath6kl/htc.c +++ b/drivers/net/wireless/ath/ath6kl/htc.c @@ -2544,6 +2544,12 @@ int ath6kl_htc_wait_target(struct htc_target *target) struct htc_service_connect_resp resp; int status; + /* FIXME: remove once USB support is implemented */ + if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) { + ath6kl_err("HTC doesn't support USB yet. Patience!\n"); + return -EOPNOTSUPP; + } + /* we should be getting 1 control message that the target is ready */ packet = htc_wait_for_ctrl_msg(target); @@ -2773,7 +2779,9 @@ void ath6kl_htc_cleanup(struct htc_target *target) { struct htc_packet *packet, *tmp_packet; - ath6kl_hif_cleanup_scatter(target->dev->ar); + /* FIXME: remove check once USB support is implemented */ + if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB) + ath6kl_hif_cleanup_scatter(target->dev->ar); list_for_each_entry_safe(packet, tmp_packet, &target->free_ctrl_txbuf, list) { diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index bef32ecea79..7bb61077c40 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1330,7 +1330,7 @@ static const struct sdio_device_id ath6kl_sdio_devices[] = { MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices); static struct sdio_driver ath6kl_sdio_driver = { - .name = "ath6kl", + .name = "ath6kl_sdio", .id_table = ath6kl_sdio_devices, .probe = ath6kl_sdio_probe, .remove = ath6kl_sdio_remove, diff --git a/drivers/net/wireless/ath/ath6kl/usb.c b/drivers/net/wireless/ath/ath6kl/usb.c new file mode 100644 index 00000000000..c72567c6d33 --- /dev/null +++ b/drivers/net/wireless/ath/ath6kl/usb.c @@ -0,0 +1,431 @@ +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#include "debug.h" +#include "core.h" + +/* usb device object */ +struct ath6kl_usb { + struct usb_device *udev; + struct usb_interface *interface; + u8 *diag_cmd_buffer; + u8 *diag_resp_buffer; + struct ath6kl *ar; +}; + +/* diagnostic command defnitions */ +#define ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD 1 +#define ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP 2 +#define ATH6KL_USB_CONTROL_REQ_DIAG_CMD 3 +#define ATH6KL_USB_CONTROL_REQ_DIAG_RESP 4 + +#define ATH6KL_USB_CTRL_DIAG_CC_READ 0 +#define ATH6KL_USB_CTRL_DIAG_CC_WRITE 1 + +struct ath6kl_usb_ctrl_diag_cmd_write { + __le32 cmd; + __le32 address; + __le32 value; + __le32 _pad[1]; +} __packed; + +struct ath6kl_usb_ctrl_diag_cmd_read { + __le32 cmd; + __le32 address; +} __packed; + +struct ath6kl_usb_ctrl_diag_resp_read { + __le32 value; +} __packed; + +#define ATH6KL_USB_MAX_DIAG_CMD (sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)) +#define ATH6KL_USB_MAX_DIAG_RESP (sizeof(struct ath6kl_usb_ctrl_diag_resp_read)) + +static void ath6kl_usb_destroy(struct ath6kl_usb *ar_usb) +{ + usb_set_intfdata(ar_usb->interface, NULL); + + kfree(ar_usb->diag_cmd_buffer); + kfree(ar_usb->diag_resp_buffer); + + kfree(ar_usb); +} + +static struct ath6kl_usb *ath6kl_usb_create(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb = NULL; + struct usb_device *dev = interface_to_usbdev(interface); + int status = 0; + + ar_usb = kzalloc(sizeof(struct ath6kl_usb), GFP_KERNEL); + if (ar_usb == NULL) + goto fail_ath6kl_usb_create; + + memset(ar_usb, 0, sizeof(struct ath6kl_usb)); + usb_set_intfdata(interface, ar_usb); + ar_usb->udev = dev; + ar_usb->interface = interface; + + ar_usb->diag_cmd_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_CMD, GFP_KERNEL); + if (ar_usb->diag_cmd_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + + ar_usb->diag_resp_buffer = kzalloc(ATH6KL_USB_MAX_DIAG_RESP, + GFP_KERNEL); + if (ar_usb->diag_resp_buffer == NULL) { + status = -ENOMEM; + goto fail_ath6kl_usb_create; + } + +fail_ath6kl_usb_create: + if (status != 0) { + ath6kl_usb_destroy(ar_usb); + ar_usb = NULL; + } + return ar_usb; +} + +static void ath6kl_usb_device_detached(struct usb_interface *interface) +{ + struct ath6kl_usb *ar_usb; + + ar_usb = usb_get_intfdata(interface); + if (ar_usb == NULL) + return; + + ath6kl_stop_txrx(ar_usb->ar); + + ath6kl_core_cleanup(ar_usb->ar); + + ath6kl_usb_destroy(ar_usb); +} + +static int ath6kl_usb_submit_ctrl_out(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, data, size); + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_sndctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 1000); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_submit_ctrl_in(struct ath6kl_usb *ar_usb, + u8 req, u16 value, u16 index, void *data, + u32 size) +{ + u8 *buf = NULL; + int ret; + + if (size > 0) { + buf = kmalloc(size, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + } + + /* note: if successful returns number of bytes transfered */ + ret = usb_control_msg(ar_usb->udev, + usb_rcvctrlpipe(ar_usb->udev, 0), + req, + USB_DIR_IN | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, buf, + size, 2 * HZ); + + if (ret < 0) { + ath6kl_dbg(ATH6KL_DBG_USB, "%s failed,result = %d\n", + __func__, ret); + } + + memcpy((u8 *) data, buf, size); + + kfree(buf); + + return 0; +} + +static int ath6kl_usb_ctrl_msg_exchange(struct ath6kl_usb *ar_usb, + u8 req_val, u8 *req_buf, u32 req_len, + u8 resp_val, u8 *resp_buf, u32 *resp_len) +{ + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, req_val, 0, 0, + req_buf, req_len); + + if (ret != 0) + return ret; + + if (resp_buf == NULL) { + /* no expected response */ + return ret; + } + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, resp_val, 0, 0, + resp_buf, *resp_len); + + return ret; +} + +static int ath6kl_usb_diag_read32(struct ath6kl *ar, u32 address, u32 *data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_resp_read *resp; + struct ath6kl_usb_ctrl_diag_cmd_read *cmd; + u32 resp_len; + int ret; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_read *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(*cmd)); + cmd->cmd = ATH6KL_USB_CTRL_DIAG_CC_READ; + cmd->address = cpu_to_le32(address); + resp_len = sizeof(*resp); + + ret = ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(struct ath6kl_usb_ctrl_diag_cmd_write), + ATH6KL_USB_CONTROL_REQ_DIAG_RESP, + ar_usb->diag_resp_buffer, &resp_len); + + if (ret) + return ret; + + resp = (struct ath6kl_usb_ctrl_diag_resp_read *) + ar_usb->diag_resp_buffer; + + *data = le32_to_cpu(resp->value); + + return ret; +} + +static int ath6kl_usb_diag_write32(struct ath6kl *ar, u32 address, __le32 data) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + struct ath6kl_usb_ctrl_diag_cmd_write *cmd; + + cmd = (struct ath6kl_usb_ctrl_diag_cmd_write *) ar_usb->diag_cmd_buffer; + + memset(cmd, 0, sizeof(struct ath6kl_usb_ctrl_diag_cmd_write)); + cmd->cmd = cpu_to_le32(ATH6KL_USB_CTRL_DIAG_CC_WRITE); + cmd->address = cpu_to_le32(address); + cmd->value = data; + + return ath6kl_usb_ctrl_msg_exchange(ar_usb, + ATH6KL_USB_CONTROL_REQ_DIAG_CMD, + (u8 *) cmd, + sizeof(*cmd), + 0, NULL, NULL); + +} + +static int ath6kl_usb_bmi_read(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* get response */ + ret = ath6kl_usb_submit_ctrl_in(ar_usb, + ATH6KL_USB_CONTROL_REQ_RECV_BMI_RESP, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("Unable to read the bmi data from the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_bmi_write(struct ath6kl *ar, u8 *buf, u32 len) +{ + struct ath6kl_usb *ar_usb = ar->hif_priv; + int ret; + + /* send command */ + ret = ath6kl_usb_submit_ctrl_out(ar_usb, + ATH6KL_USB_CONTROL_REQ_SEND_BMI_CMD, + 0, 0, buf, len); + if (ret != 0) { + ath6kl_err("unable to send the bmi data to the device: %d\n", + ret); + return ret; + } + + return 0; +} + +static int ath6kl_usb_power_on(struct ath6kl *ar) +{ + return 0; +} + +static int ath6kl_usb_power_off(struct ath6kl *ar) +{ + return 0; +} + +static const struct ath6kl_hif_ops ath6kl_usb_ops = { + .diag_read32 = ath6kl_usb_diag_read32, + .diag_write32 = ath6kl_usb_diag_write32, + .bmi_read = ath6kl_usb_bmi_read, + .bmi_write = ath6kl_usb_bmi_write, + .power_on = ath6kl_usb_power_on, + .power_off = ath6kl_usb_power_off, +}; + +/* ath6kl usb driver registered functions */ +static int ath6kl_usb_probe(struct usb_interface *interface, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(interface); + struct ath6kl *ar; + struct ath6kl_usb *ar_usb = NULL; + int vendor_id, product_id; + int ret = 0; + + usb_get_dev(dev); + + vendor_id = le16_to_cpu(dev->descriptor.idVendor); + product_id = le16_to_cpu(dev->descriptor.idProduct); + + ath6kl_dbg(ATH6KL_DBG_USB, "vendor_id = %04x\n", vendor_id); + ath6kl_dbg(ATH6KL_DBG_USB, "product_id = %04x\n", product_id); + + if (interface->cur_altsetting) + ath6kl_dbg(ATH6KL_DBG_USB, "USB Interface %d\n", + interface->cur_altsetting->desc.bInterfaceNumber); + + + if (dev->speed == USB_SPEED_HIGH) + ath6kl_dbg(ATH6KL_DBG_USB, "USB 2.0 Host\n"); + else + ath6kl_dbg(ATH6KL_DBG_USB, "USB 1.1 Host\n"); + + ar_usb = ath6kl_usb_create(interface); + + if (ar_usb == NULL) { + ret = -ENOMEM; + goto err_usb_put; + } + + ar = ath6kl_core_create(&ar_usb->udev->dev); + if (ar == NULL) { + ath6kl_err("Failed to alloc ath6kl core\n"); + ret = -ENOMEM; + goto err_usb_destroy; + } + + ar->hif_priv = ar_usb; + ar->hif_type = ATH6KL_HIF_TYPE_USB; + ar->hif_ops = &ath6kl_usb_ops; + ar->mbox_info.block_size = 16; + ar->bmi.max_data_size = 252; + + ar_usb->ar = ar; + + ret = ath6kl_core_init(ar); + if (ret) { + ath6kl_err("Failed to init ath6kl core: %d\n", ret); + goto err_core_free; + } + + return ret; + +err_core_free: + ath6kl_core_destroy(ar); +err_usb_destroy: + ath6kl_usb_destroy(ar_usb); +err_usb_put: + usb_put_dev(dev); + + return ret; +} + +static void ath6kl_usb_remove(struct usb_interface *interface) +{ + usb_put_dev(interface_to_usbdev(interface)); + ath6kl_usb_device_detached(interface); +} + +/* table of devices that work with this driver */ +static struct usb_device_id ath6kl_usb_ids[] = { + {USB_DEVICE(0x0cf3, 0x9374)}, + { /* Terminating entry */ }, +}; + +MODULE_DEVICE_TABLE(usb, ath6kl_usb_ids); + +static struct usb_driver ath6kl_usb_driver = { + .name = "ath6kl_usb", + .probe = ath6kl_usb_probe, + .disconnect = ath6kl_usb_remove, + .id_table = ath6kl_usb_ids, +}; + +static int ath6kl_usb_init(void) +{ + usb_register(&ath6kl_usb_driver); + return 0; +} + +static void ath6kl_usb_exit(void) +{ + usb_deregister(&ath6kl_usb_driver); +} + +module_init(ath6kl_usb_init); +module_exit(ath6kl_usb_exit); + +MODULE_AUTHOR("Atheros Communications, Inc."); +MODULE_DESCRIPTION("Driver support for Atheros AR600x USB devices"); +MODULE_LICENSE("Dual BSD/GPL"); +MODULE_FIRMWARE(AR6004_HW_1_0_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_0_DEFAULT_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_FIRMWARE_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_BOARD_DATA_FILE); +MODULE_FIRMWARE(AR6004_HW_1_1_DEFAULT_BOARD_DATA_FILE); -- cgit v1.2.3-70-g09d2 From 859dd55d91d977090efbba15c7dfc82e7ed774ef Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:52:00 +0100 Subject: ARM: 7215/1: mmc: mmci: Increase max_segs from 16 to 128 A significant increase (10-20%) in performance throughput for USB mass storage is the reason for incrementing the value. By some reason the USB driver allocates buffers which requires a scattergather list to contain a lot more than 16 elements to get optimal performance. This change sets the maximum elements to 128. Tests with large reads and large writes (100 MiB) show that the throughput increase is significant for write (10% for this test) but not for read. Tests are run on a Linux host with ext4 FS on the gadget mass storage device. The sg-len still exceeds 16 for the read tests but the performance gain is low or nothing. Tested-by: Linus Walleij Signed-off-by: Per Forlin Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 79e4143ab9d..49f153e6ef7 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -160,7 +160,7 @@ (MCI_RXFIFOHALFFULLMASK | MCI_RXDATAAVLBLMASK | \ MCI_TXFIFOHALFEMPTYMASK) -#define NR_SG 16 +#define NR_SG 128 struct clk; struct variant_data; -- cgit v1.2.3-70-g09d2 From 5074d25dc97ac2d93fca7852563b7e204f03464a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:53:17 +0100 Subject: ARM: 7216/1: mmc: mmci: Do not release spinlock in request_end The patch "mmc: core: move ->request() call from atomic context", is the reason to why this change is possible. This simplifies the error handling code execution path quite a lot and potentially also fixes some error handling hang problems. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44..0e04138b175 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -166,14 +166,8 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - /* - * Need to drop the host lock here; mmc_request_done may call - * back into the driver... - */ - spin_unlock(&host->lock); pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); - spin_lock(&host->lock); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) -- cgit v1.2.3-70-g09d2 From 7d72a1d48af95211677ea83157945a8ef76b0751 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:54:55 +0100 Subject: ARM: 7217/1: mmc: mmci: Put power register deviations in variant data Use variant data to store hardware controller deviations concerning power registers to improve readability of the code. Signed-off-by: Sebastian Rasmussen Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0e04138b175..7cc89beee87 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -53,6 +53,7 @@ static unsigned int fmax = 515633; * @sdio: variant supports SDIO * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register + * @pwrreg_powerup: power up value for MMCIPOWER register */ struct variant_data { unsigned int clkreg; @@ -63,18 +64,21 @@ struct variant_data { bool sdio; bool st_clkdiv; bool blksz_datactrl16; + u32 pwrreg_powerup; }; static struct variant_data variant_arm = { .fifosize = 16 * 4, .fifohalfsize = 8 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_arm_extended_fifo = { .fifosize = 128 * 4, .fifohalfsize = 64 * 4, .datalength_bits = 16, + .pwrreg_powerup = MCI_PWR_UP, }; static struct variant_data variant_u300 = { @@ -83,6 +87,7 @@ static struct variant_data variant_u300 = { .clkreg_enable = MCI_ST_U300_HWFCEN, .datalength_bits = 16, .sdio = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500 = { @@ -93,6 +98,7 @@ static struct variant_data variant_ux500 = { .datalength_bits = 24, .sdio = true, .st_clkdiv = true, + .pwrreg_powerup = MCI_PWR_ON, }; static struct variant_data variant_ux500v2 = { @@ -104,6 +110,7 @@ static struct variant_data variant_ux500v2 = { .sdio = true, .st_clkdiv = true, .blksz_datactrl16 = true, + .pwrreg_powerup = MCI_PWR_ON, }; /* @@ -1009,6 +1016,7 @@ static void mmci_request(struct mmc_host *mmc, struct mmc_request *mrq) static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) { struct mmci_host *host = mmc_priv(mmc); + struct variant_data *variant = host->variant; u32 pwr = 0; unsigned long flags; int ret; @@ -1035,11 +1043,15 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) if (host->plat->vdd_handler) pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, ios->power_mode); - /* The ST version does not have this, fall through to POWER_ON */ - if (host->hw_designer != AMBA_VENDOR_ST) { - pwr |= MCI_PWR_UP; - break; - } + + /* + * The ST Micro variant doesn't have the PL180s MCI_PWR_UP + * and instead uses MCI_PWR_ON so apply whatever value is + * configured in the variant data. + */ + pwr |= variant->pwrreg_powerup; + + break; case MMC_POWER_ON: pwr |= MCI_PWR_ON; break; -- cgit v1.2.3-70-g09d2 From 4d1a3a0dc551cfa7304ca46e014231500f3b81a6 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:07 +0100 Subject: ARM: 7218/1: mmc: mmci: Provide option to configure bus signal direction The ST Micro variant supports bus signal direction indication. A new member in the variant struct is added for this. Moreover the actual signal direction configuration is board specific, thus the amba mmci platform data is extended with a new member to be able provide mmci with these specific board configurations. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 21 +++++++++++++++++++++ drivers/mmc/host/mmci.h | 10 ---------- include/linux/amba/mmci.h | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7cc89beee87..eb11ce61941 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -54,6 +54,7 @@ static unsigned int fmax = 515633; * @st_clkdiv: true if using a ST-specific clock divider algorithm * @blksz_datactrl16: true if Block size is at b16..b30 position in datactrl register * @pwrreg_powerup: power up value for MMCIPOWER register + * @signal_direction: input/out direction of bus signals can be indicated */ struct variant_data { unsigned int clkreg; @@ -65,6 +66,7 @@ struct variant_data { bool st_clkdiv; bool blksz_datactrl16; u32 pwrreg_powerup; + bool signal_direction; }; static struct variant_data variant_arm = { @@ -88,6 +90,7 @@ static struct variant_data variant_u300 = { .datalength_bits = 16, .sdio = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500 = { @@ -99,6 +102,7 @@ static struct variant_data variant_ux500 = { .sdio = true, .st_clkdiv = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; static struct variant_data variant_ux500v2 = { @@ -111,6 +115,7 @@ static struct variant_data variant_ux500v2 = { .st_clkdiv = true, .blksz_datactrl16 = true, .pwrreg_powerup = MCI_PWR_ON, + .signal_direction = true, }; /* @@ -1057,6 +1062,22 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) break; } + if (variant->signal_direction && ios->power_mode != MMC_POWER_OFF) { + /* + * The ST Micro variant has some additional bits + * indicating signal direction for the signals in + * the SD/MMC bus and feedback-clock usage. + */ + pwr |= host->plat->sigdir; + + if (ios->bus_width == MMC_BUS_WIDTH_4) + pwr &= ~MCI_ST_DATA74DIREN; + else if (ios->bus_width == MMC_BUS_WIDTH_1) + pwr &= (~MCI_ST_DATA74DIREN & + ~MCI_ST_DATA31DIREN & + ~MCI_ST_DATA2DIREN); + } + if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) { if (host->hw_designer != AMBA_VENDOR_ST) pwr |= MCI_ROD; diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 49f153e6ef7..89eb2e3556d 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -13,16 +13,6 @@ #define MCI_PWR_ON 0x03 #define MCI_OD (1 << 6) #define MCI_ROD (1 << 7) -/* - * The ST Micro version does not have ROD and reuse the voltage registers - * for direction settings - */ -#define MCI_ST_DATA2DIREN (1 << 2) -#define MCI_ST_CMDDIREN (1 << 3) -#define MCI_ST_DATA0DIREN (1 << 4) -#define MCI_ST_DATA31DIREN (1 << 5) -#define MCI_ST_FBCLKEN (1 << 7) -#define MCI_ST_DATA74DIREN (1 << 8) #define MMCICLOCK 0x004 #define MCI_CLK_ENABLE (1 << 8) diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index 0101e9c17fa..b51bf5fa85f 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h @@ -6,6 +6,19 @@ #include + +/* + * These defines is places here due to access is needed from machine + * configuration files. The ST Micro version does not have ROD and + * reuse the voltage registers for direction settings. + */ +#define MCI_ST_DATA2DIREN (1 << 2) +#define MCI_ST_CMDDIREN (1 << 3) +#define MCI_ST_DATA0DIREN (1 << 4) +#define MCI_ST_DATA31DIREN (1 << 5) +#define MCI_ST_FBCLKEN (1 << 7) +#define MCI_ST_DATA74DIREN (1 << 8) + /* Just some dummy forwarding */ struct dma_chan; @@ -31,6 +44,8 @@ struct dma_chan; * @capabilities: the capabilities of the block as implemented in * this platform, signify anything MMC_CAP_* from mmc/host.h * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h + * @sigdir: a bit field indicating for what bits in the MMC bus the host + * should enable signal direction indication. * @dma_filter: function used to select an appropriate RX and TX * DMA channel to be used for DMA, if and only if you're deploying the * generic DMA engine @@ -54,6 +69,7 @@ struct mmci_platform_data { bool cd_invert; unsigned long capabilities; unsigned long capabilities2; + u32 sigdir; bool (*dma_filter)(struct dma_chan *chan, void *filter_param); void *dma_rx_param; void *dma_tx_param; -- cgit v1.2.3-70-g09d2 From bc521818e28042bb6018d91c353d24fb01ccb162 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:57:55 +0100 Subject: ARM: 7219/1: mmc: mmci: Change vdd_handler to a generic ios_handler The purpose of the vdd_handler does not make sense. We remove it and use a generic approach instead. A new ios_handler is added, the purpose of which e.g. can be to control GPIO pins to a levelshifter. Previously the vdd_handler was also used for making additional changes to the power register bits. This option is superfluous and is therefore removed. Adaptaptions from the old vdd_handler to the new ios_handler is done for mach-ux500 board, which was the only one using the vdd_handler. This patch is based upon a patch from Sebastian Rasmussen. Tested-by: Linus Walleij Signed-off-by: Sebastian Rasmussen Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- arch/arm/mach-ux500/board-mop500-sdi.c | 21 ++++++++------------- drivers/mmc/host/mmci.c | 8 ++++---- include/linux/amba/mmci.h | 6 +++--- 3 files changed, 15 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-ux500/board-mop500-sdi.c b/arch/arm/mach-ux500/board-mop500-sdi.c index 23be34b3bb6..4049bd7f061 100644 --- a/arch/arm/mach-ux500/board-mop500-sdi.c +++ b/arch/arm/mach-ux500/board-mop500-sdi.c @@ -31,21 +31,13 @@ * SDI 0 (MicroSD slot) */ -/* MMCIPOWER bits */ -#define MCI_DATA2DIREN (1 << 2) -#define MCI_CMDDIREN (1 << 3) -#define MCI_DATA0DIREN (1 << 4) -#define MCI_DATA31DIREN (1 << 5) -#define MCI_FBCLKEN (1 << 7) - /* GPIO pins used by the sdi0 level shifter */ static int sdi0_en = -1; static int sdi0_vsel = -1; -static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, - unsigned char power_mode) +static int mop500_sdi0_ios_handler(struct device *dev, struct mmc_ios *ios) { - switch (power_mode) { + switch (ios->power_mode) { case MMC_POWER_UP: case MMC_POWER_ON: /* @@ -65,8 +57,7 @@ static u32 mop500_sdi0_vdd_handler(struct device *dev, unsigned int vdd, break; } - return MCI_FBCLKEN | MCI_CMDDIREN | MCI_DATA0DIREN | - MCI_DATA2DIREN | MCI_DATA31DIREN; + return 0; } #ifdef CONFIG_STE_DMA40 @@ -90,13 +81,17 @@ static struct stedma40_chan_cfg mop500_sdi0_dma_cfg_tx = { #endif static struct mmci_platform_data mop500_sdi0_data = { - .vdd_handler = mop500_sdi0_vdd_handler, + .ios_handler = mop500_sdi0_ios_handler, .ocr_mask = MMC_VDD_29_30, .f_max = 50000000, .capabilities = MMC_CAP_4_BIT_DATA | MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED, .gpio_wp = -1, + .sigdir = MCI_ST_FBCLKEN | + MCI_ST_CMDDIREN | + MCI_ST_DATA0DIREN | + MCI_ST_DATA2DIREN, #ifdef CONFIG_STE_DMA40 .dma_filter = stedma40_filter, .dma_rx_param = &mop500_sdi0_dma_cfg_rx, diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index eb11ce61941..0af1507d15c 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1026,6 +1026,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + if (host->plat->ios_handler && + host->plat->ios_handler(mmc_dev(mmc), ios)) + dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); + switch (ios->power_mode) { case MMC_POWER_OFF: if (host->vcc) @@ -1045,10 +1049,6 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) return; } } - if (host->plat->vdd_handler) - pwr |= host->plat->vdd_handler(mmc_dev(mmc), ios->vdd, - ios->power_mode); - /* * The ST Micro variant doesn't have the PL180s MCI_PWR_UP * and instead uses MCI_PWR_ON so apply whatever value is diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h index b51bf5fa85f..32a89cf5ec4 100644 --- a/include/linux/amba/mmci.h +++ b/include/linux/amba/mmci.h @@ -31,7 +31,8 @@ struct dma_chan; * @ocr_mask: available voltages on the 4 pins from the block, this * is ignored if a regulator is used, see the MMC_VDD_* masks in * mmc/host.h - * @vdd_handler: a callback function to translate a MMC_VDD_* + * @ios_handler: a callback function to act on specfic ios changes, + * used for example to control a levelshifter * mask into a value to be binary (or set some other custom bits * in MMCIPWR) or:ed and written into the MMCIPWR register of the * block. May also control external power based on the power_mode. @@ -61,8 +62,7 @@ struct dma_chan; struct mmci_platform_data { unsigned int f_max; unsigned int ocr_mask; - u32 (*vdd_handler)(struct device *, unsigned int vdd, - unsigned char power_mode); + int (*ios_handler)(struct device *, struct mmc_ios *); unsigned int (*status)(struct device *); int gpio_wp; int gpio_cd; -- cgit v1.2.3-70-g09d2 From 48fa700388bec2ba79e9c8cc087f39c800a6fff5 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 16:59:34 +0100 Subject: ARM: 7221/1: mmc: mmci: Change from using legacy suspend This patch switch from using the legacy suspend/resume to the new way of registering PM callbacks. No functional change is done. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0af1507d15c..544995b3cb9 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1456,10 +1456,11 @@ static int __devexit mmci_remove(struct amba_device *dev) return 0; } -#ifdef CONFIG_PM -static int mmci_suspend(struct amba_device *dev, pm_message_t state) +#ifdef CONFIG_SUSPEND +static int mmci_suspend(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1473,9 +1474,10 @@ static int mmci_suspend(struct amba_device *dev, pm_message_t state) return ret; } -static int mmci_resume(struct amba_device *dev) +static int mmci_resume(struct device *dev) { - struct mmc_host *mmc = amba_get_drvdata(dev); + struct amba_device *adev = to_amba_device(dev); + struct mmc_host *mmc = amba_get_drvdata(adev); int ret = 0; if (mmc) { @@ -1488,11 +1490,12 @@ static int mmci_resume(struct amba_device *dev) return ret; } -#else -#define mmci_suspend NULL -#define mmci_resume NULL #endif +static const struct dev_pm_ops mmci_dev_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(mmci_suspend, mmci_resume) +}; + static struct amba_id mmci_ids[] = { { .id = 0x00041180, @@ -1538,11 +1541,10 @@ MODULE_DEVICE_TABLE(amba, mmci_ids); static struct amba_driver mmci_driver = { .drv = { .name = DRIVER_NAME, + .pm = &mmci_dev_pm_ops, }, .probe = mmci_probe, .remove = __devexit_p(mmci_remove), - .suspend = mmci_suspend, - .resume = mmci_resume, .id_table = mmci_ids, }; -- cgit v1.2.3-70-g09d2 From 2cd976c46472e34460349ed43a217e34f90bad55 Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:01:11 +0100 Subject: ARM: 7223/1: mmc: mmci: Fixup use of runtime PM and use autosuspend Added use of runtime PM autosuspend feature, with a fixed timeout of 50 ms. This will prevent adding a latency, although very minor, for _every_ request. Moreover the runtime_get_sync is now also used in set_ios and suspend since the runtime resourses are needed here as well. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 544995b3cb9..6a21fc0bf3d 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -178,8 +178,10 @@ mmci_request_end(struct mmci_host *host, struct mmc_request *mrq) host->mrq = NULL; host->cmd = NULL; - pm_runtime_put(mmc_dev(host->mmc)); mmc_request_done(host->mmc, mrq); + + pm_runtime_mark_last_busy(mmc_dev(host->mmc)); + pm_runtime_put_autosuspend(mmc_dev(host->mmc)); } static void mmci_set_mask1(struct mmci_host *host, unsigned int mask) @@ -1026,6 +1028,8 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) unsigned long flags; int ret; + pm_runtime_get_sync(mmc_dev(mmc)); + if (host->plat->ios_handler && host->plat->ios_handler(mmc_dev(mmc), ios)) dev_err(mmc_dev(mmc), "platform ios_handler failed\n"); @@ -1046,7 +1050,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) * power should be rare so we print an error * and return here. */ - return; + goto out; } } /* @@ -1100,6 +1104,10 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) } spin_unlock_irqrestore(&host->lock, flags); + + out: + pm_runtime_mark_last_busy(mmc_dev(mmc)); + pm_runtime_put_autosuspend(mmc_dev(mmc)); } static int mmci_get_ro(struct mmc_host *mmc) @@ -1372,6 +1380,8 @@ static int __devinit mmci_probe(struct amba_device *dev, mmci_dma_setup(host); + pm_runtime_set_autosuspend_delay(&dev->dev, 50); + pm_runtime_use_autosuspend(&dev->dev); pm_runtime_put(&dev->dev); mmc_add_host(mmc); @@ -1467,8 +1477,10 @@ static int mmci_suspend(struct device *dev) struct mmci_host *host = mmc_priv(mmc); ret = mmc_suspend_host(mmc); - if (ret == 0) + if (ret == 0) { + pm_runtime_get_sync(dev); writel(0, host->base + MMCIMASK0); + } } return ret; @@ -1484,6 +1496,7 @@ static int mmci_resume(struct device *dev) struct mmci_host *host = mmc_priv(mmc); writel(MCI_IRQENABLE, host->base + MMCIMASK0); + pm_runtime_put(dev); ret = mmc_resume_host(mmc); } -- cgit v1.2.3-70-g09d2 From 7258db7efe7d9c5eb80151554faa1fa7411d6e3e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:05:28 +0100 Subject: ARM: 7227/1: mmc: mmci: Prepare for SDIO before setting up DMA job Move the SDIO preparation to be done before the DMA job is setup. This makes it possible to do DMA for SDIO transfers as well as the earlier supported pio mode. Signed-off-by: Ulf Hansson Signed-off-by: Stefan Nilsson XK Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 6a21fc0bf3d..b09ccb7223e 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -615,6 +615,11 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) if (data->flags & MMC_DATA_READ) datactrl |= MCI_DPSM_DIRECTION; + /* The ST Micro variants has a special bit to enable SDIO */ + if (variant->sdio && host->mmc->card) + if (mmc_card_sdio(host->mmc->card)) + datactrl |= MCI_ST_DPSM_SDIOEN; + /* * Attempt to use DMA operation mode, if this * should fail, fall back to PIO mode @@ -643,11 +648,6 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) irqmask = MCI_TXFIFOHALFEMPTYMASK; } - /* The ST Micro variants has a special bit to enable SDIO */ - if (variant->sdio && host->mmc->card) - if (mmc_card_sdio(host->mmc->card)) - datactrl |= MCI_ST_DPSM_SDIOEN; - writel(datactrl, base + MMCIDATACTRL); writel(readl(base + MMCIMASK0) & ~MCI_DATAENDMASK, base + MMCIMASK0); mmci_set_mask1(host, irqmask); -- cgit v1.2.3-70-g09d2 From 393e5e24165d0bef60489ecd0baef085e9af2e5a Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Tue, 13 Dec 2011 17:08:04 +0100 Subject: ARM: 7230/1: mmc: mmci: Fix PIO read for small SDIO packets Corrects a bug in MMCI host driver which silently causes small reads (< 4 bytes as only used in SDIO) from PL-18X to fail. Signed-off-by: Stefan Nilsson XK Signed-off-by: Ulf Hansson Signed-off-by: Fredrik Soderstedt Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index b09ccb7223e..1f8832699cd 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -794,7 +794,24 @@ static int mmci_pio_read(struct mmci_host *host, char *buffer, unsigned int rema if (count <= 0) break; - readsl(base + MMCIFIFO, ptr, count >> 2); + /* + * SDIO especially may want to send something that is + * not divisible by 4 (as opposed to card sectors + * etc). Therefore make sure to always read the last bytes + * while only doing full 32-bit reads towards the FIFO. + */ + if (unlikely(count & 0x3)) { + if (count < 4) { + unsigned char buf[4]; + readsl(base + MMCIFIFO, buf, 1); + memcpy(ptr, buf, count); + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + count &= ~0x3; + } + } else { + readsl(base + MMCIFIFO, ptr, count >> 2); + } ptr += count; remain -= count; -- cgit v1.2.3-70-g09d2 From f0c28b0075cad861f4b93c526c6446169d136466 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 14 Jan 2012 16:56:43 +0800 Subject: devfreq: exynos4_bus: Use dev_get_drvdata at appropriate places Signed-off-by: Axel Lin Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 6460577d670..489ccfa93a9 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -622,9 +622,7 @@ static int exynos4_bus_setvolt(struct busfreq_data *data, struct opp *opp, static int exynos4_bus_target(struct device *dev, unsigned long *_freq) { int err = 0; - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); struct opp *opp = devfreq_recommended_opp(dev, _freq); unsigned long old_freq = opp_get_freq(data->curr_opp); unsigned long freq = opp_get_freq(opp); @@ -689,9 +687,7 @@ static int exynos4_get_busier_dmc(struct busfreq_data *data) static int exynos4_bus_get_dev_status(struct device *dev, struct devfreq_dev_status *stat) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); int busier_dmc; int cycles_x2 = 2; /* 2 x cycles */ void __iomem *addr; @@ -739,9 +735,7 @@ static int exynos4_bus_get_dev_status(struct device *dev, static void exynos4_bus_exit(struct device *dev) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); devfreq_unregister_opp_notifier(dev, data->devfreq); } @@ -1087,9 +1081,7 @@ static __devexit int exynos4_busfreq_remove(struct platform_device *pdev) static int exynos4_busfreq_resume(struct device *dev) { - struct platform_device *pdev = container_of(dev, struct platform_device, - dev); - struct busfreq_data *data = platform_get_drvdata(pdev); + struct busfreq_data *data = dev_get_drvdata(dev); busfreq_mon_reset(data); return 0; -- cgit v1.2.3-70-g09d2 From e0d44e8ab06885a5bb980f3d6d4cf64ad430d406 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Jan 2012 14:53:08 +0800 Subject: devfreq: Remove MODULE_ALIAS for exynos4 busfreq driver This driver can only be built-in, it does not make sense to add modalias for it (in addition to being incorrect, the platform modalias needs to be prefixed with "platform:"). Signed-off-by: Axel Lin Signed-off-by: MyungJoo Ham --- drivers/devfreq/exynos4_bus.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/devfreq/exynos4_bus.c b/drivers/devfreq/exynos4_bus.c index 489ccfa93a9..590d6865e38 100644 --- a/drivers/devfreq/exynos4_bus.c +++ b/drivers/devfreq/exynos4_bus.c @@ -1124,4 +1124,3 @@ module_exit(exynos4_busfreq_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("EXYNOS4 busfreq driver with devfreq framework"); MODULE_AUTHOR("MyungJoo Ham "); -MODULE_ALIAS("exynos4-busfreq"); -- cgit v1.2.3-70-g09d2 From 6530b9dea1b7f33eaf79ba625e3a99f2455f3eb1 Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Fri, 9 Dec 2011 16:42:19 +0900 Subject: PM / devfreq: add min/max_freq limit requested by users. The frequency requested to devfreq device driver from devfreq governors is restricted by min_freq and max_freq input. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park --- drivers/devfreq/devfreq.c | 70 +++++++++++++++++++++++++++++++ drivers/devfreq/governor_performance.c | 5 ++- drivers/devfreq/governor_powersave.c | 2 +- drivers/devfreq/governor_simpleondemand.c | 12 ++++-- drivers/devfreq/governor_userspace.c | 15 +++++-- include/linux/devfreq.h | 5 +++ 6 files changed, 101 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index c189b82f5ec..a129a7b6bfd 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -501,12 +501,82 @@ static ssize_t show_central_polling(struct device *dev, !to_devfreq(dev)->governor->no_central_polling); } +static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned long value; + int ret; + unsigned long max; + + ret = sscanf(buf, "%lu", &value); + if (ret != 1) + goto out; + + mutex_lock(&df->lock); + max = df->max_freq; + if (value && max && value > max) { + ret = -EINVAL; + goto unlock; + } + + df->min_freq = value; + update_devfreq(df); + ret = count; +unlock: + mutex_unlock(&df->lock); +out: + return ret; +} + +static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq); +} + +static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned long value; + int ret; + unsigned long min; + + ret = sscanf(buf, "%lu", &value); + if (ret != 1) + goto out; + + mutex_lock(&df->lock); + min = df->min_freq; + if (value && min && value < min) { + ret = -EINVAL; + goto unlock; + } + + df->max_freq = value; + update_devfreq(df); + ret = count; +unlock: + mutex_unlock(&df->lock); +out: + return ret; +} + +static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); +} + static struct device_attribute devfreq_attrs[] = { __ATTR(governor, S_IRUGO, show_governor, NULL), __ATTR(cur_freq, S_IRUGO, show_freq, NULL), __ATTR(central_polling, S_IRUGO, show_central_polling, NULL), __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, store_polling_interval), + __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), + __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq), { }, }; diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c index c0596b29176..574a06b1b1d 100644 --- a/drivers/devfreq/governor_performance.c +++ b/drivers/devfreq/governor_performance.c @@ -18,7 +18,10 @@ static int devfreq_performance_func(struct devfreq *df, * target callback should be able to get floor value as * said in devfreq.h */ - *freq = UINT_MAX; + if (!df->max_freq) + *freq = UINT_MAX; + else + *freq = df->max_freq; return 0; } diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c index 2483a85a266..d742d4a82d6 100644 --- a/drivers/devfreq/governor_powersave.c +++ b/drivers/devfreq/governor_powersave.c @@ -18,7 +18,7 @@ static int devfreq_powersave_func(struct devfreq *df, * target callback should be able to get ceiling value as * said in devfreq.h */ - *freq = 0; + *freq = df->min_freq; return 0; } diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c index efad8dcf902..a2e3eae7901 100644 --- a/drivers/devfreq/governor_simpleondemand.c +++ b/drivers/devfreq/governor_simpleondemand.c @@ -25,6 +25,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD; unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL; struct devfreq_simple_ondemand_data *data = df->data; + unsigned long max = (df->max_freq) ? df->max_freq : UINT_MAX; if (err) return err; @@ -41,7 +42,7 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, /* Assume MAX if it is going to be divided by zero */ if (stat.total_time == 0) { - *freq = UINT_MAX; + *freq = max; return 0; } @@ -54,13 +55,13 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, /* Set MAX if it's busy enough */ if (stat.busy_time * 100 > stat.total_time * dfso_upthreshold) { - *freq = UINT_MAX; + *freq = max; return 0; } /* Set MAX if we do not know the initial frequency */ if (stat.current_frequency == 0) { - *freq = UINT_MAX; + *freq = max; return 0; } @@ -79,6 +80,11 @@ static int devfreq_simple_ondemand_func(struct devfreq *df, b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2)); *freq = (unsigned long) b; + if (df->min_freq && *freq < df->min_freq) + *freq = df->min_freq; + if (df->max_freq && *freq > df->max_freq) + *freq = df->max_freq; + return 0; } diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c index 4f8b563da78..0681246fc89 100644 --- a/drivers/devfreq/governor_userspace.c +++ b/drivers/devfreq/governor_userspace.c @@ -25,10 +25,19 @@ static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) { struct userspace_data *data = df->data; - if (!data->valid) + if (data->valid) { + unsigned long adjusted_freq = data->user_frequency; + + if (df->max_freq && adjusted_freq > df->max_freq) + adjusted_freq = df->max_freq; + + if (df->min_freq && adjusted_freq < df->min_freq) + adjusted_freq = df->min_freq; + + *freq = adjusted_freq; + } else { *freq = df->previous_freq; /* No user freq specified yet */ - else - *freq = data->user_frequency; + } return 0; } diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index f7eb7d06df7..5862475d05f 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -124,6 +124,8 @@ struct devfreq_governor { * touch this. * @being_removed a flag to mark that this object is being removed in * order to prevent trying to remove the object multiple times. + * @min_freq Limit minimum frequency requested by user (0: none) + * @max_freq Limit maximum frequency requested by user (0: none) * * This structure stores the devfreq information for a give device. * @@ -149,6 +151,9 @@ struct devfreq { void *data; /* private data for governors */ bool being_removed; + + unsigned long min_freq; + unsigned long max_freq; }; #if defined(CONFIG_PM_DEVFREQ) -- cgit v1.2.3-70-g09d2 From f4a0391dfa91155bd961673b31eb42d9d45c799d Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 5 Jan 2012 12:49:54 -0200 Subject: ima: fix Kconfig dependencies Fix the following build warning: warning: (IMA) selects TCG_TPM which has unmet direct dependencies (HAS_IOMEM && EXPERIMENTAL) Suggested-by: Rajiv Andrade Signed-off-by: Fabio Estevam Signed-off-by: Rajiv Andrade Cc: Signed-off-by: Mimi Zohar --- drivers/char/tpm/Kconfig | 1 - security/integrity/ima/Kconfig | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index 7fc75e47e6d..a048199ce86 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig @@ -5,7 +5,6 @@ menuconfig TCG_TPM tristate "TPM Hardware Support" depends on HAS_IOMEM - depends on EXPERIMENTAL select SECURITYFS ---help--- If you have a TPM security chip in your system, which diff --git a/security/integrity/ima/Kconfig b/security/integrity/ima/Kconfig index 4f554f20dc9..063298a797e 100644 --- a/security/integrity/ima/Kconfig +++ b/security/integrity/ima/Kconfig @@ -9,7 +9,7 @@ config IMA select CRYPTO_HMAC select CRYPTO_MD5 select CRYPTO_SHA1 - select TCG_TPM if !S390 && !UML + select TCG_TPM if HAS_IOMEM && !UML select TCG_TIS if TCG_TPM help The Trusted Computing Group(TCG) runtime Integrity -- cgit v1.2.3-70-g09d2 From 6219929f5f82708309b3054ec7db6cb6e3ee47d5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Mon, 9 Jan 2012 20:27:41 +0530 Subject: regulator: TPS62360: Add tps62360 regulator driver The regulator module consists of 1 DCDC. The output voltage is configurable and is meant for supply power to the core voltage of Soc. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 10 + drivers/regulator/Makefile | 1 + drivers/regulator/tps62360-regulator.c | 472 +++++++++++++++++++++++++++++++++ include/linux/regulator/tps62360.h | 57 ++++ 4 files changed, 540 insertions(+) create mode 100644 drivers/regulator/tps62360-regulator.c create mode 100644 include/linux/regulator/tps62360.h (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 7a61b17ddd0..b9ad3d8e03c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -328,6 +328,16 @@ config REGULATOR_TPS65910 help This driver supports TPS65910 voltage regulator chips. +config REGULATOR_TPS62360 + tristate "TI TPS62360 Power Regulator" + depends on I2C + select REGMAP_I2C + help + This driver supports TPS62360 voltage regulator chip. This + regulator is meant for processor core supply. This chip is + high-frequency synchronous step down dc-dc converter optimized + for battery-powered portable applications. + config REGULATOR_AAT2870 tristate "AnalogicTech AAT2870 Regulators" depends on MFD_AAT2870_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 503bac87715..1668b2e667c 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -47,6 +47,7 @@ obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o +obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG diff --git a/drivers/regulator/tps62360-regulator.c b/drivers/regulator/tps62360-regulator.c new file mode 100644 index 00000000000..f778ef06769 --- /dev/null +++ b/drivers/regulator/tps62360-regulator.c @@ -0,0 +1,472 @@ +/* + * tps62360.c -- TI tps62360 + * + * Driver for processor core supply tps62360 and tps62361B + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, + * whether express or implied; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + * 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Register definitions */ +#define REG_VSET0 0 +#define REG_VSET1 1 +#define REG_VSET2 2 +#define REG_VSET3 3 +#define REG_CONTROL 4 +#define REG_TEMP 5 +#define REG_RAMPCTRL 6 +#define REG_CHIPID 8 + +enum chips {TPS62360, TPS62361}; + +#define TPS62360_BASE_VOLTAGE 770 +#define TPS62360_N_VOLTAGES 64 + +#define TPS62361_BASE_VOLTAGE 500 +#define TPS62361_N_VOLTAGES 128 + +/* tps 62360 chip information */ +struct tps62360_chip { + const char *name; + struct device *dev; + struct regulator_desc desc; + struct i2c_client *client; + struct regulator_dev *rdev; + struct regmap *regmap; + int chip_id; + int vsel0_gpio; + int vsel1_gpio; + int voltage_base; + u8 voltage_reg_mask; + bool en_internal_pulldn; + bool en_force_pwm; + bool en_discharge; + bool valid_gpios; + int lru_index[4]; + int curr_vset_vsel[4]; + int curr_vset_id; +}; + +/* + * find_voltage_set_register: Find new voltage configuration register + * (VSET) id. + * The finding of the new VSET register will be based on the LRU mechanism. + * Each VSET register will have different voltage configured . This + * Function will look if any of the VSET register have requested voltage set + * or not. + * - If it is already there then it will make that register as most + * recently used and return as found so that caller need not to set + * the VSET register but need to set the proper gpios to select this + * VSET register. + * - If requested voltage is not found then it will use the least + * recently mechanism to get new VSET register for new configuration + * and will return not_found so that caller need to set new VSET + * register and then gpios (both). + */ +static bool find_voltage_set_register(struct tps62360_chip *tps, + int req_vsel, int *vset_reg_id) +{ + int i; + bool found = false; + int new_vset_reg = tps->lru_index[3]; + int found_index = 3; + for (i = 0; i < 4; ++i) { + if (tps->curr_vset_vsel[tps->lru_index[i]] == req_vsel) { + new_vset_reg = tps->lru_index[i]; + found_index = i; + found = true; + goto update_lru_index; + } + } + +update_lru_index: + for (i = found_index; i > 0; i--) + tps->lru_index[i] = tps->lru_index[i - 1]; + + tps->lru_index[0] = new_vset_reg; + *vset_reg_id = new_vset_reg; + return found; +} + +static int tps62360_dcdc_get_voltage(struct regulator_dev *dev) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + int vsel; + unsigned int data; + int ret; + + ret = regmap_read(tps->regmap, REG_VSET0 + tps->curr_vset_id, &data); + if (ret < 0) { + dev_err(tps->dev, "%s: Error in reading register %d\n", + __func__, REG_VSET0 + tps->curr_vset_id); + return ret; + } + vsel = (int)data & tps->voltage_reg_mask; + return (tps->voltage_base + vsel * 10) * 1000; +} + +static int tps62360_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + int vsel; + int ret; + bool found = false; + int new_vset_id = tps->curr_vset_id; + + if (max_uV < min_uV) + return -EINVAL; + + if (min_uV > + ((tps->voltage_base + (tps->desc.n_voltages - 1) * 10) * 1000)) + return -EINVAL; + + if (max_uV < tps->voltage_base * 1000) + return -EINVAL; + + vsel = DIV_ROUND_UP(min_uV - (tps->voltage_base * 1000), 10000); + if (selector) + *selector = (vsel & tps->voltage_reg_mask); + + /* + * If gpios are available to select the VSET register then least + * recently used register for new configuration. + */ + if (tps->valid_gpios) + found = find_voltage_set_register(tps, vsel, &new_vset_id); + + if (!found) { + ret = regmap_update_bits(tps->regmap, REG_VSET0 + new_vset_id, + tps->voltage_reg_mask, vsel); + if (ret < 0) { + dev_err(tps->dev, "%s: Error in updating register %d\n", + __func__, REG_VSET0 + new_vset_id); + return ret; + } + tps->curr_vset_id = new_vset_id; + tps->curr_vset_vsel[new_vset_id] = vsel; + } + + /* Select proper VSET register vio gpios */ + if (tps->valid_gpios) { + gpio_set_value_cansleep(tps->vsel0_gpio, + new_vset_id & 0x1); + gpio_set_value_cansleep(tps->vsel1_gpio, + (new_vset_id >> 1) & 0x1); + } + return 0; +} + +static int tps62360_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps62360_chip *tps = rdev_get_drvdata(dev); + + if ((selector < 0) || (selector >= tps->desc.n_voltages)) + return -EINVAL; + return (tps->voltage_base + selector * 10) * 1000; +} + +static struct regulator_ops tps62360_dcdc_ops = { + .get_voltage = tps62360_dcdc_get_voltage, + .set_voltage = tps62360_dcdc_set_voltage, + .list_voltage = tps62360_dcdc_list_voltage, +}; + +static int tps62360_init_force_pwm(struct tps62360_chip *tps, + struct tps62360_regulator_platform_data *pdata, + int vset_id) +{ + unsigned int data; + int ret; + ret = regmap_read(tps->regmap, REG_VSET0 + vset_id, &data); + if (ret < 0) { + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); + return ret; + } + tps->curr_vset_vsel[vset_id] = data & tps->voltage_reg_mask; + if (pdata->en_force_pwm) + data |= BIT(7); + else + data &= ~BIT(7); + ret = regmap_write(tps->regmap, REG_VSET0 + vset_id, data); + if (ret < 0) + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_VSET0 + vset_id); + return ret; +} + +static int tps62360_init_dcdc(struct tps62360_chip *tps, + struct tps62360_regulator_platform_data *pdata) +{ + int ret; + int i; + + /* Initailize internal pull up/down control */ + if (tps->en_internal_pulldn) + ret = regmap_write(tps->regmap, REG_CONTROL, 0xE0); + else + ret = regmap_write(tps->regmap, REG_CONTROL, 0x0); + if (ret < 0) { + dev_err(tps->dev, "%s() fails in writing reg %d\n", + __func__, REG_CONTROL); + return ret; + } + + /* Initailize force PWM mode */ + if (tps->valid_gpios) { + for (i = 0; i < 4; ++i) { + ret = tps62360_init_force_pwm(tps, pdata, i); + if (ret < 0) + return ret; + } + } else { + ret = tps62360_init_force_pwm(tps, pdata, tps->curr_vset_id); + if (ret < 0) + return ret; + } + + /* Reset output discharge path to reduce power consumption */ + ret = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), 0); + if (ret < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); + return ret; +} + +static const struct regmap_config tps62360_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + +static int __devinit tps62360_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct tps62360_regulator_platform_data *pdata; + struct regulator_dev *rdev; + struct tps62360_chip *tps; + int ret; + int i; + + pdata = client->dev.platform_data; + if (!pdata) { + dev_err(&client->dev, "%s() Err: Platform data not found\n", + __func__); + return -EIO; + } + + tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL); + if (!tps) { + dev_err(&client->dev, "%s() Err: Memory allocation fails\n", + __func__); + return -ENOMEM; + } + + tps->en_force_pwm = pdata->en_force_pwm; + tps->en_discharge = pdata->en_discharge; + tps->en_internal_pulldn = pdata->en_internal_pulldn; + tps->vsel0_gpio = pdata->vsel0_gpio; + tps->vsel1_gpio = pdata->vsel1_gpio; + tps->client = client; + tps->dev = &client->dev; + tps->name = id->name; + tps->voltage_base = (id->driver_data == TPS62360) ? + TPS62360_BASE_VOLTAGE : TPS62361_BASE_VOLTAGE; + tps->voltage_reg_mask = (id->driver_data == TPS62360) ? 0x3F : 0x7F; + + tps->desc.name = id->name; + tps->desc.id = 0; + tps->desc.n_voltages = (id->driver_data == TPS62360) ? + TPS62360_N_VOLTAGES : TPS62361_N_VOLTAGES; + tps->desc.ops = &tps62360_dcdc_ops; + tps->desc.type = REGULATOR_VOLTAGE; + tps->desc.owner = THIS_MODULE; + tps->regmap = regmap_init_i2c(client, &tps62360_regmap_config); + if (IS_ERR(tps->regmap)) { + ret = PTR_ERR(tps->regmap); + dev_err(&client->dev, "%s() Err: Failed to allocate register" + "map: %d\n", __func__, ret); + return ret; + } + i2c_set_clientdata(client, tps); + + tps->curr_vset_id = (pdata->vsel1_def_state & 1) * 2 + + (pdata->vsel0_def_state & 1); + tps->lru_index[0] = tps->curr_vset_id; + tps->valid_gpios = false; + + if (gpio_is_valid(tps->vsel0_gpio) && gpio_is_valid(tps->vsel1_gpio)) { + ret = gpio_request(tps->vsel0_gpio, "tps62360-vsel0"); + if (ret) { + dev_err(&client->dev, + "Err: Could not obtain vsel0 GPIO %d: %d\n", + tps->vsel0_gpio, ret); + goto err_gpio0; + } + ret = gpio_direction_output(tps->vsel0_gpio, + pdata->vsel0_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel0 GPIO %d: %d\n", tps->vsel0_gpio, ret); + gpio_free(tps->vsel0_gpio); + goto err_gpio0; + } + + ret = gpio_request(tps->vsel1_gpio, "tps62360-vsel1"); + if (ret) { + dev_err(&client->dev, + "Err: Could not obtain vsel1 GPIO %d: %d\n", + tps->vsel1_gpio, ret); + goto err_gpio1; + } + ret = gpio_direction_output(tps->vsel1_gpio, + pdata->vsel1_def_state); + if (ret) { + dev_err(&client->dev, "Err: Could not set direction of" + "vsel1 GPIO %d: %d\n", tps->vsel1_gpio, ret); + gpio_free(tps->vsel1_gpio); + goto err_gpio1; + } + tps->valid_gpios = true; + + /* + * Initialize the lru index with vset_reg id + * The index 0 will be most recently used and + * set with the tps->curr_vset_id */ + for (i = 0; i < 4; ++i) + tps->lru_index[i] = i; + tps->lru_index[0] = tps->curr_vset_id; + tps->lru_index[tps->curr_vset_id] = 0; + } + + ret = tps62360_init_dcdc(tps, pdata); + if (ret < 0) { + dev_err(tps->dev, "%s() Err: Init fails with = %d\n", + __func__, ret); + goto err_init; + } + + /* Register the regulators */ + rdev = regulator_register(&tps->desc, &client->dev, + &pdata->reg_init_data, tps, NULL); + if (IS_ERR(rdev)) { + dev_err(tps->dev, "%s() Err: Failed to register %s\n", + __func__, id->name); + ret = PTR_ERR(rdev); + goto err_init; + } + + tps->rdev = rdev; + return 0; + +err_init: + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); +err_gpio1: + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); +err_gpio0: + regmap_exit(tps->regmap); + return ret; +} + +/** + * tps62360_remove - tps62360 driver i2c remove handler + * @client: i2c driver client device structure + * + * Unregister TPS driver as an i2c client device driver + */ +static int __devexit tps62360_remove(struct i2c_client *client) +{ + struct tps62360_chip *tps = i2c_get_clientdata(client); + + if (gpio_is_valid(tps->vsel1_gpio)) + gpio_free(tps->vsel1_gpio); + + if (gpio_is_valid(tps->vsel0_gpio)) + gpio_free(tps->vsel0_gpio); + + regulator_unregister(tps->rdev); + regmap_exit(tps->regmap); + return 0; +} + +static void tps62360_shutdown(struct i2c_client *client) +{ + struct tps62360_chip *tps = i2c_get_clientdata(client); + int st; + + if (!tps->en_discharge) + return; + + /* Configure the output discharge path */ + st = regmap_update_bits(tps->regmap, REG_RAMPCTRL, BIT(2), BIT(2)); + if (st < 0) + dev_err(tps->dev, "%s() fails in updating reg %d\n", + __func__, REG_RAMPCTRL); +} + +static const struct i2c_device_id tps62360_id[] = { + {.name = "tps62360", .driver_data = TPS62360}, + {.name = "tps62361", .driver_data = TPS62361}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, tps62360_id); + +static struct i2c_driver tps62360_i2c_driver = { + .driver = { + .name = "tps62360", + .owner = THIS_MODULE, + }, + .probe = tps62360_probe, + .remove = __devexit_p(tps62360_remove), + .shutdown = tps62360_shutdown, + .id_table = tps62360_id, +}; + +static int __init tps62360_init(void) +{ + return i2c_add_driver(&tps62360_i2c_driver); +} +subsys_initcall(tps62360_init); + +static void __exit tps62360_cleanup(void) +{ + i2c_del_driver(&tps62360_i2c_driver); +} +module_exit(tps62360_cleanup); + +MODULE_AUTHOR("Laxman Dewangan "); +MODULE_DESCRIPTION("TPS62360 voltage regulator driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/regulator/tps62360.h b/include/linux/regulator/tps62360.h new file mode 100644 index 00000000000..6a5c1b2c751 --- /dev/null +++ b/include/linux/regulator/tps62360.h @@ -0,0 +1,57 @@ +/* + * tps62360.h -- TI tps62360 + * + * Interface for regulator driver for TI TPS62360 Processor core supply + * + * Copyright (C) 2012 NVIDIA Corporation + + * Author: Laxman Dewangan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __LINUX_REGULATOR_TPS62360_H +#define __LINUX_REGULATOR_TPS62360_H + +#include + +/* + * struct tps62360_regulator_platform_data - tps62360 regulator platform data. + * + * @reg_init_data: The regulator init data. + * @en_force_pwm: Enable force pwm or not. + * @en_discharge: Enable discharge the output capacitor via internal + * register. + * @en_internal_pulldn: internal pull down enable or not. + * @vsel0_gpio: Gpio number for vsel0. It should be -1 if this is tied with + * fixed logic. + * @vsel1_gpio: Gpio number for vsel1. It should be -1 if this is tied with + * fixed logic. + * @vsel0_def_state: Default state of vsel0. 1 if it is high else 0. + * @vsel1_def_state: Default state of vsel1. 1 if it is high else 0. + */ +struct tps62360_regulator_platform_data { + struct regulator_init_data reg_init_data; + bool en_force_pwm; + bool en_discharge; + bool en_internal_pulldn; + int vsel0_gpio; + int vsel1_gpio; + int vsel0_def_state; + int vsel1_def_state; +}; + +#endif /* __LINUX_REGULATOR_TPS62360_H */ -- cgit v1.2.3-70-g09d2 From 9767ec7fe8d9bf00e764f1d0ca0176988255be11 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Mon, 9 Jan 2012 19:10:25 +0900 Subject: regulator: Add S5M8767A regulator driver S5M8767A is a cost-effective PMIC which is designed for mobile applications. It includes high efficient 9 Buck converters, 28 LDOs. Especially, S5M8767A is optimized for Multi-core SOCs. And during DVFS operation, S5M8767A output stable voltage. This patch implement regulator driver for S5M8767A. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 834 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 834 insertions(+) create mode 100644 drivers/regulator/s5m8767.c (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c new file mode 100644 index 00000000000..b3d356f5e27 --- /dev/null +++ b/drivers/regulator/s5m8767.c @@ -0,0 +1,834 @@ +/* + * s5m8767.c + * + * Copyright (c) 2011 Samsung Electronics Co., Ltd + * http://www.samsung.com + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct s5m8767_info { + struct device *dev; + struct s5m87xx_dev *iodev; + int num_regulators; + struct regulator_dev **rdev; + + int ramp_delay; + bool buck2_ramp; + bool buck3_ramp; + bool buck4_ramp; + + bool buck2_gpiodvs; + bool buck3_gpiodvs; + bool buck4_gpiodvs; + u8 buck2_vol[8]; + u8 buck3_vol[8]; + u8 buck4_vol[8]; + int buck_gpios[3]; + int buck_gpioindex; +}; + +struct s5m_voltage_desc { + int max; + int min; + int step; +}; + +static const struct s5m_voltage_desc buck_voltage_val1 = { + .max = 2225000, + .min = 650000, + .step = 6250, +}; + +static const struct s5m_voltage_desc buck_voltage_val2 = { + .max = 1600000, + .min = 600000, + .step = 6250, +}; + +static const struct s5m_voltage_desc buck_voltage_val3 = { + .max = 3000000, + .min = 750000, + .step = 12500, +}; + +static const struct s5m_voltage_desc ldo_voltage_val1 = { + .max = 3950000, + .min = 800000, + .step = 50000, +}; + +static const struct s5m_voltage_desc ldo_voltage_val2 = { + .max = 2375000, + .min = 800000, + .step = 25000, +}; + +static const struct s5m_voltage_desc *reg_voltage_map[] = { + [S5M8767_LDO1] = &ldo_voltage_val2, + [S5M8767_LDO2] = &ldo_voltage_val2, + [S5M8767_LDO3] = &ldo_voltage_val1, + [S5M8767_LDO4] = &ldo_voltage_val1, + [S5M8767_LDO5] = &ldo_voltage_val1, + [S5M8767_LDO6] = &ldo_voltage_val2, + [S5M8767_LDO7] = &ldo_voltage_val2, + [S5M8767_LDO8] = &ldo_voltage_val2, + [S5M8767_LDO9] = &ldo_voltage_val1, + [S5M8767_LDO10] = &ldo_voltage_val1, + [S5M8767_LDO11] = &ldo_voltage_val1, + [S5M8767_LDO12] = &ldo_voltage_val1, + [S5M8767_LDO13] = &ldo_voltage_val1, + [S5M8767_LDO14] = &ldo_voltage_val1, + [S5M8767_LDO15] = &ldo_voltage_val2, + [S5M8767_LDO16] = &ldo_voltage_val1, + [S5M8767_LDO17] = &ldo_voltage_val1, + [S5M8767_LDO18] = &ldo_voltage_val1, + [S5M8767_LDO19] = &ldo_voltage_val1, + [S5M8767_LDO20] = &ldo_voltage_val1, + [S5M8767_LDO21] = &ldo_voltage_val1, + [S5M8767_LDO22] = &ldo_voltage_val1, + [S5M8767_LDO23] = &ldo_voltage_val1, + [S5M8767_LDO24] = &ldo_voltage_val1, + [S5M8767_LDO25] = &ldo_voltage_val1, + [S5M8767_LDO26] = &ldo_voltage_val1, + [S5M8767_LDO27] = &ldo_voltage_val1, + [S5M8767_LDO28] = &ldo_voltage_val1, + [S5M8767_BUCK1] = &buck_voltage_val1, + [S5M8767_BUCK2] = &buck_voltage_val2, + [S5M8767_BUCK3] = &buck_voltage_val2, + [S5M8767_BUCK4] = &buck_voltage_val2, + [S5M8767_BUCK5] = &buck_voltage_val1, + [S5M8767_BUCK6] = &buck_voltage_val1, + [S5M8767_BUCK7] = NULL, + [S5M8767_BUCK8] = NULL, + [S5M8767_BUCK9] = &buck_voltage_val3, +}; + +static inline int s5m8767_get_reg_id(struct regulator_dev *rdev) +{ + return rdev_get_id(rdev); +} + +static int s5m8767_list_voltage(struct regulator_dev *rdev, + unsigned int selector) +{ + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int val; + + if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) + return -EINVAL; + + desc = reg_voltage_map[reg_id]; + if (desc == NULL) + return -EINVAL; + + val = desc->min + desc->step * selector; + if (val > desc->max) + return -EINVAL; + + return val; +} + +static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) +{ + int reg_id = s5m8767_get_reg_id(rdev); + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO2: + *reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); + break; + case S5M8767_LDO3 ... S5M8767_LDO28: + *reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); + break; + case S5M8767_BUCK1: + *reg = S5M8767_REG_BUCK1CTRL1; + break; + case S5M8767_BUCK2 ... S5M8767_BUCK4: + *reg = S5M8767_REG_BUCK2CTRL + (reg_id - S5M8767_BUCK2) * 9; + break; + case S5M8767_BUCK5: + *reg = S5M8767_REG_BUCK5CTRL1; + break; + case S5M8767_BUCK6 ... S5M8767_BUCK9: + *reg = S5M8767_REG_BUCK6CTRL1 + (reg_id - S5M8767_BUCK6) * 2; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int s5m8767_reg_is_enabled(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + u8 val; + + ret = s5m8767_get_register(rdev, ®); + if (ret == -EINVAL) + return 1; + else if (ret) + return ret; + + ret = s5m_reg_read(s5m8767->iodev, reg, &val); + if (ret) + return ret; + + return (val & mask) == pattern; +} + +static int s5m8767_reg_enable(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + + ret = s5m8767_get_register(rdev, ®); + if (ret) + return ret; + + return s5m_reg_update(s5m8767->iodev, reg, pattern, mask); +} + +static int s5m8767_reg_disable(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int ret, reg; + int mask = 0xc0, pattern = 0xc0; + + ret = s5m8767_get_register(rdev, ®); + if (ret) + return ret; + + return s5m_reg_update(s5m8767->iodev, reg, ~pattern, mask); +} + +static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) +{ + int reg_id = s5m8767_get_reg_id(rdev); + int reg; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO2: + reg = S5M8767_REG_LDO1CTRL + (reg_id - S5M8767_LDO1); + break; + case S5M8767_LDO3 ... S5M8767_LDO28: + reg = S5M8767_REG_LDO3CTRL + (reg_id - S5M8767_LDO3); + break; + case S5M8767_BUCK1: + reg = S5M8767_REG_BUCK1CTRL2; + break; + case S5M8767_BUCK2: + reg = S5M8767_REG_BUCK2DVS1; + break; + case S5M8767_BUCK3: + reg = S5M8767_REG_BUCK3DVS1; + break; + case S5M8767_BUCK4: + reg = S5M8767_REG_BUCK4DVS1; + break; + case S5M8767_BUCK5: + reg = S5M8767_REG_BUCK5CTRL2; + break; + case S5M8767_BUCK6 ... S5M8767_BUCK9: + reg = S5M8767_REG_BUCK6CTRL2 + (reg_id - S5M8767_BUCK6) * 2; + break; + default: + return -EINVAL; + } + + *_reg = reg; + + return 0; +} + +static int s5m8767_get_voltage_sel(struct regulator_dev *rdev) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int reg, mask = 0xff, ret; + int reg_id = s5m8767_get_reg_id(rdev); + u8 val; + + ret = s5m8767_get_voltage_register(rdev, ®); + if (ret) + return ret; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK2: + if (s5m8767->buck2_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + case S5M8767_BUCK3: + if (s5m8767->buck3_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + case S5M8767_BUCK4: + if (s5m8767->buck4_gpiodvs) + reg += s5m8767->buck_gpioindex; + break; + } + + ret = s5m_reg_read(s5m8767->iodev, reg, &val); + if (ret) + return ret; + + val &= mask; + + return val; +} + +static inline int s5m8767_convert_voltage( + const struct s5m_voltage_desc *desc, + int min_vol, int max_vol) +{ + int out_vol = 0; + + if (desc == NULL) + return -EINVAL; + + if (max_vol < desc->min || min_vol > desc->max) + return -EINVAL; + + out_vol = (min_vol - desc->min) / desc->step; + + if (desc->min + desc->step * out_vol > max_vol) + return -EINVAL; + + return out_vol; +} + +static int s5m8767_set_voltage(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int min_vol = min_uV, max_vol = max_uV; + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int reg, mask, ret; + int i; + u8 val; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK1 ... S5M8767_BUCK6: + mask = 0xff; + break; + case S5M8767_BUCK7 ... S5M8767_BUCK8: + return -EINVAL; + case S5M8767_BUCK9: + mask = 0xff; + break; + default: + return -EINVAL; + } + + desc = reg_voltage_map[reg_id]; + + i = s5m8767_convert_voltage(desc, min_vol, max_vol); + if (i < 0) + return i; + + ret = s5m8767_get_voltage_register(rdev, ®); + if (ret) + return ret; + + s5m_reg_read(s5m8767->iodev, reg, &val); + val = val & mask; + + ret = s5m_reg_write(s5m8767->iodev, reg, val); + *selector = i; + + return ret; +} + +static inline void s5m8767_set_high(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); +} + +static inline void s5m8767_set_low(struct s5m8767_info *s5m8767) +{ + int temp_index = s5m8767->buck_gpioindex; + + gpio_set_value(s5m8767->buck_gpios[2], temp_index & 0x1); + gpio_set_value(s5m8767->buck_gpios[1], (temp_index >> 1) & 0x1); + gpio_set_value(s5m8767->buck_gpios[0], (temp_index >> 2) & 0x1); +} + +static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, + int min_uV, int max_uV, unsigned *selector) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + int reg_id = s5m8767_get_reg_id(rdev); + const struct s5m_voltage_desc *desc; + int new_val, old_val, i = 0; + int min_vol = min_uV, max_vol = max_uV; + + if (reg_id < S5M8767_BUCK1 || reg_id > S5M8767_BUCK6) + return -EINVAL; + + switch (reg_id) { + case S5M8767_BUCK1: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK2 ... S5M8767_BUCK4: + break; + case S5M8767_BUCK5 ... S5M8767_BUCK6: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + case S5M8767_BUCK9: + return s5m8767_set_voltage(rdev, min_uV, max_uV, selector); + } + + desc = reg_voltage_map[reg_id]; + new_val = s5m8767_convert_voltage(desc, min_vol, max_vol); + if (new_val < 0) + return new_val; + + switch (reg_id) { + case S5M8767_BUCK2: + if (s5m8767->buck2_gpiodvs) { + while (s5m8767->buck2_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK3: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck3_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + case S5M8767_BUCK4: + if (s5m8767->buck3_gpiodvs) { + while (s5m8767->buck4_vol[i] != new_val) + i++; + } else + return s5m8767_set_voltage(rdev, min_uV, + max_uV, selector); + break; + } + + old_val = s5m8767->buck_gpioindex; + s5m8767->buck_gpioindex = i; + + if (i > old_val) + s5m8767_set_high(s5m8767); + else + s5m8767_set_low(s5m8767); + + *selector = new_val; + return 0; +} + +static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, + unsigned int old_sel, + unsigned int new_sel) +{ + struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); + const struct s5m_voltage_desc *desc; + int reg_id = s5m8767_get_reg_id(rdev); + int mask; + int new_val, old_val; + + switch (reg_id) { + case S5M8767_LDO1 ... S5M8767_LDO28: + mask = 0x3f; + break; + case S5M8767_BUCK1 ... S5M8767_BUCK6: + mask = 0xff; + break; + case S5M8767_BUCK7 ... S5M8767_BUCK8: + return -EINVAL; + case S5M8767_BUCK9: + mask = 0xff; + break; + default: + return -EINVAL; + } + desc = reg_voltage_map[reg_id]; + + new_val = s5m8767_convert_voltage(desc, new_sel, new_sel); + if (new_val < 0) + return new_val; + + old_val = s5m8767_convert_voltage(desc, old_sel, old_sel); + if (old_val < 0) + return old_val; + + if (old_sel < new_sel) + return DIV_ROUND_UP(desc->step * (new_val - old_val), + s5m8767->ramp_delay); + else + return 0; +} + +static struct regulator_ops s5m8767_ldo_ops = { + .list_voltage = s5m8767_list_voltage, + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, + .get_voltage_sel = s5m8767_get_voltage_sel, + .set_voltage = s5m8767_set_voltage, + .set_voltage_time_sel = s5m8767_set_voltage_time_sel, +}; + +static struct regulator_ops s5m8767_buck_ops = { + .list_voltage = s5m8767_list_voltage, + .is_enabled = s5m8767_reg_is_enabled, + .enable = s5m8767_reg_enable, + .disable = s5m8767_reg_disable, + .get_voltage_sel = s5m8767_get_voltage_sel, + .set_voltage = s5m8767_set_voltage_buck, + .set_voltage_time_sel = s5m8767_set_voltage_time_sel, +}; + +#define regulator_desc_ldo(num) { \ + .name = "LDO"#num, \ + .id = S5M8767_LDO##num, \ + .ops = &s5m8767_ldo_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} +#define regulator_desc_buck(num) { \ + .name = "BUCK"#num, \ + .id = S5M8767_BUCK##num, \ + .ops = &s5m8767_buck_ops, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ +} + +static struct regulator_desc regulators[] = { + regulator_desc_ldo(1), + regulator_desc_ldo(2), + regulator_desc_ldo(3), + regulator_desc_ldo(4), + regulator_desc_ldo(5), + regulator_desc_ldo(6), + regulator_desc_ldo(7), + regulator_desc_ldo(8), + regulator_desc_ldo(9), + regulator_desc_ldo(10), + regulator_desc_ldo(11), + regulator_desc_ldo(12), + regulator_desc_ldo(13), + regulator_desc_ldo(14), + regulator_desc_ldo(15), + regulator_desc_ldo(16), + regulator_desc_ldo(17), + regulator_desc_ldo(18), + regulator_desc_ldo(19), + regulator_desc_ldo(20), + regulator_desc_ldo(21), + regulator_desc_ldo(22), + regulator_desc_ldo(23), + regulator_desc_ldo(24), + regulator_desc_ldo(25), + regulator_desc_ldo(26), + regulator_desc_ldo(27), + regulator_desc_ldo(28), + regulator_desc_buck(1), + regulator_desc_buck(2), + regulator_desc_buck(3), + regulator_desc_buck(4), + regulator_desc_buck(5), + regulator_desc_buck(6), + regulator_desc_buck(7), + regulator_desc_buck(8), + regulator_desc_buck(9), +}; + +static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) +{ + struct s5m87xx_dev *iodev = dev_get_drvdata(pdev->dev.parent); + struct s5m_platform_data *pdata = dev_get_platdata(iodev->dev); + struct regulator_dev **rdev; + struct s5m8767_info *s5m8767; + struct i2c_client *i2c; + int i, ret, size, reg; + + if (!pdata) { + dev_err(pdev->dev.parent, "Platform data not supplied\n"); + return -ENODEV; + } + + s5m8767 = devm_kzalloc(&pdev->dev, sizeof(struct s5m8767_info), + GFP_KERNEL); + if (!s5m8767) + return -ENOMEM; + + size = sizeof(struct regulator_dev *) * (S5M8767_REG_MAX - 2); + s5m8767->rdev = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); + if (!s5m8767->rdev) + return -ENOMEM; + + rdev = s5m8767->rdev; + s5m8767->dev = &pdev->dev; + s5m8767->iodev = iodev; + s5m8767->num_regulators = S5M8767_REG_MAX - 2; + platform_set_drvdata(pdev, s5m8767); + i2c = s5m8767->iodev->i2c; + + s5m8767->buck_gpioindex = pdata->buck_default_idx; + s5m8767->buck2_gpiodvs = pdata->buck2_gpiodvs; + s5m8767->buck3_gpiodvs = pdata->buck3_gpiodvs; + s5m8767->buck4_gpiodvs = pdata->buck4_gpiodvs; + s5m8767->buck_gpios[0] = pdata->buck_gpios[0]; + s5m8767->buck_gpios[1] = pdata->buck_gpios[1]; + s5m8767->buck_gpios[2] = pdata->buck_gpios[2]; + s5m8767->ramp_delay = pdata->buck_ramp_delay; + s5m8767->buck2_ramp = pdata->buck2_ramp_enable; + s5m8767->buck3_ramp = pdata->buck3_ramp_enable; + s5m8767->buck4_ramp = pdata->buck4_ramp_enable; + + for (i = 0; i < 8; i++) { + if (s5m8767->buck2_gpiodvs) { + s5m8767->buck2_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck2_voltage[i], + pdata->buck2_voltage[i] + + buck_voltage_val2.step); + } + + if (s5m8767->buck3_gpiodvs) { + s5m8767->buck3_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck3_voltage[i], + pdata->buck3_voltage[i] + + buck_voltage_val2.step); + } + + if (s5m8767->buck4_gpiodvs) { + s5m8767->buck4_vol[i] = + s5m8767_convert_voltage( + &buck_voltage_val2, + pdata->buck4_voltage[i], + pdata->buck4_voltage[i] + + buck_voltage_val2.step); + } + } + + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || + pdata->buck4_gpiodvs) { + if (gpio_is_valid(pdata->buck_gpios[0]) && + gpio_is_valid(pdata->buck_gpios[1]) && + gpio_is_valid(pdata->buck_gpios[2])) { + ret = gpio_request(pdata->buck_gpios[0], + "S5M8767 SET1"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET1\n"); + + ret = gpio_request(pdata->buck_gpios[1], + "S5M8767 SET2"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET2\n"); + + ret = gpio_request(pdata->buck_gpios[2], + "S5M8767 SET3"); + if (ret == -EBUSY) + dev_warn(&pdev->dev, "Duplicated gpio request for SET3\n"); + /* SET1 GPIO */ + gpio_direction_output(pdata->buck_gpios[0], + (s5m8767->buck_gpioindex >> 2) & 0x1); + /* SET2 GPIO */ + gpio_direction_output(pdata->buck_gpios[1], + (s5m8767->buck_gpioindex >> 1) & 0x1); + /* SET3 GPIO */ + gpio_direction_output(pdata->buck_gpios[2], + (s5m8767->buck_gpioindex >> 0) & 0x1); + ret = 0; + } else { + dev_err(&pdev->dev, "GPIO NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck2_gpiodvs) { + if (pdata->buck3_gpiodvs || pdata->buck4_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck3_gpiodvs) { + if (pdata->buck2_gpiodvs || pdata->buck4_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + if (pdata->buck4_gpiodvs) { + if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs) { + dev_err(&pdev->dev, "S5M8767 GPIO DVS NOT VALID\n"); + ret = -EINVAL; + return ret; + } + } + + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, + (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, + (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, + (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), 1 << 1); + + /* Initialize GPIO DVS registers */ + for (i = 0; i < 8; i++) { + if (s5m8767->buck2_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i, + s5m8767->buck2_vol[i]); + } + + if (s5m8767->buck3_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i, + s5m8767->buck3_vol[i]); + } + + if (s5m8767->buck4_gpiodvs) { + s5m_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i, + s5m8767->buck4_vol[i]); + } + } + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, 0x78, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, 0x58, 0xff); + s5m_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, 0x78, 0xff); + + if (s5m8767->buck2_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); + + if (s5m8767->buck3_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04); + + if (s5m8767->buck4_ramp) + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02); + + if (s5m8767->buck2_ramp || s5m8767->buck3_ramp + || s5m8767->buck4_ramp) { + switch (s5m8767->ramp_delay) { + case 15: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xc0, 0xf0); + case 25: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xd0, 0xf0); + case 50: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xe0, 0xf0); + case 100: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0xf0, 0xf0); + default: + s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, + 0x90, 0xf0); + } + } + + for (i = 0; i < pdata->num_regulators; i++) { + const struct s5m_voltage_desc *desc; + int id = pdata->regulators[i].id; + + desc = reg_voltage_map[id]; + if (desc) + regulators[id].n_voltages = + (desc->max - desc->min) / desc->step + 1; + + rdev[i] = regulator_register(®ulators[id], s5m8767->dev, + pdata->regulators[i].initdata, s5m8767); + if (IS_ERR(rdev[i])) { + ret = PTR_ERR(rdev[i]); + dev_err(s5m8767->dev, "regulator init failed for %d\n", + id); + rdev[i] = NULL; + goto err; + } + } + + return 0; +err: + for (i = 0; i < s5m8767->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + + return ret; +} + +static int __devexit s5m8767_pmic_remove(struct platform_device *pdev) +{ + struct s5m8767_info *s5m8767 = platform_get_drvdata(pdev); + struct regulator_dev **rdev = s5m8767->rdev; + int i; + + for (i = 0; i < s5m8767->num_regulators; i++) + if (rdev[i]) + regulator_unregister(rdev[i]); + + return 0; +} + +static const struct platform_device_id s5m8767_pmic_id[] = { + { "s5m8767-pmic", 0}, + { }, +}; +MODULE_DEVICE_TABLE(platform, s5m8767_pmic_id); + +static struct platform_driver s5m8767_pmic_driver = { + .driver = { + .name = "s5m8767-pmic", + .owner = THIS_MODULE, + }, + .probe = s5m8767_pmic_probe, + .remove = __devexit_p(s5m8767_pmic_remove), + .id_table = s5m8767_pmic_id, +}; + +static int __init s5m8767_pmic_init(void) +{ + return platform_driver_register(&s5m8767_pmic_driver); +} +subsys_initcall(s5m8767_pmic_init); + +static void __exit s5m8767_pmic_exit(void) +{ + platform_driver_unregister(&s5m8767_pmic_driver); +} +module_exit(s5m8767_pmic_exit); + +/* Module information */ +MODULE_AUTHOR("Sangbeom Kim "); +MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s5m8767-pmic"); -- cgit v1.2.3-70-g09d2 From 047ec220a49f96ab0f8bd0bc574368e2cae8f1f7 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 12 Jan 2012 14:57:09 +0800 Subject: regulator: s5m8767: Add missing breaks Signed-off-by: Axel Lin Acked-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index b3d356f5e27..40610126ab2 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -742,15 +742,19 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) case 15: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xc0, 0xf0); + break; case 25: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xd0, 0xf0); + break; case 50: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xe0, 0xf0); + break; case 100: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0xf0, 0xf0); + break; default: s5m_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x90, 0xf0); -- cgit v1.2.3-70-g09d2 From c835e1c00eda6f8f6c6bce49b2d89208f3a184dc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 12 Jan 2012 14:58:25 +0800 Subject: regulator: s5m8767: Remove redundant MODULE_ALIAS The MODULE_DEVICE_TABLE will setup the modalias, thus adding a MODULE_ALIAS for an entry already in s5m8767_pmic_id is redundant. Signed-off-by: Axel Lin Acked-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index 40610126ab2..caf0117b471 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -835,4 +835,3 @@ module_exit(s5m8767_pmic_exit); MODULE_AUTHOR("Sangbeom Kim "); MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s5m8767-pmic"); -- cgit v1.2.3-70-g09d2 From 38e968380b27d6c0f4b68bdd6e3161f8a7effe38 Mon Sep 17 00:00:00 2001 From: Bengt Jonsson Date: Fri, 13 Jan 2012 16:30:31 +0100 Subject: regulators/db8500: split off shared dbx500 code As we progress with DB5500 and future voltage domain regulators based on very similar hardware as found in the DB8500 PRCMU, it makes sense to split off the generic parts and introduce some generic debug code for the DBx500 regulators. This patch accoplish a basic abstraction of the DBx500 voltage domain regulators. Signed-off-by: Bengt Jonsson Signed-off-by: Linus Walleij Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 4 + drivers/regulator/Makefile | 1 + drivers/regulator/db8500-prcmu.c | 118 ++++++------------- drivers/regulator/dbx500-prcmu.c | 241 +++++++++++++++++++++++++++++++++++++++ drivers/regulator/dbx500-prcmu.h | 63 ++++++++++ 5 files changed, 341 insertions(+), 86 deletions(-) create mode 100644 drivers/regulator/dbx500-prcmu.c create mode 100644 drivers/regulator/dbx500-prcmu.h (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index b9ad3d8e03c..c7e49b140be 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -299,9 +299,13 @@ config REGULATOR_AB8500 This driver supports the regulators found on the ST-Ericsson mixed signal AB8500 PMIC +config REGULATOR_DBX500_PRCMU + bool + config REGULATOR_DB8500_PRCMU bool "ST-Ericsson DB8500 Voltage Domain Regulators" depends on MFD_DB8500_PRCMU + select REGULATOR_DBX500_PRCMU help This driver supports the voltage domain regulators controlled by the DB8500 PRCMU diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 1668b2e667c..bf595135248 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -45,6 +45,7 @@ obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o +obj-$(CONFIG_REGULATOR_DBX500_PRCMU) += dbx500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 515443fcd26..4bd25e75efa 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -18,74 +18,11 @@ #include #include #include - -/* - * power state reference count - */ -static int power_state_active_cnt; /* will initialize to zero */ -static DEFINE_SPINLOCK(power_state_active_lock); - -static void power_state_active_enable(void) -{ - unsigned long flags; - - spin_lock_irqsave(&power_state_active_lock, flags); - power_state_active_cnt++; - spin_unlock_irqrestore(&power_state_active_lock, flags); -} - -static int power_state_active_disable(void) -{ - int ret = 0; - unsigned long flags; - - spin_lock_irqsave(&power_state_active_lock, flags); - if (power_state_active_cnt <= 0) { - pr_err("power state: unbalanced enable/disable calls\n"); - ret = -EINVAL; - goto out; - } - - power_state_active_cnt--; -out: - spin_unlock_irqrestore(&power_state_active_lock, flags); - return ret; -} - -/* - * Exported interface for CPUIdle only. This function is called when interrupts - * are turned off. Hence, no locking. - */ -int power_state_active_is_enabled(void) -{ - return (power_state_active_cnt > 0); -} - -/** - * struct db8500_regulator_info - db8500 regulator information - * @dev: device pointer - * @desc: regulator description - * @rdev: regulator device pointer - * @is_enabled: status of the regulator - * @epod_id: id for EPOD (power domain) - * @is_ramret: RAM retention switch for EPOD (power domain) - * @operating_point: operating point (only for vape, to be removed) - * - */ -struct db8500_regulator_info { - struct device *dev; - struct regulator_desc desc; - struct regulator_dev *rdev; - bool is_enabled; - u16 epod_id; - bool is_ramret; - bool exclude_from_power_state; - unsigned int operating_point; -}; +#include "dbx500-prcmu.h" static int db8500_regulator_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -93,16 +30,18 @@ static int db8500_regulator_enable(struct regulator_dev *rdev) dev_vdbg(rdev_get_dev(rdev), "regulator-%s-enable\n", info->desc.name); - info->is_enabled = true; - if (!info->exclude_from_power_state) - power_state_active_enable(); + if (!info->is_enabled) { + info->is_enabled = true; + if (!info->exclude_from_power_state) + power_state_active_enable(); + } return 0; } static int db8500_regulator_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret = 0; if (info == NULL) @@ -111,16 +50,18 @@ static int db8500_regulator_disable(struct regulator_dev *rdev) dev_vdbg(rdev_get_dev(rdev), "regulator-%s-disable\n", info->desc.name); - info->is_enabled = false; - if (!info->exclude_from_power_state) - ret = power_state_active_disable(); + if (info->is_enabled) { + info->is_enabled = false; + if (!info->exclude_from_power_state) + ret = power_state_active_disable(); + } return ret; } static int db8500_regulator_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -197,7 +138,7 @@ static int disable_epod(u16 epod_id, bool ramret) */ static int db8500_regulator_switch_enable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -221,7 +162,7 @@ out: static int db8500_regulator_switch_disable(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); int ret; if (info == NULL) @@ -245,7 +186,7 @@ out: static int db8500_regulator_switch_is_enabled(struct regulator_dev *rdev) { - struct db8500_regulator_info *info = rdev_get_drvdata(rdev); + struct dbx500_regulator_info *info = rdev_get_drvdata(rdev); if (info == NULL) return -EINVAL; @@ -266,8 +207,8 @@ static struct regulator_ops db8500_regulator_switch_ops = { /* * Regulator information */ -static struct db8500_regulator_info -db8500_regulator_info[DB8500_NUM_REGULATORS] = { +static struct dbx500_regulator_info +dbx500_regulator_info[DB8500_NUM_REGULATORS] = { [DB8500_REGULATOR_VAPE] = { .desc = { .name = "db8500-vape", @@ -476,12 +417,12 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) int i, err; /* register all regulators */ - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; struct regulator_init_data *init_data = &db8500_init_data[i]; /* assign per-regulator data */ - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; info->dev = &pdev->dev; /* register with the regulator framework */ @@ -494,7 +435,7 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) /* if failing, unregister all earlier regulators */ while (--i >= 0) { - info = &db8500_regulator_info[i]; + info = &dbx500_regulator_info[i]; regulator_unregister(info->rdev); } return err; @@ -503,17 +444,22 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) dev_dbg(rdev_get_dev(info->rdev), "regulator-%s-probed\n", info->desc.name); } + err = ux500_regulator_debug_init(pdev, + dbx500_regulator_info, + ARRAY_SIZE(dbx500_regulator_info)); - return 0; + return err; } static int __exit db8500_regulator_remove(struct platform_device *pdev) { int i; - for (i = 0; i < ARRAY_SIZE(db8500_regulator_info); i++) { - struct db8500_regulator_info *info; - info = &db8500_regulator_info[i]; + ux500_regulator_debug_exit(); + + for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) { + struct dbx500_regulator_info *info; + info = &dbx500_regulator_info[i]; dev_vdbg(rdev_get_dev(info->rdev), "regulator-%s-remove\n", info->desc.name); diff --git a/drivers/regulator/dbx500-prcmu.c b/drivers/regulator/dbx500-prcmu.c new file mode 100644 index 00000000000..f2e5ecdc586 --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * License Terms: GNU General Public License v2 + * Authors: Sundar Iyer for ST-Ericsson + * Bengt Jonsson for ST-Ericsson + * + * UX500 common part of Power domain regulators + */ + +#include +#include +#include +#include +#include +#include + +#include "dbx500-prcmu.h" + +/* + * power state reference count + */ +static int power_state_active_cnt; /* will initialize to zero */ +static DEFINE_SPINLOCK(power_state_active_lock); + +int power_state_active_get(void) +{ + unsigned long flags; + int cnt; + + spin_lock_irqsave(&power_state_active_lock, flags); + cnt = power_state_active_cnt; + spin_unlock_irqrestore(&power_state_active_lock, flags); + + return cnt; +} + +void power_state_active_enable(void) +{ + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + power_state_active_cnt++; + spin_unlock_irqrestore(&power_state_active_lock, flags); +} + +int power_state_active_disable(void) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&power_state_active_lock, flags); + if (power_state_active_cnt <= 0) { + pr_err("power state: unbalanced enable/disable calls\n"); + ret = -EINVAL; + goto out; + } + + power_state_active_cnt--; +out: + spin_unlock_irqrestore(&power_state_active_lock, flags); + return ret; +} + +#ifdef CONFIG_REGULATOR_DEBUG + +static struct ux500_regulator_debug { + struct dentry *dir; + struct dentry *status_file; + struct dentry *power_state_cnt_file; + struct dbx500_regulator_info *regulator_array; + int num_regulators; + u8 *state_before_suspend; + u8 *state_after_suspend; +} rdebug; + +void ux500_regulator_suspend_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_before_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +void ux500_regulator_resume_debug(void) +{ + int i; + for (i = 0; i < rdebug.num_regulators; i++) + rdebug.state_after_suspend[i] = + rdebug.regulator_array[i].is_enabled; +} + +static int ux500_regulator_power_state_cnt_print(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + int err; + + /* print power state count */ + err = seq_printf(s, "ux500-regulator power state count: %i\n", + power_state_active_get()); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + return 0; +} + +static int ux500_regulator_power_state_cnt_open(struct inode *inode, + struct file *file) +{ + return single_open(file, ux500_regulator_power_state_cnt_print, + inode->i_private); +} + +static const struct file_operations ux500_regulator_power_state_cnt_fops = { + .open = ux500_regulator_power_state_cnt_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +static int ux500_regulator_status_print(struct seq_file *s, void *p) +{ + struct device *dev = s->private; + int err; + int i; + + /* print dump header */ + err = seq_printf(s, "ux500-regulator status:\n"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + err = seq_printf(s, "%31s : %8s : %8s\n", "current", + "before", "after"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + + for (i = 0; i < rdebug.num_regulators; i++) { + struct dbx500_regulator_info *info; + /* Access per-regulator data */ + info = &rdebug.regulator_array[i]; + + /* print status */ + err = seq_printf(s, "%20s : %8s : %8s : %8s\n", info->desc.name, + info->is_enabled ? "enabled" : "disabled", + rdebug.state_before_suspend[i] ? "enabled" : "disabled", + rdebug.state_after_suspend[i] ? "enabled" : "disabled"); + if (err < 0) + dev_err(dev, "seq_printf overflow\n"); + } + + return 0; +} + +static int ux500_regulator_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, ux500_regulator_status_print, + inode->i_private); +} + +static const struct file_operations ux500_regulator_status_fops = { + .open = ux500_regulator_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .owner = THIS_MODULE, +}; + +int __attribute__((weak)) dbx500_regulator_testcase( + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + return 0; +} + +int __devinit +ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + /* create directory */ + rdebug.dir = debugfs_create_dir("ux500-regulator", NULL); + if (!rdebug.dir) + goto exit_no_debugfs; + + /* create "status" file */ + rdebug.status_file = debugfs_create_file("status", + S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_status_fops); + if (!rdebug.status_file) + goto exit_destroy_dir; + + /* create "power-state-count" file */ + rdebug.power_state_cnt_file = debugfs_create_file("power-state-count", + S_IRUGO, rdebug.dir, &pdev->dev, + &ux500_regulator_power_state_cnt_fops); + if (!rdebug.power_state_cnt_file) + goto exit_destroy_status; + + rdebug.regulator_array = regulator_info; + rdebug.num_regulators = num_regulators; + + rdebug.state_before_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_before_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_destroy_power_state; + } + + rdebug.state_after_suspend = kzalloc(num_regulators, GFP_KERNEL); + if (!rdebug.state_after_suspend) { + dev_err(&pdev->dev, + "could not allocate memory for saving state\n"); + goto exit_free; + } + + dbx500_regulator_testcase(regulator_info, num_regulators); + return 0; + +exit_free: + kfree(rdebug.state_before_suspend); +exit_destroy_power_state: + debugfs_remove(rdebug.power_state_cnt_file); +exit_destroy_status: + debugfs_remove(rdebug.status_file); +exit_destroy_dir: + debugfs_remove(rdebug.dir); +exit_no_debugfs: + dev_err(&pdev->dev, "failed to create debugfs entries.\n"); + return -ENOMEM; +} + +int __devexit ux500_regulator_debug_exit(void) +{ + debugfs_remove_recursive(rdebug.dir); + kfree(rdebug.state_after_suspend); + kfree(rdebug.state_before_suspend); + + return 0; +} +#endif diff --git a/drivers/regulator/dbx500-prcmu.h b/drivers/regulator/dbx500-prcmu.h new file mode 100644 index 00000000000..e763883a44f --- /dev/null +++ b/drivers/regulator/dbx500-prcmu.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Bengt Jonsson for ST-Ericsson, + * Jonas Aaberg for ST-Ericsson + * + * License Terms: GNU General Public License v2 + * + */ + +#ifndef DBX500_REGULATOR_H +#define DBX500_REGULATOR_H + +#include + +/** + * struct dbx500_regulator_info - dbx500 regulator information + * @dev: device pointer + * @desc: regulator description + * @rdev: regulator device pointer + * @is_enabled: status of the regulator + * @epod_id: id for EPOD (power domain) + * @is_ramret: RAM retention switch for EPOD (power domain) + * @operating_point: operating point (only for vape, to be removed) + * + */ +struct dbx500_regulator_info { + struct device *dev; + struct regulator_desc desc; + struct regulator_dev *rdev; + bool is_enabled; + u16 epod_id; + bool is_ramret; + bool exclude_from_power_state; + unsigned int operating_point; +}; + +void power_state_active_enable(void); +int power_state_active_disable(void); + + +#ifdef CONFIG_REGULATOR_DEBUG +int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators); + +int ux500_regulator_debug_exit(void); +#else + +static inline int ux500_regulator_debug_init(struct platform_device *pdev, + struct dbx500_regulator_info *regulator_info, + int num_regulators) +{ + return 0; +} + +static inline int ux500_regulator_debug_exit(void) +{ + return 0; +} + +#endif +#endif -- cgit v1.2.3-70-g09d2 From 62aa492582cd6ce9f5e797ac3197239e63de1df9 Mon Sep 17 00:00:00 2001 From: Sangbeom Kim Date: Fri, 13 Jan 2012 10:13:13 +0900 Subject: regulator: Add S5M8767 configuration This patch add Samsung S5M8767A pmic configuration. Signed-off-by: Sangbeom Kim Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 8 ++++++++ drivers/regulator/Makefile | 2 ++ 2 files changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c7e49b140be..4792d661f0b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -136,6 +136,14 @@ config REGULATOR_MAX8998 via I2C bus. The provided regulator is suitable for S3C6410 and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. +config REGULATOR_S5M8767 + tristate "Samsung S5M8767A voltage regulator" + depends on MFD_S5M_CORE + help + This driver supports a Samsung S5M8767A voltage output regulator + via I2C bus. S5M8767A have 9 Bucks and 28 LDOs output and + supports DVS mode with 8bits of output voltage control. + config REGULATOR_TWL4030 bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC" depends on TWL4030_CORE diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index bf595135248..66be54a3e68 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -50,5 +50,7 @@ obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o +obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o + ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG -- cgit v1.2.3-70-g09d2 From a493077f1883a627d6ba2659b0a82888e58d31dd Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Wed, 11 Jan 2012 16:11:49 +0530 Subject: regulator: tps65217: Add tps65217 regulator driver This patch adds tps65217 PMIC as a regulator The regulator module consists of 3 DCDCs and 4 LDOs. The output voltages are configurable and are meant to supply power to the main processor and other components Signed-off-by: AnilKumar Ch Signed-off-by: Mark Brown --- drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/tps65217-regulator.c | 493 +++++++++++++++++++++++++++++++++ 3 files changed, 503 insertions(+) create mode 100644 drivers/regulator/tps65217-regulator.c (limited to 'drivers') diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 4792d661f0b..376824b865a 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -275,6 +275,15 @@ config REGULATOR_TPS6507X three step-down converters and two general-purpose LDO voltage regulators. It supports TI's software based Class-2 SmartReflex implementation. +config REGULATOR_TPS65217 + tristate "TI TPS65217 Power regulators" + depends on MFD_TPS65217 + help + This driver supports TPS65217 voltage regulator chips. TPS65217 + provides three step-down converters and four general-purpose LDO + voltage regulators. It supports software based voltage control + for different voltage domains + config REGULATOR_TPS65912 tristate "TI TPS65912 Power regulator" depends on (MFD_TPS65912_I2C || MFD_TPS65912_SPI) diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 66be54a3e68..4cbf8c55f8a 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -40,6 +40,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o +obj-$(CONFIG_REGULATOR_TPS65217) += tps65217-regulator.o obj-$(CONFIG_REGULATOR_TPS6524X) += tps6524x-regulator.o obj-$(CONFIG_REGULATOR_TPS65912) += tps65912-regulator.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c new file mode 100644 index 00000000000..66655668f96 --- /dev/null +++ b/drivers/regulator/tps65217-regulator.c @@ -0,0 +1,493 @@ +/* + * tps65217-regulator.c + * + * Regulator driver for TPS65217 PMIC + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TPS65217_REGULATOR(_name, _id, _ops, _n) \ + { \ + .name = _name, \ + .id = _id, \ + .ops = &_ops, \ + .n_voltages = _n, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } \ + +#define TPS65217_INFO(_nm, _min, _max, _f1, _f2, _t, _n, _em, _vr, _vm) \ + { \ + .name = _nm, \ + .min_uV = _min, \ + .max_uV = _max, \ + .vsel_to_uv = _f1, \ + .uv_to_vsel = _f2, \ + .table = _t, \ + .table_len = _n, \ + .enable_mask = _em, \ + .set_vout_reg = _vr, \ + .set_vout_mask = _vm, \ + } + +static const int LDO1_VSEL_table[] = { + 1000000, 1100000, 1200000, 1250000, + 1300000, 1350000, 1400000, 1500000, + 1600000, 1800000, 2500000, 2750000, + 2800000, 3000000, 3100000, 3300000, +}; + +static int tps65217_vsel_to_uv1(unsigned int vsel) +{ + int uV = 0; + + if (vsel > 63) + return -EINVAL; + + if (vsel <= 24) + uV = vsel * 25000 + 900000; + else if (vsel <= 52) + uV = (vsel - 24) * 50000 + 1500000; + else if (vsel < 56) + uV = (vsel - 52) * 100000 + 2900000; + else + uV = 3300000; + + return uV; +} + +static int tps65217_uv_to_vsel1(int uV, unsigned int *vsel) +{ + if ((uV < 0) && (uV > 3300000)) + return -EINVAL; + + if (uV <= 1500000) + *vsel = (uV - 875001) / 25000; + else if (uV <= 2900000) + *vsel = 24 + (uV - 1450001) / 50000; + else if (uV < 3300000) + *vsel = 52 + (uV - 2800001) / 100000; + else + *vsel = 56; + + return 0; +} + +static int tps65217_vsel_to_uv2(unsigned int vsel) +{ + int uV = 0; + + if (vsel > 31) + return -EINVAL; + + if (vsel <= 8) + uV = vsel * 50000 + 1500000; + else if (vsel <= 13) + uV = (vsel - 8) * 100000 + 1900000; + else + uV = (vsel - 13) * 50000 + 2400000; + + return uV; +} + +static int tps65217_uv_to_vsel2(int uV, unsigned int *vsel) +{ + if ((uV < 0) && (uV > 3300000)) + return -EINVAL; + + if (uV <= 1900000) + *vsel = (uV - 1450001) / 50000; + else if (uV <= 2400000) + *vsel = 8 + (uV - 1800001) / 100000; + else + *vsel = 13 + (uV - 2350001) / 50000; + + return 0; +} + +static struct tps_info tps65217_pmic_regs[] = { + TPS65217_INFO("DCDC1", 900000, 1800000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC1_EN, + TPS65217_REG_DEFDCDC1, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("DCDC2", 900000, 3300000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC2_EN, + TPS65217_REG_DEFDCDC2, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("DCDC3", 900000, 1500000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_DC3_EN, + TPS65217_REG_DEFDCDC3, TPS65217_DEFDCDCX_DCDC_MASK), + TPS65217_INFO("LDO1", 1000000, 3300000, NULL, NULL, LDO1_VSEL_table, + 16, TPS65217_ENABLE_LDO1_EN, TPS65217_REG_DEFLDO1, + TPS65217_DEFLDO1_LDO1_MASK), + TPS65217_INFO("LDO2", 900000, 3300000, tps65217_vsel_to_uv1, + tps65217_uv_to_vsel1, NULL, 64, TPS65217_ENABLE_LDO2_EN, + TPS65217_REG_DEFLDO2, TPS65217_DEFLDO2_LDO2_MASK), + TPS65217_INFO("LDO3", 1800000, 3300000, tps65217_vsel_to_uv2, + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN, + TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK), + TPS65217_INFO("LDO4", 1800000, 3300000, tps65217_vsel_to_uv2, + tps65217_uv_to_vsel2, NULL, 32, + TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN, + TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK), +}; + +static int tps65217_pmic_dcdc_is_enabled(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int data, dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); + if (ret) + return ret; + + return (data & tps->info[dcdc]->enable_mask) ? 1 : 0; +} + +static int tps65217_pmic_ldo_is_enabled(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int data, ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, TPS65217_REG_ENABLE, &data); + if (ret) + return ret; + + return (data & tps->info[ldo]->enable_mask) ? 1 : 0; +} + +static int tps65217_pmic_dcdc_enable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + /* Enable the regulator and password protection is level 1 */ + return tps65217_set_bits(tps, TPS65217_REG_ENABLE, + tps->info[dcdc]->enable_mask, + tps->info[dcdc]->enable_mask, + TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_dcdc_disable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + /* Disable the regulator and password protection is level 1 */ + return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, + tps->info[dcdc]->enable_mask, TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_ldo_enable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + /* Enable the regulator and password protection is level 1 */ + return tps65217_set_bits(tps, TPS65217_REG_ENABLE, + tps->info[ldo]->enable_mask, + tps->info[ldo]->enable_mask, + TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_ldo_disable(struct regulator_dev *dev) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + /* Disable the regulator and password protection is level 1 */ + return tps65217_clear_bits(tps, TPS65217_REG_ENABLE, + tps->info[ldo]->enable_mask, TPS65217_PROTECT_L1); +} + +static int tps65217_pmic_dcdc_get_voltage_sel(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int selector, dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + ret = tps65217_reg_read(tps, tps->info[dcdc]->set_vout_reg, &selector); + if (ret) + return ret; + + selector &= tps->info[dcdc]->set_vout_mask; + + return selector; +} + +static int tps65217_pmic_dcdc_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + if (min_uV < tps->info[dcdc]->min_uV + || min_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + + if (max_uV < tps->info[dcdc]->min_uV + || max_uV > tps->info[dcdc]->max_uV) + return -EINVAL; + + ret = tps->info[dcdc]->uv_to_vsel(min_uV, selector); + if (ret) + return ret; + + /* Set the voltage based on vsel value and write protect level is 2 */ + ret = tps65217_set_bits(tps, tps->info[dcdc]->set_vout_reg, + tps->info[dcdc]->set_vout_mask, + *selector, TPS65217_PROTECT_L2); + if (ret) + return ret; + + /* Set GO bit to initiate voltage transistion */ + return tps65217_set_bits(tps, TPS65217_REG_DEFSLEW, + TPS65217_DEFSLEW_GO, TPS65217_DEFSLEW_GO, + TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_ldo_get_voltage_sel(struct regulator_dev *dev) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int selector, ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + ret = tps65217_reg_read(tps, tps->info[ldo]->set_vout_reg, &selector); + if (ret) + return ret; + + selector &= tps->info[ldo]->set_vout_mask; + + return selector; +} + +static int tps65217_pmic_ldo_set_voltage_sel(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + int ldo = rdev_get_id(dev); + + if (ldo != TPS65217_LDO_1) + return -EINVAL; + + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; + + /* Set the voltage based on vsel value and write protect level is 2 */ + return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, + tps->info[ldo]->set_vout_mask, + selector, TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_ldo_set_voltage(struct regulator_dev *dev, + int min_uV, int max_uV, unsigned *selector) +{ + int ret; + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_2 || ldo > TPS65217_LDO_4) + return -EINVAL; + + if (min_uV < tps->info[ldo]->min_uV + || min_uV > tps->info[ldo]->max_uV) + return -EINVAL; + + if (max_uV < tps->info[ldo]->min_uV + || max_uV > tps->info[ldo]->max_uV) + return -EINVAL; + + ret = tps->info[ldo]->uv_to_vsel(min_uV, selector); + if (ret) + return ret; + + /* Set the voltage based on vsel value and write protect level is 2 */ + return tps65217_set_bits(tps, tps->info[ldo]->set_vout_reg, + tps->info[ldo]->set_vout_mask, + *selector, TPS65217_PROTECT_L2); +} + +static int tps65217_pmic_dcdc_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int dcdc = rdev_get_id(dev); + + if (dcdc < TPS65217_DCDC_1 || dcdc > TPS65217_DCDC_3) + return -EINVAL; + + if (selector >= tps->info[dcdc]->table_len) + return -EINVAL; + + return tps->info[dcdc]->vsel_to_uv(selector); +} + +static int tps65217_pmic_ldo_list_voltage(struct regulator_dev *dev, + unsigned selector) +{ + struct tps65217 *tps = rdev_get_drvdata(dev); + unsigned int ldo = rdev_get_id(dev); + + if (ldo < TPS65217_LDO_1 || ldo > TPS65217_LDO_4) + return -EINVAL; + + if (selector >= tps->info[ldo]->table_len) + return -EINVAL; + + if (tps->info[ldo]->table) + return tps->info[ldo]->table[selector]; + + return tps->info[ldo]->vsel_to_uv(selector); +} + +/* Operations permitted on DCDCx */ +static struct regulator_ops tps65217_pmic_dcdc_ops = { + .is_enabled = tps65217_pmic_dcdc_is_enabled, + .enable = tps65217_pmic_dcdc_enable, + .disable = tps65217_pmic_dcdc_disable, + .get_voltage_sel = tps65217_pmic_dcdc_get_voltage_sel, + .set_voltage = tps65217_pmic_dcdc_set_voltage, + .list_voltage = tps65217_pmic_dcdc_list_voltage, +}; + +/* Operations permitted on LDO1 */ +static struct regulator_ops tps65217_pmic_ldo1_ops = { + .is_enabled = tps65217_pmic_ldo_is_enabled, + .enable = tps65217_pmic_ldo_enable, + .disable = tps65217_pmic_ldo_disable, + .get_voltage_sel = tps65217_pmic_ldo_get_voltage_sel, + .set_voltage_sel = tps65217_pmic_ldo_set_voltage_sel, + .list_voltage = tps65217_pmic_ldo_list_voltage, +}; + +/* Operations permitted on LDO2, LDO3 and LDO4 */ +static struct regulator_ops tps65217_pmic_ldo234_ops = { + .is_enabled = tps65217_pmic_ldo_is_enabled, + .enable = tps65217_pmic_ldo_enable, + .disable = tps65217_pmic_ldo_disable, + .get_voltage_sel = tps65217_pmic_ldo_get_voltage_sel, + .set_voltage = tps65217_pmic_ldo_set_voltage, + .list_voltage = tps65217_pmic_ldo_list_voltage, +}; + +static struct regulator_desc regulators[] = { + TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("DCDC2",TPS65217_DCDC_2, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, + tps65217_pmic_dcdc_ops, 64), + TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, + tps65217_pmic_ldo1_ops, 16), + TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, + tps65217_pmic_ldo234_ops, 64), + TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, + tps65217_pmic_ldo234_ops, 32), + TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, + tps65217_pmic_ldo234_ops, 32), +}; + +static int __devinit tps65217_regulator_probe(struct platform_device *pdev) +{ + struct regulator_dev *rdev; + struct tps65217 *tps; + struct tps_info *info = &tps65217_pmic_regs[pdev->id]; + + /* Already set by core driver */ + tps = dev_to_tps65217(pdev->dev.parent); + tps->info[pdev->id] = info; + + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, + pdev->dev.platform_data, tps); + if (IS_ERR(rdev)) + return PTR_ERR(rdev); + + platform_set_drvdata(pdev, rdev); + + return 0; +} + +static int __devexit tps65217_regulator_remove(struct platform_device *pdev) +{ + struct regulator_dev *rdev = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + regulator_unregister(rdev); + + return 0; +} + +static struct platform_driver tps65217_regulator_driver = { + .driver = { + .name = "tps65217-pmic", + }, + .probe = tps65217_regulator_probe, + .remove = __devexit_p(tps65217_regulator_remove), +}; + +static int __init tps65217_regulator_init(void) +{ + return platform_driver_register(&tps65217_regulator_driver); +} +subsys_initcall(tps65217_regulator_init); + +static void __exit tps65217_regulator_exit(void) +{ + platform_driver_unregister(&tps65217_regulator_driver); +} +module_exit(tps65217_regulator_exit); + + +MODULE_AUTHOR("AnilKumar Ch "); +MODULE_DESCRIPTION("TPS65217 voltage regulator driver"); +MODULE_ALIAS("platform:tps65217-pmic"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From b683d980d8cd91f95a00c9be95ea5116a7db7537 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 15 Jan 2012 20:25:22 +0800 Subject: regulator: Update tps65217-regulator for DT changes Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/tps65217-regulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65217-regulator.c b/drivers/regulator/tps65217-regulator.c index 66655668f96..28a10eaeda1 100644 --- a/drivers/regulator/tps65217-regulator.c +++ b/drivers/regulator/tps65217-regulator.c @@ -447,7 +447,7 @@ static int __devinit tps65217_regulator_probe(struct platform_device *pdev) tps->info[pdev->id] = info; rdev = regulator_register(®ulators[pdev->id], &pdev->dev, - pdev->dev.platform_data, tps); + pdev->dev.platform_data, tps, NULL); if (IS_ERR(rdev)) return PTR_ERR(rdev); -- cgit v1.2.3-70-g09d2 From 0ce6987345a739fc3b2ac5da9c727c3b0133bb9c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 17 Jan 2012 11:25:45 +0000 Subject: regulator: Update s5m8767 for device tree API changes Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index caf0117b471..a5b9d83913f 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -771,7 +771,7 @@ static __devinit int s5m8767_pmic_probe(struct platform_device *pdev) (desc->max - desc->min) / desc->step + 1; rdev[i] = regulator_register(®ulators[id], s5m8767->dev, - pdata->regulators[i].initdata, s5m8767); + pdata->regulators[i].initdata, s5m8767, NULL); if (IS_ERR(rdev[i])) { ret = PTR_ERR(rdev[i]); dev_err(s5m8767->dev, "regulator init failed for %d\n", -- cgit v1.2.3-70-g09d2 From c2f8efd7641b1b10b73ffa6f216a45209a5705dd Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:46:56 +0530 Subject: regulator: tps65910: Add regulator info for RTC rail Adding missing regulator info for VRTC rail for device tps65911. The regulator voltage rail index start from VRTC which is defined as 0. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 5c15ba01e9c..67424185b36 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -174,6 +174,9 @@ static struct tps_info tps65910_regs[] = { }; static struct tps_info tps65911_regs[] = { + { + .name = "VRTC", + }, { .name = "VIO", .min_uV = 1500000, -- cgit v1.2.3-70-g09d2 From 070b9079226d4f3e3e7c9f4eb81f2e02e7d99572 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 16 Jan 2012 19:39:58 -0800 Subject: regulator: Add devm_regulator_get() Add a resource managed regulator_get() to simplify regulator usage in drivers. This allows driver authors to "get and forget" about their regulators by automatically calling regulator_put() when the driver is detached. [Fixed up a couple of coding style issues -- broonie] Signed-off-by: Stephen Boyd Signed-off-by: Mark Brown --- Documentation/driver-model/devres.txt | 3 +++ drivers/regulator/core.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 9 +++++++++ 3 files changed, 46 insertions(+) (limited to 'drivers') diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt index 10c64c8a13d..016fd2b06a5 100644 --- a/Documentation/driver-model/devres.txt +++ b/Documentation/driver-model/devres.txt @@ -267,3 +267,6 @@ IOMAP pcim_iounmap() pcim_iomap_table() : array of mapped addresses indexed by BAR pcim_iomap_regions() : do request_region() and iomap() on multiple BARs + +REGULATOR + devm_regulator_get() diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca86f39a0fd..214640db084 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1320,6 +1320,40 @@ struct regulator *regulator_get(struct device *dev, const char *id) } EXPORT_SYMBOL_GPL(regulator_get); +static void devm_regulator_release(struct device *dev, void *res) +{ + regulator_put(*(struct regulator **)res); +} + +/** + * devm_regulator_get - Resource managed regulator_get() + * @dev: device for regulator "consumer" + * @id: Supply name or regulator ID. + * + * Managed regulator_get(). Regulators returned from this function are + * automatically regulator_put() on driver detach. See regulator_get() for more + * information. + */ +struct regulator *devm_regulator_get(struct device *dev, const char *id) +{ + struct regulator **ptr, *regulator; + + ptr = devres_alloc(devm_regulator_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regulator = regulator_get(dev, id); + if (!IS_ERR(regulator)) { + *ptr = regulator; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regulator; +} +EXPORT_SYMBOL_GPL(devm_regulator_get); + /** * regulator_get_exclusive - obtain exclusive access to a regulator. * @dev: device for regulator "consumer" diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index f2698a0edfc..bcfe1065876 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -132,6 +132,8 @@ struct regulator_bulk_data { /* regulator get and put */ struct regulator *__must_check regulator_get(struct device *dev, const char *id); +struct regulator *__must_check devm_regulator_get(struct device *dev, + const char *id); struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); @@ -200,6 +202,13 @@ static inline struct regulator *__must_check regulator_get(struct device *dev, */ return NULL; } + +static inline struct regulator *__must_check +devm_regulator_get(struct device *dev, const char *id) +{ + return NULL; +} + static inline void regulator_put(struct regulator *regulator) { } -- cgit v1.2.3-70-g09d2 From 51ced5e288b4381705df173fb05f561dea35bfac Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Wed, 18 Jan 2012 20:47:16 +0530 Subject: regulator: tps65910: Initialize n_voltages for rails. Initializing the number of voltages supported by different rails of pmic device tps65911. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 67424185b36..3ac5f91a4f7 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -188,56 +188,67 @@ static struct tps_info tps65911_regs[] = { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, + .table_len = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, + .table_len = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, + .table_len = 24, }, }; -- cgit v1.2.3-70-g09d2 From 7d38a3cb9b9f6a6d31b1d19e4f07a7c0b71407d5 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 20 Jan 2012 16:36:22 +0530 Subject: regulator: tps65910: use appropriate variable names. Renaming the variables "table" to "voltage_table" and "table_len" to "n_voltages" of regulator information to have more meaningful. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 82 +++++++++++++++++----------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 3ac5f91a4f7..1d13cf997af 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -83,8 +83,8 @@ struct tps_info { const char *name; unsigned min_uV; unsigned max_uV; - u8 table_len; - const u16 *table; + u8 n_voltages; + const u16 *voltage_table; }; static struct tps_info tps65910_regs[] = { @@ -95,8 +95,8 @@ static struct tps_info tps65910_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", @@ -112,64 +112,64 @@ static struct tps_info tps65910_regs[] = { .name = "VDD3", .min_uV = 5000000, .max_uV = 5000000, - .table_len = ARRAY_SIZE(VDD3_VSEL_table), - .table = VDD3_VSEL_table, + .n_voltages = ARRAY_SIZE(VDD3_VSEL_table), + .voltage_table = VDD3_VSEL_table, }, { .name = "VDIG1", .min_uV = 1200000, .max_uV = 2700000, - .table_len = ARRAY_SIZE(VDIG1_VSEL_table), - .table = VDIG1_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG1_VSEL_table), + .voltage_table = VDIG1_VSEL_table, }, { .name = "VDIG2", .min_uV = 1000000, .max_uV = 1800000, - .table_len = ARRAY_SIZE(VDIG2_VSEL_table), - .table = VDIG2_VSEL_table, + .n_voltages = ARRAY_SIZE(VDIG2_VSEL_table), + .voltage_table = VDIG2_VSEL_table, }, { .name = "VPLL", .min_uV = 1000000, .max_uV = 2500000, - .table_len = ARRAY_SIZE(VPLL_VSEL_table), - .table = VPLL_VSEL_table, + .n_voltages = ARRAY_SIZE(VPLL_VSEL_table), + .voltage_table = VPLL_VSEL_table, }, { .name = "VDAC", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VDAC_VSEL_table), - .table = VDAC_VSEL_table, + .n_voltages = ARRAY_SIZE(VDAC_VSEL_table), + .voltage_table = VDAC_VSEL_table, }, { .name = "VAUX1", .min_uV = 1800000, .max_uV = 2850000, - .table_len = ARRAY_SIZE(VAUX1_VSEL_table), - .table = VAUX1_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX1_VSEL_table), + .voltage_table = VAUX1_VSEL_table, }, { .name = "VAUX2", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX2_VSEL_table), - .table = VAUX2_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX2_VSEL_table), + .voltage_table = VAUX2_VSEL_table, }, { .name = "VAUX33", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VAUX33_VSEL_table), - .table = VAUX33_VSEL_table, + .n_voltages = ARRAY_SIZE(VAUX33_VSEL_table), + .voltage_table = VAUX33_VSEL_table, }, { .name = "VMMC", .min_uV = 1800000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VMMC_VSEL_table), - .table = VMMC_VSEL_table, + .n_voltages = ARRAY_SIZE(VMMC_VSEL_table), + .voltage_table = VMMC_VSEL_table, }, }; @@ -181,74 +181,74 @@ static struct tps_info tps65911_regs[] = { .name = "VIO", .min_uV = 1500000, .max_uV = 3300000, - .table_len = ARRAY_SIZE(VIO_VSEL_table), - .table = VIO_VSEL_table, + .n_voltages = ARRAY_SIZE(VIO_VSEL_table), + .voltage_table = VIO_VSEL_table, }, { .name = "VDD1", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDD2", .min_uV = 600000, .max_uV = 4500000, - .table_len = 73, + .n_voltages = 73, }, { .name = "VDDCTRL", .min_uV = 600000, .max_uV = 1400000, - .table_len = 65, + .n_voltages = 65, }, { .name = "LDO1", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO2", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO3", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO4", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 47, + .n_voltages = 47, }, { .name = "LDO5", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO6", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO7", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, { .name = "LDO8", .min_uV = 1000000, .max_uV = 3300000, - .table_len = 24, + .n_voltages = 24, }, }; @@ -586,7 +586,7 @@ static int tps65910_get_voltage(struct regulator_dev *dev) return -EINVAL; } - voltage = pmic->info[id]->table[value] * 1000; + voltage = pmic->info[id]->voltage_table[value] * 1000; return voltage; } @@ -636,7 +636,7 @@ static int tps65911_get_voltage(struct regulator_dev *dev) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[value] * 1000; + return pmic->info[id]->voltage_table[value] * 1000; break; default: return -EINVAL; @@ -770,10 +770,10 @@ static int tps65910_list_voltage(struct regulator_dev *dev, if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC) return -EINVAL; - if (selector >= pmic->info[id]->table_len) + if (selector >= pmic->info[id]->n_voltages) return -EINVAL; else - voltage = pmic->info[id]->table[selector] * 1000; + voltage = pmic->info[id]->voltage_table[selector] * 1000; return voltage; } @@ -809,7 +809,7 @@ static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector) step_mv = 100; break; case TPS65910_REG_VIO: - return pmic->info[id]->table[selector] * 1000; + return pmic->info[id]->voltage_table[selector] * 1000; default: return -EINVAL; } @@ -940,7 +940,7 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].name = info->name; pmic->desc[i].id = i; - pmic->desc[i].n_voltages = info->table_len; + pmic->desc[i].n_voltages = info->n_voltages; if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) { pmic->desc[i].ops = &tps65910_ops_dcdc; -- cgit v1.2.3-70-g09d2 From 82159ba8e6ef8c38e3e0452d90b4ff8da9e4b2c1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 18 Jan 2012 10:52:25 +0000 Subject: regmap: Add support for padding between register and address Some devices, especially those with high speed control interfaces, require padding between the register and the data. Support this in the regmap API by providing a pad_bits configuration parameter. Only devices with integer byte counts are supported. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 1 + drivers/base/regmap/regmap.c | 32 +++++++++++++++++++++----------- include/linux/regmap.h | 2 ++ 3 files changed, 24 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 1a02b7537c8..e33f1be2b29 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -22,6 +22,7 @@ struct regcache_ops; struct regmap_format { size_t buf_size; size_t reg_bytes; + size_t pad_bytes; size_t val_bytes; void (*format_write)(struct regmap *map, unsigned int reg, unsigned int val); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..e9c2ac0174c 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -160,7 +160,9 @@ struct regmap *regmap_init(struct device *dev, mutex_init(&map->lock); map->format.buf_size = (config->reg_bits + config->val_bits) / 8; map->format.reg_bytes = config->reg_bits / 8; + map->format.pad_bytes = config->pad_bits / 8; map->format.val_bytes = config->val_bits / 8; + map->format.buf_size += map->format.pad_bytes; map->dev = dev; map->bus = bus; map->max_register = config->max_register; @@ -235,7 +237,7 @@ struct regmap *regmap_init(struct device *dev, !(map->format.format_reg && map->format.format_val)) goto err_map; - map->work_buf = kmalloc(map->format.buf_size, GFP_KERNEL); + map->work_buf = kzalloc(map->format.buf_size, GFP_KERNEL); if (map->work_buf == NULL) { ret = -ENOMEM; goto err_map; @@ -329,23 +331,28 @@ static int _regmap_raw_write(struct regmap *map, unsigned int reg, * send the work_buf directly, otherwise try to do a gather * write. */ - if (val == map->work_buf + map->format.reg_bytes) + if (val == (map->work_buf + map->format.pad_bytes + + map->format.reg_bytes)) ret = map->bus->write(map->dev, map->work_buf, - map->format.reg_bytes + val_len); + map->format.reg_bytes + + map->format.pad_bytes + + val_len); else if (map->bus->gather_write) ret = map->bus->gather_write(map->dev, map->work_buf, - map->format.reg_bytes, + map->format.reg_bytes + + map->format.pad_bytes, val, val_len); /* If that didn't work fall back on linearising by hand. */ if (ret == -ENOTSUPP) { - len = map->format.reg_bytes + val_len; - buf = kmalloc(len, GFP_KERNEL); + len = map->format.reg_bytes + map->format.pad_bytes + val_len; + buf = kzalloc(len, GFP_KERNEL); if (!buf) return -ENOMEM; memcpy(buf, map->work_buf, map->format.reg_bytes); - memcpy(buf + map->format.reg_bytes, val, val_len); + memcpy(buf + map->format.reg_bytes + map->format.pad_bytes, + val, val_len); ret = map->bus->write(map->dev, buf, len); kfree(buf); @@ -387,10 +394,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, return ret; } else { - map->format.format_val(map->work_buf + map->format.reg_bytes, - val); + map->format.format_val(map->work_buf + map->format.reg_bytes + + map->format.pad_bytes, val); return _regmap_raw_write(map, reg, - map->work_buf + map->format.reg_bytes, + map->work_buf + + map->format.reg_bytes + + map->format.pad_bytes, map->format.val_bytes); } } @@ -473,7 +482,8 @@ static int _regmap_raw_read(struct regmap *map, unsigned int reg, void *val, trace_regmap_hw_read_start(map->dev, reg, val_len / map->format.val_bytes); - ret = map->bus->read(map->dev, map->work_buf, map->format.reg_bytes, + ret = map->bus->read(map->dev, map->work_buf, + map->format.reg_bytes + map->format.pad_bytes, val, val_len); trace_regmap_hw_read_done(map->dev, reg, diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..a6ed6e6e27a 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -44,6 +44,7 @@ struct reg_default { * Configuration for the register map of a device. * * @reg_bits: Number of bits in a register address, mandatory. + * @pad_bits: Number of bits of padding between register and value. * @val_bits: Number of bits in a register value, mandatory. * * @writeable_reg: Optional callback returning true if the register @@ -74,6 +75,7 @@ struct reg_default { */ struct regmap_config { int reg_bits; + int pad_bits; int val_bits; bool (*writeable_reg)(struct device *dev, unsigned int reg); -- cgit v1.2.3-70-g09d2 From c2573128ad1ff36a7e231799c102be2413a2f756 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 10 Nov 2011 10:57:32 +0000 Subject: spi/s3c64xx: Log error interrupts Although the hardware supports interrupts we're not currently using them at all since for small transfers the overhead is greater than that for busy waiting and for large transfers we have interrupts from the DMA. This means that if the hardware reports an error (especially one which might not stall transfer) we might miss it. Take a first pass at dealing with such errors by enabling the interrupt if we can and logging the errors if they happen. Ideally we'd report the error via the affected transfer but since we're in master mode it's very difficult to trigger errors at present and this code is much simpler. Signed-off-by: Mark Brown Acked-by: Linus Walleij --- drivers/spi/spi-s3c64xx.c | 57 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 019a7163572..d56066bcbb9 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -153,6 +154,7 @@ struct s3c64xx_spi_dma_data { * @tx_dmach: Controller's DMA channel for Tx. * @sfr_start: BUS address of SPI controller regs. * @regs: Pointer to ioremap'ed controller registers. + * @irq: interrupt * @xfer_completion: To indicate completion of xfer task. * @cur_mode: Stores the active configuration of the controller. * @cur_bpw: Stores the active bits per word settings. @@ -930,6 +932,33 @@ setup_exit: return err; } +static irqreturn_t s3c64xx_spi_irq(int irq, void *data) +{ + struct s3c64xx_spi_driver_data *sdd = data; + struct spi_master *spi = sdd->master; + unsigned int val; + + val = readl(sdd->regs + S3C64XX_SPI_PENDING_CLR); + + val &= S3C64XX_SPI_PND_RX_OVERRUN_CLR | + S3C64XX_SPI_PND_RX_UNDERRUN_CLR | + S3C64XX_SPI_PND_TX_OVERRUN_CLR | + S3C64XX_SPI_PND_TX_UNDERRUN_CLR; + + writel(val, sdd->regs + S3C64XX_SPI_PENDING_CLR); + + if (val & S3C64XX_SPI_PND_RX_OVERRUN_CLR) + dev_err(&spi->dev, "RX overrun\n"); + if (val & S3C64XX_SPI_PND_RX_UNDERRUN_CLR) + dev_err(&spi->dev, "RX underrun\n"); + if (val & S3C64XX_SPI_PND_TX_OVERRUN_CLR) + dev_err(&spi->dev, "TX overrun\n"); + if (val & S3C64XX_SPI_PND_TX_UNDERRUN_CLR) + dev_err(&spi->dev, "TX underrun\n"); + + return IRQ_HANDLED; +} + static void s3c64xx_spi_hwinit(struct s3c64xx_spi_driver_data *sdd, int channel) { struct s3c64xx_spi_info *sci = sdd->cntrlr_info; @@ -970,7 +999,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) struct s3c64xx_spi_driver_data *sdd; struct s3c64xx_spi_info *sci; struct spi_master *master; - int ret; + int ret, irq; + char clk_name[16]; if (pdev->id < 0) { dev_err(&pdev->dev, @@ -1010,6 +1040,12 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return -ENXIO; } + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_warn(&pdev->dev, "Failed to get IRQ: %d\n", irq); + return irq; + } + master = spi_alloc_master(&pdev->dev, sizeof(struct s3c64xx_spi_driver_data)); if (master == NULL) { @@ -1104,10 +1140,21 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) INIT_WORK(&sdd->work, s3c64xx_spi_work); INIT_LIST_HEAD(&sdd->queue); + ret = request_irq(irq, s3c64xx_spi_irq, 0, "spi-s3c64xx", sdd); + if (ret != 0) { + dev_err(&pdev->dev, "Failed to request IRQ %d: %d\n", + irq, ret); + goto err8; + } + + writel(S3C64XX_SPI_INT_RX_OVERRUN_EN | S3C64XX_SPI_INT_RX_UNDERRUN_EN | + S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN, + sdd->regs + S3C64XX_SPI_INT_EN); + if (spi_register_master(master)) { dev_err(&pdev->dev, "cannot register SPI master\n"); ret = -EBUSY; - goto err8; + goto err9; } dev_dbg(&pdev->dev, "Samsung SoC SPI Driver loaded for Bus SPI-%d " @@ -1119,6 +1166,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) return 0; +err9: + free_irq(irq, sdd); err8: destroy_workqueue(sdd->workqueue); err7: @@ -1157,6 +1206,10 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) spi_unregister_master(master); + writel(0, sdd->regs + S3C64XX_SPI_INT_EN); + + free_irq(platform_get_irq(pdev, 0), sdd); + destroy_workqueue(sdd->workqueue); clk_disable(sdd->src_clk); -- cgit v1.2.3-70-g09d2 From e25d0bf917e8f3b6b5bafdc2fe666ca81eb9099d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 4 Dec 2011 00:36:18 +0000 Subject: spi/s3c64xx: Convert to dev_pm_ops In preparation for the addition of runtime PM ops. Signed-off-by: Mark Brown --- drivers/spi/spi-s3c64xx.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index d56066bcbb9..56dbdf15cba 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -1231,9 +1231,9 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) } #ifdef CONFIG_PM -static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) +static int s3c64xx_spi_suspend(struct device *dev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); unsigned long flags; @@ -1253,9 +1253,10 @@ static int s3c64xx_spi_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int s3c64xx_spi_resume(struct platform_device *pdev) +static int s3c64xx_spi_resume(struct device *dev) { - struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); + struct platform_device *pdev = to_platform_device(dev); + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); struct s3c64xx_spi_info *sci = sdd->cntrlr_info; unsigned long flags; @@ -1274,19 +1275,19 @@ static int s3c64xx_spi_resume(struct platform_device *pdev) return 0; } -#else -#define s3c64xx_spi_suspend NULL -#define s3c64xx_spi_resume NULL #endif /* CONFIG_PM */ +static const struct dev_pm_ops s3c64xx_spi_pm = { + SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume) +}; + static struct platform_driver s3c64xx_spi_driver = { .driver = { .name = "s3c64xx-spi", .owner = THIS_MODULE, + .pm = &s3c64xx_spi_pm, }, .remove = s3c64xx_spi_remove, - .suspend = s3c64xx_spi_suspend, - .resume = s3c64xx_spi_resume, }; MODULE_ALIAS("platform:s3c64xx-spi"); -- cgit v1.2.3-70-g09d2 From b97b662174162b44944abd0fa9faea50006ba711 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 4 Dec 2011 00:58:06 +0000 Subject: spi/s3c64xx: Implement runtime PM support Enable and disable the clocks to the SPI controller using runtime PM. This serves the dual purpose of reducing power consumption a little and letting the core know when the device is idle. Signed-off-by: Mark Brown Acked-by: Linus Walleij Acked-by: Heiko Stuebner --- drivers/spi/spi-s3c64xx.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 56dbdf15cba..b0b843b321b 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -782,6 +783,8 @@ static void s3c64xx_spi_work(struct work_struct *work) while (!acquire_dma(sdd)) msleep(10); + pm_runtime_get_sync(&sdd->pdev->dev); + spin_lock_irqsave(&sdd->lock, flags); while (!list_empty(&sdd->queue) @@ -810,6 +813,8 @@ static void s3c64xx_spi_work(struct work_struct *work) /* Free DMA channels */ sdd->ops->release(sdd->rx_dma.ch, &s3c64xx_spi_dma_client); sdd->ops->release(sdd->tx_dma.ch, &s3c64xx_spi_dma_client); + + pm_runtime_put(&sdd->pdev->dev); } static int s3c64xx_spi_transfer(struct spi_device *spi, @@ -892,6 +897,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi) goto setup_exit; } + pm_runtime_get_sync(&sdd->pdev->dev); + /* Check if we can provide the requested rate */ if (!sci->clk_from_cmu) { u32 psr, speed; @@ -924,6 +931,8 @@ static int s3c64xx_spi_setup(struct spi_device *spi) err = -EINVAL; } + pm_runtime_put(&sdd->pdev->dev); + setup_exit: /* setup() returns with device de-selected */ @@ -1164,6 +1173,8 @@ static int __init s3c64xx_spi_probe(struct platform_device *pdev) mem_res->end, mem_res->start, sdd->rx_dma.dmach, sdd->tx_dma.dmach); + pm_runtime_enable(&pdev->dev); + return 0; err9: @@ -1197,6 +1208,8 @@ static int s3c64xx_spi_remove(struct platform_device *pdev) struct resource *mem_res; unsigned long flags; + pm_runtime_disable(&pdev->dev); + spin_lock_irqsave(&sdd->lock, flags); sdd->state |= SUSPND; spin_unlock_irqrestore(&sdd->lock, flags); @@ -1277,8 +1290,34 @@ static int s3c64xx_spi_resume(struct device *dev) } #endif /* CONFIG_PM */ +#ifdef CONFIG_PM_RUNTIME +static int s3c64xx_spi_runtime_suspend(struct device *dev) +{ + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + + clk_disable(sdd->clk); + clk_disable(sdd->src_clk); + + return 0; +} + +static int s3c64xx_spi_runtime_resume(struct device *dev) +{ + struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); + struct s3c64xx_spi_driver_data *sdd = spi_master_get_devdata(master); + + clk_enable(sdd->src_clk); + clk_enable(sdd->clk); + + return 0; +} +#endif /* CONFIG_PM_RUNTIME */ + static const struct dev_pm_ops s3c64xx_spi_pm = { SET_SYSTEM_SLEEP_PM_OPS(s3c64xx_spi_suspend, s3c64xx_spi_resume) + SET_RUNTIME_PM_OPS(s3c64xx_spi_runtime_suspend, + s3c64xx_spi_runtime_resume, NULL) }; static struct platform_driver s3c64xx_spi_driver = { -- cgit v1.2.3-70-g09d2 From 71d676345698b275955b2584803ae550972249e5 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 17:46:41 -0300 Subject: [media] dvb: Add a new driver for az6007 Import the az6007 driver from Terratec H7 source, as-is. It won't compile or run, so latter patches are needed in order to fix it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 627 +++++++++++++++++++++++++++++++++++++ drivers/media/dvb/dvb-usb/az6007.h | 18 ++ 2 files changed, 645 insertions(+) create mode 100644 drivers/media/dvb/dvb-usb/az6007.c create mode 100644 drivers/media/dvb/dvb-usb/az6007.h (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c new file mode 100644 index 00000000000..cd5dd4cecd0 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -0,0 +1,627 @@ +/* DVB USB compliant Linux driver for the AzureWave 6017 USB2.0 DVB-S + * receiver. + * see Documentation/dvb/README.dvb-usb for more information + */ + +#include "az6007.h" +#include "drxk.h" +#include "mt2063.h" +#include "dvb_ca_en50221.h" + +/* debug */ +int dvb_usb_az6007_debug; +module_param_named(debug,dvb_usb_az6007_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + + +static int az6007_type =0; +module_param(az6007_type, int, 0644); +MODULE_PARM_DESC(az6007_type, "select delivery mode (0=DVB-T, 1=DVB-T"); + +//module_param_named(type, 6007_type, int, 0644); +//MODULE_PARM_DESC(type, "select delivery mode (0=DVB-T, 1=DVB-C)"); + +DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); + + +struct az6007_device_state { + struct dvb_ca_en50221 ca; + struct mutex ca_mutex; + u8 power_state; +}; + +struct drxk3913_config az6007_drxk3913_config_DVBT = { + .demod_address = 0x52, + .min_delay_ms = 100, + .standard = MTTUNEA_DVBT, + .set_tuner = mt2063_setTune, + .tuner_getlocked = mt2063_lockStatus, + .tuner_MT2063_Open = tuner_MT2063_Open, + .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, + .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +}; + +struct drxk3913_config az6007_drxk3913_config_DVBC = { + .demod_address = 0x52, + .min_delay_ms = 100, + .standard = MTTUNEA_DVBC, + .set_tuner = mt2063_setTune, + .tuner_getlocked = mt2063_lockStatus, + .tuner_MT2063_Open = tuner_MT2063_Open, + .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, + .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +}; + +struct mt2063_config az6007_mt2063_config = { + .tuner_address = 0xc0, + .refclock = 36125000, +}; + +/* check for mutex FIXME */ +int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +{ + int ret = -1; + + ret = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_IN, + value,index,b,blen, + 5000); + + if (ret < 0) { + warn("usb in operation failed. (%d)", ret); + ret = -EIO; + } else + ret = 0; + + + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + return ret; +} + +static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + int ret; + +#if 0 + int i=0, cyc=0, rem=0; + cyc = blen/64; + rem = blen%64; +#endif + + deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + +#if 0 + if (blen>64) + { + for (i=0; iudev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index+i*64,b+i*64,64, + 5000)) != 64) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + + if (rem>0) + { + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index+cyc*64,b+cyc*64,rem, + 5000)) != rem) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + } + else +#endif + { + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,b,blen, + 5000)) != blen) { + warn("usb out operation failed. (%d)",ret); + return -EIO; + } + } + + return 0; +} + +static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) +{ + return 0; +} + +/* keys for the enclosed remote control */ +static struct dvb_usb_rc_key az6007_rc_keys[] = { + { 0x00, 0x01, KEY_1 }, + { 0x00, 0x02, KEY_2 }, +}; + +/* remote control stuff (does not work with my box) */ +static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + return 0; +#if 0 + u8 key[10]; + int i; + +/* remove the following return to enabled remote querying */ + + + az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); + + deb_rc("remote query key: %x %d\n",key[1],key[1]); + + if (key[1] == 0x44) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + for (i = 0; i < ARRAY_SIZE(az6007_rc_keys); i++) + if (az6007_rc_keys[i].custom == key[1]) { + *state = REMOTE_KEY_PRESSED; + *event = az6007_rc_keys[i].event; + break; + } + return 0; +#endif +} + +/* +int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + u8 v = onoff; + return az6007_usb_out_op(d,0xBC,v,3,NULL,1); +} +*/ + +static int az6007_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +{ + az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); + return 0; +} + +static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + + info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); + + req = 0xBC; + value = 1;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + + msleep_interruptible(200); + + req = 0xBC; + value = 0;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + + msleep_interruptible(200); + + req = 0xBC; + value = 1;//power on + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_poweron failed!!!"); + return -EIO; + } + info("az6007_frontend_poweron\n"); + return 0; +} + +static int az6007_frontend_reset(struct dvb_usb_adapter *adap) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + + info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); + + //reset demodulator + req = 0xC0; + value = 1;//high + index = 3; + blen =0; + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 1 !!!"); + return -EIO; + } + + req = 0xC0; + value = 0;//low + index = 3; + blen =0; + msleep_interruptible(200); + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 2 !!!"); + return -EIO; + } + msleep_interruptible(200); + req = 0xC0; + value = 1;//high + index = 3; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + { + err("az6007_frontend_reset failed 3 !!!"); + return -EIO; + } + + msleep_interruptible(200); + + info("reset az6007 frontend\n"); + + return 0; +} + +static int az6007_led_on_off(struct usb_interface *intf, int onoff) +{ + int ret = -1; + u8 req; + u16 value; + u16 index; + int blen; + //TS through + req = 0xBC; + value = onoff; + index = 0; + blen =0; + + ret = usb_control_msg(interface_to_usbdev(intf), + usb_rcvctrlpipe(interface_to_usbdev(intf),0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,NULL,blen, + 2000); + + if (ret < 0) { + warn("usb in operation failed. (%d)", ret); + ret = -EIO; + } else + ret = 0; + + + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + + return ret; +} + +static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) +{ + int ret; + u8 req; + u16 value; + u16 index; + int blen; + //TS through + req = 0xC7; + value = onoff; + index = 0; + blen =0; + + if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) + return -EIO; + return 0; +} + +static int az6007_frontend_attach(struct dvb_usb_adapter *adap) +{ + az6007_frontend_poweron(adap); + az6007_frontend_reset(adap); + + info("az6007_frontend_attach\n"); + + if (az6007_type == 0) + { + info("az6007_drxk3913_config_DVBT\n"); + adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBT, &adap->dev->i2c_adap); + } + else + { + info("az6007_drxk3913_config_DVBC\n"); + adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBC, &adap->dev->i2c_adap); + } + if (adap->fe) { + if (mt2063_attach(adap->fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) { + info("found STB6100 DVB-C/DVB-T frontend @0x%02x\n",az6007_mt2063_config.tuner_address); + + //vp6027_ci_init(adap); + } else { + adap->fe = NULL; + } + } + else + { + adap->fe = NULL; + err("no front-end attached\n"); + } + //az6007_frontend_tsbypass(adap,0); + + return 0; +} + +static struct dvb_usb_device_properties az6007_properties; + +static void +az6007_usb_disconnect(struct usb_interface *intf) +{ + dvb_usb_device_exit (intf); +} + +/* I2C */ +static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ + struct dvb_usb_device *d = i2c_get_adapdata(adap); + int j=0,len=0; + int ret=0; + u16 index; + u16 value; + int length; + u8 req; + u8 data[512]; + + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + return -EAGAIN; + if (num > 2) + warn("more than 2 i2c messages at a time is not handled yet. TODO."); + + + if (msg[0].addr == 0xc0) //MT2063 + { + if (msg[0].flags != I2C_M_RD) //write + { + //printk("Tuner Tuner Write DevAddr=%02x RegAddr=%d\n", msg[0].addr, msg[0].buf[0]); + req = 0xBD; + index = msg[0].buf[0]; + value = msg[0].addr | (1<<8); + length = msg[0].len - 1; + len = msg[0].len - 1; + //printk("Tuner Tuner WriteDATA len=%d ", len); + for(j=0;ji2c_mutex); + return ret; +} + + +static u32 az6007_i2c_func(struct i2c_adapter *adapter) +{ + return I2C_FUNC_I2C; +} + +static struct i2c_algorithm az6007_i2c_algo = { + .master_xfer = az6007_i2c_xfer, + .functionality = az6007_i2c_func, +#ifdef NEED_ALGO_CONTROL + .algo_control = dummy_algo_control, +#endif +}; + +int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) +{ + u8 b[16]; + s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), + 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); + + info("FW GET_VERSION length: %d\n",ret); + + *cold = ret <= 0; + + info("cold: %d\n", *cold); + return 0; +} + +static int az6007_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + az6007_led_on_off(intf, 0); + + return dvb_usb_device_init(intf, &az6007_properties, + THIS_MODULE, NULL, adapter_nr); +} + +static struct usb_device_id az6007_usb_table [] = { + { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007) }, + { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7) }, + { 0 }, +}; + +MODULE_DEVICE_TABLE(usb, az6007_usb_table); + +static struct dvb_usb_device_properties az6007_properties = { + .caps = DVB_USB_IS_AN_I2C_ADAPTER, + .usb_ctrl = CYPRESS_FX2, + //.download_firmware = az6007_download_firmware, + .firmware = "dvb-usb-az6007-03.fw", + .no_reconnect = 1, + + .size_of_priv = sizeof(struct az6007_device_state), + .identify_state = az6007_identify_state, + .num_adapters = 1, + .adapter = { + { + //.caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, + + .streaming_ctrl = az6007_streaming_ctrl, + .frontend_attach = az6007_frontend_attach, + + /* parameter for the MPEG2-data transfer */ + .stream = { + .type = USB_BULK, + .count = 10, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + .size_of_priv = 0,//sizeof(struct az6007_state), + } + }, + //.power_ctrl = az6007_power_ctrl, + .read_mac_address = az6007_read_mac_addr, + + .rc_key_map = az6007_rc_keys, + .rc_key_map_size = ARRAY_SIZE(az6007_rc_keys), + .rc_interval = 400, + .rc_query = az6007_rc_query, + .i2c_algo = &az6007_i2c_algo, + + .num_device_descs = 2, + .devices = { + { .name = "AzureWave DTV StarBox DVB-T/C USB2.0 (az6007)", + .cold_ids = { &az6007_usb_table[0], NULL }, + .warm_ids = { NULL }, + }, + { .name = "TerraTec DTV StarBox DVB-T/C USB2.0 (az6007)", + .cold_ids = { &az6007_usb_table[1], NULL }, + .warm_ids = { NULL }, + }, + { NULL }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver az6007_usb_driver = { + .name = "dvb_usb_az6007", + .probe = az6007_usb_probe, + .disconnect = dvb_usb_device_exit, + //.disconnect = az6007_usb_disconnect, + .id_table = az6007_usb_table, +}; + +/* module stuff */ +static int __init az6007_usb_module_init(void) +{ + int result; + info("henry :: az6007 usb module init"); + if ((result = usb_register(&az6007_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit az6007_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + info("henry :: az6007 usb module exit"); + usb_deregister(&az6007_usb_driver); +} + +module_init(az6007_usb_module_init); +module_exit(az6007_usb_module_exit); + +MODULE_AUTHOR("Henry Wang "); +MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); +MODULE_VERSION("1.0"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/az6007.h b/drivers/media/dvb/dvb-usb/az6007.h new file mode 100644 index 00000000000..aefa5b506ee --- /dev/null +++ b/drivers/media/dvb/dvb-usb/az6007.h @@ -0,0 +1,18 @@ +#ifndef _DVB_USB_AZ6007_H_ +#define _DVB_USB_AZ6007_H_ + +#define DVB_USB_LOG_PREFIX "az6007" +#include "dvb-usb.h" + + +extern int dvb_usb_az6007_debug; +#define deb_info(args...) dprintk(dvb_usb_az6007_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug,0x02,args) +#define deb_rc(args...) dprintk(dvb_usb_az6007_debug,0x04,args) +#define deb_fe(args...) dprintk(dvb_usb_az6007_debug,0x08,args) + + +extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); +extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); + +#endif -- cgit v1.2.3-70-g09d2 From 6da347065062d28de035c01b298c6aebab2723fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 18:31:14 -0300 Subject: [media] az6007: Fix compilation troubles at az6007 Some changes are needed, in order to make az6007 compile with the upstream tree. Most of the changes are due to the upstream drxk module. Even allowing its compilation, the driver is not working yet. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/common/tuners/mt2063.c | 2 +- drivers/media/dvb/dvb-usb/az6007.c | 174 +++++++++++++++++++++-------------- 2 files changed, 104 insertions(+), 72 deletions(-) (limited to 'drivers') diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c index c89af3cd5eb..7bbf25da3ef 100644 --- a/drivers/media/common/tuners/mt2063.c +++ b/drivers/media/common/tuners/mt2063.c @@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe) /* * ToDo: Add code here to implement a OS blocking */ - msleep(10); + msleep(100); return 0; } diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index cd5dd4cecd0..5873759f5db 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -8,6 +8,10 @@ #include "mt2063.h" #include "dvb_ca_en50221.h" +/* HACK: Should be moved to the right place */ +#define USB_PID_AZUREWAVE_6007 0xccd +#define USB_PID_TERRATEC_H7 0x10b4 + /* debug */ int dvb_usb_az6007_debug; module_param_named(debug,dvb_usb_az6007_debug, int, 0644); @@ -28,30 +32,39 @@ struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; u8 power_state; -}; -struct drxk3913_config az6007_drxk3913_config_DVBT = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBT, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, + /* Due to DRX-K - probably need changes */ + int (*gate_ctrl)(struct dvb_frontend *, int); + struct semaphore pll_mutex; + bool dont_attach_fe1; }; -struct drxk3913_config az6007_drxk3913_config_DVBC = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBC, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +struct drxk_config terratec_h7_drxk = { + .adr = 0x29, + .single_master = 1, + .no_i2c_bridge = 1, + .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; +static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->sec_priv; + struct az6007_device_state *st = adap->priv; + int status; + + if (!adap || !st) + return -EINVAL; + + if (enable) { + down(&st->pll_mutex); + status = st->gate_ctrl(fe, 1); + } else { + status = st->gate_ctrl(fe, 0); + up(&st->pll_mutex); + } + return status; +} + struct mt2063_config az6007_mt2063_config = { .tuner_address = 0xc0, .refclock = 36125000, @@ -87,7 +100,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; -#if 0 +#if 0 int i=0, cyc=0, rem=0; cyc = blen/64; rem = blen%64; @@ -96,7 +109,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); - + #if 0 if (blen>64) { @@ -110,7 +123,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 5000)) != 64) { warn("usb out operation failed. (%d)",ret); return -EIO; - } + } } if (rem>0) @@ -127,7 +140,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, } } else -#endif +#endif { if ((ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), @@ -139,7 +152,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, return -EIO; } } - + return 0; } @@ -149,9 +162,9 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -static struct dvb_usb_rc_key az6007_rc_keys[] = { - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, +struct rc_map_table rc_map_az6007_table[] = { + { 0x0001, KEY_1 }, + { 0x0002, KEY_2 }, }; /* remote control stuff (does not work with my box) */ @@ -163,7 +176,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) int i; /* remove the following return to enabled remote querying */ - + az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); @@ -257,7 +270,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) int blen; info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); - + //reset demodulator req = 0xC0; value = 1;//high @@ -268,7 +281,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 1 !!!"); return -EIO; } - + req = 0xC0; value = 0;//low index = 3; @@ -290,11 +303,11 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 3 !!!"); return -EIO; } - + msleep_interruptible(200); - + info("reset az6007 frontend\n"); - + return 0; } @@ -350,38 +363,55 @@ static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { + struct az6007_device_state *st = adap->priv; + + int result; + az6007_frontend_poweron(adap); az6007_frontend_reset(adap); info("az6007_frontend_attach\n"); - if (az6007_type == 0) - { - info("az6007_drxk3913_config_DVBT\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBT, &adap->dev->i2c_adap); + adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap, &adap->fe2); + if (!adap->fe) { + result = -EINVAL; + goto out_free; } - else - { - info("az6007_drxk3913_config_DVBC\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBC, &adap->dev->i2c_adap); - } - if (adap->fe) { - if (mt2063_attach(adap->fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) { - info("found STB6100 DVB-C/DVB-T frontend @0x%02x\n",az6007_mt2063_config.tuner_address); - - //vp6027_ci_init(adap); - } else { - adap->fe = NULL; - } - } - else - { - adap->fe = NULL; - err("no front-end attached\n"); + + /* FIXME: do we need a pll semaphore? */ + adap->fe->sec_priv = adap; + sema_init(&st->pll_mutex, 1); + st->gate_ctrl = adap->fe->ops.i2c_gate_ctrl; + adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; + adap->fe2->id = 1; + + /* Attach mt2063 to DVB-C frontend */ + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); + if (!dvb_attach(mt2063_attach, adap->fe, &az6007_mt2063_config, + &adap->dev->i2c_adap)) { + result = -EINVAL; + + goto out_free; } - //az6007_frontend_tsbypass(adap,0); - + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 0); + + /* Hack - needed due to drxk */ + adap->fe2->tuner_priv = adap->fe->tuner_priv; + memcpy(&adap->fe2->ops.tuner_ops, + &adap->fe->ops.tuner_ops, + sizeof(adap->fe->ops.tuner_ops)); return 0; + +out_free: + if (adap->fe) + dvb_frontend_detach(adap->fe); + adap->fe = NULL; + adap->fe2 = NULL; + + return result; } static struct dvb_usb_device_properties az6007_properties; @@ -403,7 +433,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num int length; u8 req; u8 data[512]; - + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (num > 2) @@ -442,7 +472,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num //printk("Tuner Tuner ReadDATA len=%d ", len); for (j=0; j Date: Fri, 22 Jul 2011 10:31:25 -0300 Subject: [media] az6007: Fix it to allow loading it without crash Add some fixes to allow frontend attachment. The patch is not complete yet, as just the frontend 0 is initialized. So, more changes will be needed, including some changes at dvb-usb core. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 190 +++++++++++++++++++------------------ 1 file changed, 98 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 5873759f5db..6a21f928550 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -49,12 +49,20 @@ struct drxk_config terratec_h7_drxk = { static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct dvb_usb_adapter *adap = fe->sec_priv; - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st; int status; - if (!adap || !st) + info("%s", __func__); + + if (!adap) + return -EINVAL; + + st = adap->priv; + + if (!st) return -EINVAL; + if (enable) { down(&st->pll_mutex); status = st->gate_ctrl(fe, 1); @@ -66,7 +74,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) } struct mt2063_config az6007_mt2063_config = { - .tuner_address = 0xc0, + .tuner_address = 0x60, .refclock = 36125000, }; @@ -84,10 +92,8 @@ int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 if (ret < 0) { warn("usb in operation failed. (%d)", ret); - ret = -EIO; - } else - ret = 0; - + return -EIO; + } deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); @@ -219,7 +225,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); + info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); req = 0xBC; value = 1;//power on @@ -257,7 +263,8 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) err("az6007_frontend_poweron failed!!!"); return -EIO; } - info("az6007_frontend_poweron\n"); + info("az6007_frontend_poweron: OK"); + return 0; } @@ -269,7 +276,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); + info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); //reset demodulator req = 0xC0; @@ -306,7 +313,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) msleep_interruptible(200); - info("reset az6007 frontend\n"); + info("reset az6007 frontend"); return 0; } @@ -367,10 +374,12 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) int result; + BUG_ON(!st); + az6007_frontend_poweron(adap); az6007_frontend_reset(adap); - info("az6007_frontend_attach\n"); + info("az6007_frontend_attach: drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap, &adap->fe2); @@ -379,6 +388,8 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) goto out_free; } + info("Setting hacks"); + /* FIXME: do we need a pll semaphore? */ adap->fe->sec_priv = adap; sema_init(&st->pll_mutex, 1); @@ -386,6 +397,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; adap->fe2->id = 1; + info("az6007_frontend_attach: mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe->ops.i2c_gate_ctrl) adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); @@ -423,100 +435,95 @@ az6007_usb_disconnect(struct usb_interface *intf) } /* I2C */ -static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) +static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); - int j=0,len=0; - int ret=0; + int i, j, len; + int ret = 0; u16 index; u16 value; int length; - u8 req; + u8 req, addr; u8 data[512]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; - if (num > 2) - warn("more than 2 i2c messages at a time is not handled yet. TODO."); - - if (msg[0].addr == 0xc0) //MT2063 - { - if (msg[0].flags != I2C_M_RD) //write - { - //printk("Tuner Tuner Write DevAddr=%02x RegAddr=%d\n", msg[0].addr, msg[0].buf[0]); - req = 0xBD; - index = msg[0].buf[0]; - value = msg[0].addr | (1<<8); - length = msg[0].len - 1; - len = msg[0].len - 1; - //printk("Tuner Tuner WriteDATA len=%d ", len); - for(j=0;j= len) { + for (j = 0; j < len; j++) { + msgs[i + 1].buf[j] = data[j + 5]; + printk("0x%02x ", msgs[i + 1].buf[j]); + } + } else + ret = -EIO; + i++; + } else if (!(msgs[i].flags & I2C_M_RD)) { + /* write bytes */ +// printk("az6007 I2C xfer write addr=0x%x len=%d: ", +// addr, msgs[i].len); + req = 0xbd; + index = msgs[i].buf[0]; + value = addr | (1 << 8); + length = msgs[i].len - 1; + len = msgs[i].len - 1; +// printk("(0x%02x) ", msgs[i].buf[0]); + for (j = 0; j < len; j++) { - data[j] = msg[0].buf[j+1]; - //printk("data[%d]=%02x ", j, data[j]); + data[j] = msgs[i].buf[j + 1]; +// printk("0x%02x ", data[j]); } - //printk("\n"); ret = az6007_usb_out_op(d,req,value,index,data,length); - } - else //read - { - //printk("Demodulator Read DevAddr=%02x RegAddr=%02x\n", msg[0].addr, msg[0].buf[0]); - req = 0xB9; - index = 0; - value = msg[0].addr + (0 << 8); - length = msg[0].len + 6; + } else { + /* read bytes */ +// printk("az6007 I2C xfer read addr=0x%x len=%d: ", +// addr, msgs[i].len); + req = 0xb9; + index = msgs[i].buf[0]; + value = addr; + length = msgs[i].len + 6; + len = msgs[i].len; ret = az6007_usb_in_op(d,req,value,index,data,length); - len = msg[0].len; - //printk("Demodulator ReadDATA len=%d ", len); - for (j=0; ji2c_mutex); - return ret; + + if (ret < 0) { + info("%s ERROR: %i\n", __func__, ret); + return ret; + } + return num; } @@ -540,11 +547,11 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_propert s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d\n",ret); + info("FW GET_VERSION length: %d",ret); *cold = ret <= 0; - info("cold: %d\n", *cold); + info("cold: %d", *cold); return 0; } @@ -572,7 +579,6 @@ static struct dvb_usb_device_properties az6007_properties = { .firmware = "dvb-usb-az6007-03.fw", .no_reconnect = 1, - .size_of_priv = sizeof(struct az6007_device_state), .identify_state = az6007_identify_state, .num_adapters = 1, .adapter = { @@ -593,7 +599,7 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - .size_of_priv = 0,//sizeof(struct az6007_state), + .size_of_priv = sizeof(struct az6007_device_state), } }, //.power_ctrl = az6007_power_ctrl, @@ -634,7 +640,7 @@ static struct usb_driver az6007_usb_driver = { static int __init az6007_usb_module_init(void) { int result; - info("henry :: az6007 usb module init"); + info("az6007 usb module init"); if ((result = usb_register(&az6007_usb_driver))) { err("usb_register failed. (%d)",result); return result; @@ -646,7 +652,7 @@ static int __init az6007_usb_module_init(void) static void __exit az6007_usb_module_exit(void) { /* deregister this driver from the USB subsystem */ - info("henry :: az6007 usb module exit"); + info("az6007 usb module exit"); usb_deregister(&az6007_usb_driver); } -- cgit v1.2.3-70-g09d2 From d20a7f7277785e6f7fbe02eb469f7a99a9f058a4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 09:51:12 -0300 Subject: [media] az6007: Fix the I2C code in order to handle mt2063 mt2063 uses a one-byte transfer. This requires a special handling inside the i2c code. Fix it to properly accept i2c reads. This is needed to make the mt2063 to be detected. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 47 ++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 6a21f928550..56126d41a60 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -42,7 +42,7 @@ struct az6007_device_state { struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, - .no_i2c_bridge = 1, + .no_i2c_bridge = 0, .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; @@ -451,7 +451,6 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu for (i = 0; i < num; i++) { addr = msgs[i].addr << 1; - if (((i + 1) < num) && (msgs[i].len == 1) && (!msgs[i].flags & I2C_M_RD) @@ -462,44 +461,55 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu * the first xfer has just 1 byte length. * Need to join both into one operation */ - printk("az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", - addr, msgs[i].len, msgs[i + 1].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", + addr, msgs[i].len, msgs[i + 1].len); req = 0xb9; - index = 0; - value = addr; - for (j = 0; j < msgs[i].len; j++) - data[j] = msgs[i].buf[j]; + index = msgs[i].buf[0]; + value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; ret = az6007_usb_in_op(d,req,value,index,data,length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = data[j + 5]; - printk("0x%02x ", msgs[i + 1].buf[j]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", + msgs[i + 1].buf[j]); } } else ret = -EIO; i++; } else if (!(msgs[i].flags & I2C_M_RD)) { /* write bytes */ -// printk("az6007 I2C xfer write addr=0x%x len=%d: ", -// addr, msgs[i].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer write addr=0x%x len=%d: ", + addr, msgs[i].len); req = 0xbd; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; len = msgs[i].len - 1; -// printk("(0x%02x) ", msgs[i].buf[0]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { data[j] = msgs[i].buf[j + 1]; -// printk("0x%02x ", data[j]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", data[j]); } ret = az6007_usb_out_op(d,req,value,index,data,length); } else { /* read bytes */ -// printk("az6007 I2C xfer read addr=0x%x len=%d: ", -// addr, msgs[i].len); + if (dvb_usb_az6007_debug & 2) + printk(KERN_DEBUG + "az6007 I2C xfer read addr=0x%x len=%d: ", + addr, msgs[i].len); req = 0xb9; index = msgs[i].buf[0]; value = addr; @@ -509,10 +519,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; -// printk("0x%02x ", data[j + 5]); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT + "0x%02x ", data[j + 5]); } } -// printk("\n"); + if (dvb_usb_az6007_debug & 2) + printk(KERN_CONT "\n"); if (ret < 0) goto err; } -- cgit v1.2.3-70-g09d2 From 2212501ffad7fee1c2fcf9d6d55a24b489da18ad Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 09:58:38 -0300 Subject: [media] az6007: Comment the gate_ctl mutex The mutex is there to protect the I2C gate. However, for some reason, it is being called twice: [ 2103.542796] usbcore: registered new interface driver dvb_usb_az6007 [ 2103.772392] az6007: drxk_gate_ctrl: enable [ 2103.793900] az6007: drxk_gate_ctrl: enable For now, let's just comment, to allow the driver to run. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 56126d41a60..ed376b8292c 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -52,7 +52,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) struct az6007_device_state *st; int status; - info("%s", __func__); + info("%s: %s", __func__, enable? "enable" : "disable" ); if (!adap) return -EINVAL; @@ -64,10 +64,14 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (enable) { +#if 0 down(&st->pll_mutex); +#endif status = st->gate_ctrl(fe, 1); } else { +#if 0 status = st->gate_ctrl(fe, 0); +#endif up(&st->pll_mutex); } return status; -- cgit v1.2.3-70-g09d2 From 357535800d98174ceddc6ad1f3092f1dce0ea04c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:12:12 -0300 Subject: [media] az6007: Remove some dead code that doesn't seem to be needed Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 79 ++++++++------------------------------ 1 file changed, 16 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index ed376b8292c..1fc174b86a7 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -17,17 +17,8 @@ int dvb_usb_az6007_debug; module_param_named(debug,dvb_usb_az6007_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); - -static int az6007_type =0; -module_param(az6007_type, int, 0644); -MODULE_PARM_DESC(az6007_type, "select delivery mode (0=DVB-T, 1=DVB-T"); - -//module_param_named(type, 6007_type, int, 0644); -//MODULE_PARM_DESC(type, "select delivery mode (0=DVB-T, 1=DVB-C)"); - DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; @@ -110,57 +101,22 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; -#if 0 - int i=0, cyc=0, rem=0; - cyc = blen/64; - rem = blen%64; -#endif - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); - -#if 0 - if (blen>64) - { - for (i=0; iudev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index+i*64,b+i*64,64, - 5000)) != 64) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } - } - - if (rem>0) - { - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index+cyc*64,b+cyc*64,rem, - 5000)) != rem) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } - } + if (blen > 64) { + printk(KERN_ERR "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + return -EOPNOTSUPP; } - else -#endif - { - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 5000)) != blen) { - warn("usb out operation failed. (%d)",ret); - return -EIO; - } + + if ((ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,b,blen, + 5000)) != blen) { + warn("usb out operation failed. (%d)",ret); + return -EIO; } return 0; @@ -232,7 +188,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); req = 0xBC; - value = 1;//power on + value = 1; /* power on */ index = 3; blen =0; @@ -245,7 +201,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) msleep_interruptible(200); req = 0xBC; - value = 0;//power on + value = 0; /* power off */ index = 3; blen =0; @@ -258,7 +214,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) msleep_interruptible(200); req = 0xBC; - value = 1;//power on + value = 1; /* power on */ index = 3; blen =0; @@ -552,9 +508,6 @@ static u32 az6007_i2c_func(struct i2c_adapter *adapter) static struct i2c_algorithm az6007_i2c_algo = { .master_xfer = az6007_i2c_xfer, .functionality = az6007_i2c_func, -#ifdef NEED_ALGO_CONTROL - .algo_control = dummy_algo_control, -#endif }; int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, @@ -678,5 +631,5 @@ module_exit(az6007_usb_module_exit); MODULE_AUTHOR("Henry Wang "); MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); -MODULE_VERSION("1.0"); +MODULE_VERSION("1.1"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 93b32126f94333afd012daf5b48b594b86ae8128 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:40:08 -0300 Subject: [media] az6007: CodingStyle cleanup make checkpatch.pl happy Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 239 +++++++++++++++++++------------------ 1 file changed, 120 insertions(+), 119 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 1fc174b86a7..a709cec16b0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -14,23 +14,24 @@ /* debug */ int dvb_usb_az6007_debug; -module_param_named(debug,dvb_usb_az6007_debug, int, 0644); -MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +module_param_named(debug, dvb_usb_az6007_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." + DVB_USB_DEBUG_STATUS); DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - u8 power_state; + struct dvb_ca_en50221 ca; + struct mutex ca_mutex; + u8 power_state; /* Due to DRX-K - probably need changes */ - int (*gate_ctrl)(struct dvb_frontend *, int); - struct semaphore pll_mutex; + int (*gate_ctrl) (struct dvb_frontend *, int); + struct semaphore pll_mutex; bool dont_attach_fe1; }; -struct drxk_config terratec_h7_drxk = { +static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, @@ -43,7 +44,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) struct az6007_device_state *st; int status; - info("%s: %s", __func__, enable? "enable" : "disable" ); + info("%s: %s", __func__, enable ? "enable" : "disable"); if (!adap) return -EINVAL; @@ -53,7 +54,6 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!st) return -EINVAL; - if (enable) { #if 0 down(&st->pll_mutex); @@ -68,30 +68,31 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) return status; } -struct mt2063_config az6007_mt2063_config = { +static struct mt2063_config az6007_mt2063_config = { .tuner_address = 0x60, .refclock = 36125000, }; /* check for mutex FIXME */ -int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) { int ret = -1; - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_IN, - value,index,b,blen, - 5000); + ret = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev, 0), + req, + USB_TYPE_VENDOR | USB_DIR_IN, + value, index, b, blen, 5000); if (ret < 0) { warn("usb in operation failed. (%d)", ret); return -EIO; } - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); + debug_dump(b, blen, deb_xfer); return ret; } @@ -101,21 +102,23 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; - deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); - debug_dump(b,blen,deb_xfer); + deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); + debug_dump(b, blen, deb_xfer); if (blen > 64) { - printk(KERN_ERR "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + printk(KERN_ERR + "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); return -EOPNOTSUPP; } - if ((ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev,0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,b,blen, - 5000)) != blen) { - warn("usb out operation failed. (%d)",ret); + ret = usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev, 0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, b, blen, 5000); + if (ret != blen) { + warn("usb out operation failed. (%d)", ret); return -EIO; } @@ -128,25 +131,24 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -struct rc_map_table rc_map_az6007_table[] = { - { 0x0001, KEY_1 }, - { 0x0002, KEY_2 }, +static struct rc_map_table rc_map_az6007_table[] = { + {0x0001, KEY_1}, + {0x0002, KEY_2}, }; /* remote control stuff (does not work with my box) */ -static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { return 0; #if 0 u8 key[10]; int i; -/* remove the following return to enabled remote querying */ - + /* remove the following return to enabled remote querying */ - az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); + az6007_usb_in_op(d, READ_REMOTE_REQ, 0, 0, key, 10); - deb_rc("remote query key: %x %d\n",key[1],key[1]); + deb_rc("remote query key: %x %d\n", key[1], key[1]); if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; @@ -171,7 +173,7 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) } */ -static int az6007_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); return 0; @@ -190,12 +192,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 1; /* power on */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -203,12 +205,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 0; /* power off */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -216,12 +218,12 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) req = 0xBC; value = 1; /* power on */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_poweron failed!!!"); - return -EIO; + return -EIO; } info("az6007_frontend_poweron: OK"); @@ -238,37 +240,37 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); - //reset demodulator + /* reset demodulator */ req = 0xC0; - value = 1;//high + value = 1; /* high */ index = 3; - blen =0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + blen = 0; + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 1 !!!"); - return -EIO; + return -EIO; } req = 0xC0; - value = 0;//low + value = 0; /* low */ index = 3; - blen =0; + blen = 0; msleep_interruptible(200); - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 2 !!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); req = 0xC0; - value = 1;//high + value = 1; /* high */ index = 3; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - { + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) { err("az6007_frontend_reset failed 3 !!!"); - return -EIO; + return -EIO; } msleep_interruptible(200); @@ -285,18 +287,17 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) u16 value; u16 index; int blen; - //TS through + /* TS through */ req = 0xBC; value = onoff; index = 0; - blen =0; + blen = 0; ret = usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf),0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value,index,NULL,blen, - 2000); + usb_rcvctrlpipe(interface_to_usbdev(intf), 0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value, index, NULL, blen, 2000); if (ret < 0) { warn("usb in operation failed. (%d)", ret); @@ -304,27 +305,28 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) } else ret = 0; - - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); + deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, + index); return ret; } -static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) +static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff) { int ret; u8 req; u16 value; u16 index; int blen; - //TS through + /* TS through */ req = 0xC7; value = onoff; index = 0; - blen =0; + blen = 0; - if((ret = az6007_usb_out_op(adap->dev,req,value,index,NULL,blen)) != 0) - return -EIO; + ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + if (ret != 0) + return -EIO; return 0; } @@ -373,8 +375,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) /* Hack - needed due to drxk */ adap->fe2->tuner_priv = adap->fe->tuner_priv; memcpy(&adap->fe2->ops.tuner_ops, - &adap->fe->ops.tuner_ops, - sizeof(adap->fe->ops.tuner_ops)); + &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); return 0; out_free: @@ -388,14 +389,14 @@ out_free: static struct dvb_usb_device_properties az6007_properties; -static void -az6007_usb_disconnect(struct usb_interface *intf) +static void az6007_usb_disconnect(struct usb_interface *intf) { - dvb_usb_device_exit (intf); + dvb_usb_device_exit(intf); } /* I2C */ -static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int num) +static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], + int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); int i, j, len; @@ -430,7 +431,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_usb_in_op(d,req,value,index,data,length); + ret = az6007_usb_in_op(d, req, value, index, data, + length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = data[j + 5]; @@ -454,16 +456,14 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu length = msgs[i].len - 1; len = msgs[i].len - 1; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT - "(0x%02x) ", msgs[i].buf[0]); - for (j = 0; j < len; j++) - { + printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); + for (j = 0; j < len; j++) { data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT - "0x%02x ", data[j]); + printk(KERN_CONT "0x%02x ", data[j]); } - ret = az6007_usb_out_op(d,req,value,index,data,length); + ret = az6007_usb_out_op(d, req, value, index, data, + length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) @@ -475,9 +475,9 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msgs[],int nu value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_usb_in_op(d,req,value,index,data,length); - for (j = 0; j < len; j++) - { + ret = az6007_usb_in_op(d, req, value, index, data, + length); + for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT @@ -499,25 +499,26 @@ err: return num; } - static u32 az6007_i2c_func(struct i2c_adapter *adapter) { return I2C_FUNC_I2C; } static struct i2c_algorithm az6007_i2c_algo = { - .master_xfer = az6007_i2c_xfer, + .master_xfer = az6007_i2c_xfer, .functionality = az6007_i2c_func, }; -int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, - struct dvb_usb_device_description **desc, int *cold) +int az6007_identify_state(struct usb_device *udev, + struct dvb_usb_device_properties *props, + struct dvb_usb_device_description **desc, int *cold) { u8 b[16]; - s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0), - 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); + s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, + 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d",ret); + info("FW GET_VERSION length: %d", ret); *cold = ret <= 0; @@ -526,7 +527,7 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_propert } static int az6007_usb_probe(struct usb_interface *intf, - const struct usb_device_id *id) + const struct usb_device_id *id) { az6007_led_on_off(intf, 0); @@ -534,10 +535,10 @@ static int az6007_usb_probe(struct usb_interface *intf, THIS_MODULE, NULL, adapter_nr); } -static struct usb_device_id az6007_usb_table [] = { - { USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007) }, - { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7) }, - { 0 }, +static struct usb_device_id az6007_usb_table[] = { + {USB_DEVICE(USB_VID_AZUREWAVE, USB_PID_AZUREWAVE_6007)}, + {USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_H7)}, + {0}, }; MODULE_DEVICE_TABLE(usb, az6007_usb_table); @@ -545,7 +546,6 @@ MODULE_DEVICE_TABLE(usb, az6007_usb_table); static struct dvb_usb_device_properties az6007_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, - //.download_firmware = az6007_download_firmware, .firmware = "dvb-usb-az6007-03.fw", .no_reconnect = 1, @@ -553,8 +553,7 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - //.caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, - + /* .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, */ .streaming_ctrl = az6007_streaming_ctrl, .frontend_attach = az6007_frontend_attach, @@ -572,7 +571,7 @@ static struct dvb_usb_device_properties az6007_properties = { .size_of_priv = sizeof(struct az6007_device_state), } }, - //.power_ctrl = az6007_power_ctrl, + /* .power_ctrl = az6007_power_ctrl, */ .read_mac_address = az6007_read_mac_addr, .rc.legacy = { @@ -600,10 +599,10 @@ static struct dvb_usb_device_properties az6007_properties = { /* usb specific object needed to register this driver with the usb subsystem */ static struct usb_driver az6007_usb_driver = { .name = "dvb_usb_az6007", - .probe = az6007_usb_probe, + .probe = az6007_usb_probe, .disconnect = dvb_usb_device_exit, - //.disconnect = az6007_usb_disconnect, - .id_table = az6007_usb_table, + /* .disconnect = az6007_usb_disconnect, */ + .id_table = az6007_usb_table, }; /* module stuff */ @@ -611,8 +610,10 @@ static int __init az6007_usb_module_init(void) { int result; info("az6007 usb module init"); - if ((result = usb_register(&az6007_usb_driver))) { - err("usb_register failed. (%d)",result); + + result = usb_register(&az6007_usb_driver); + if (result) { + err("usb_register failed. (%d)", result); return result; } -- cgit v1.2.3-70-g09d2 From 70fa444d81b4fea992c2899467d5c4939a35100c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:55:10 -0300 Subject: [media] az6007: Get rid of az6007.h The header file serves for no purpose and exports some things that should be static. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 11 +++++++++-- drivers/media/dvb/dvb-usb/az6007.h | 18 ------------------ 2 files changed, 9 insertions(+), 20 deletions(-) delete mode 100644 drivers/media/dvb/dvb-usb/az6007.h (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index a709cec16b0..1791cb08862 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -3,13 +3,15 @@ * see Documentation/dvb/README.dvb-usb for more information */ -#include "az6007.h" #include "drxk.h" #include "mt2063.h" #include "dvb_ca_en50221.h" +#include "dvb-usb.h" + +#define DVB_USB_LOG_PREFIX "az6007" /* HACK: Should be moved to the right place */ -#define USB_PID_AZUREWAVE_6007 0xccd +#define USB_PID_AZUREWAVE_6007 0x0ccd #define USB_PID_TERRATEC_H7 0x10b4 /* debug */ @@ -18,6 +20,11 @@ module_param_named(debug, dvb_usb_az6007_debug, int, 0644); MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); +#define deb_info(args...) dprintk(dvb_usb_az6007_debug, 0x01, args) +#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug, 0x02, args) +#define deb_rc(args...) dprintk(dvb_usb_az6007_debug, 0x04, args) +#define deb_fe(args...) dprintk(dvb_usb_az6007_debug, 0x08, args) + DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { diff --git a/drivers/media/dvb/dvb-usb/az6007.h b/drivers/media/dvb/dvb-usb/az6007.h deleted file mode 100644 index aefa5b506ee..00000000000 --- a/drivers/media/dvb/dvb-usb/az6007.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _DVB_USB_AZ6007_H_ -#define _DVB_USB_AZ6007_H_ - -#define DVB_USB_LOG_PREFIX "az6007" -#include "dvb-usb.h" - - -extern int dvb_usb_az6007_debug; -#define deb_info(args...) dprintk(dvb_usb_az6007_debug,0x01,args) -#define deb_xfer(args...) dprintk(dvb_usb_az6007_debug,0x02,args) -#define deb_rc(args...) dprintk(dvb_usb_az6007_debug,0x04,args) -#define deb_fe(args...) dprintk(dvb_usb_az6007_debug,0x08,args) - - -extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); -extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); - -#endif -- cgit v1.2.3-70-g09d2 From 25c1646670fb4220c6c3ca91e1423c6aa76b3f87 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 10:59:25 -0300 Subject: [media] az6007: Replace the comments at the beginning of the driver The comments there is wrong. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 1791cb08862..f946b1b65b1 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -1,6 +1,23 @@ -/* DVB USB compliant Linux driver for the AzureWave 6017 USB2.0 DVB-S - * receiver. - * see Documentation/dvb/README.dvb-usb for more information +/* + * Driver for AzureWave 6007 DVB-C/T USB2.0 and clones + * + * Copyright (c) Henry Wang + * + * This driver was made publicly available by Terratec, at: + * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz + * The original driver's license is GPL, as declared with MODULE_LICENSE() + * + * Driver modifiyed by Mauro Carvalho Chehab in order + * to work with upstream drxk driver, and to fix some bugs. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation under version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. */ #include "drxk.h" -- cgit v1.2.3-70-g09d2 From 067fb88c9d423d67dbf432010b3bfc5336a2bbed Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 11:10:10 -0300 Subject: [media] az6007: move device PID's to the proper place Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 4 ---- drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f946b1b65b1..780a480fb70 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -27,10 +27,6 @@ #define DVB_USB_LOG_PREFIX "az6007" -/* HACK: Should be moved to the right place */ -#define USB_PID_AZUREWAVE_6007 0x0ccd -#define USB_PID_TERRATEC_H7 0x10b4 - /* debug */ int dvb_usb_az6007_debug; module_param_named(debug, dvb_usb_az6007_debug, int, 0644); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index d390ddaa5a5..b3e7be4718a 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -80,6 +80,7 @@ #define USB_PID_ANSONIC_DVBT_USB 0x6000 #define USB_PID_ANYSEE 0x861f #define USB_PID_AZUREWAVE_AD_TU700 0x3237 +#define USB_PID_AZUREWAVE_6007 0x0ccd #define USB_PID_AVERMEDIA_DVBT_USB_COLD 0x0001 #define USB_PID_AVERMEDIA_DVBT_USB_WARM 0x0002 #define USB_PID_AVERMEDIA_DVBT_USB2_COLD 0xa800 @@ -226,6 +227,7 @@ #define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 #define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 #define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab +#define USB_PID_TERRATEC_H7 0x10b4 #define USB_PID_TERRATEC_T3 0x10a0 #define USB_PID_TERRATEC_T5 0x10a1 #define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e -- cgit v1.2.3-70-g09d2 From f2ba9e5dda2afd4615dbd3c48afe64fe2ce70d4e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 23 Jul 2011 11:54:40 -0300 Subject: [media] az6007: make driver less verbose Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 780a480fb70..bb597c67cc9 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -62,9 +62,9 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) { struct dvb_usb_adapter *adap = fe->sec_priv; struct az6007_device_state *st; - int status; + int status = 0; - info("%s: %s", __func__, enable ? "enable" : "disable"); + deb_info("%s: %s\n", __func__, enable ? "enable" : "disable"); if (!adap) return -EINVAL; @@ -127,8 +127,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, debug_dump(b, blen, deb_xfer); if (blen > 64) { - printk(KERN_ERR - "az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + err("az6007: doesn't suport I2C transactions longer than 64 bytes\n"); return -EOPNOTSUPP; } @@ -138,7 +137,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); if (ret != blen) { - warn("usb out operation failed. (%d)", ret); + err("usb out operation failed. (%d)", ret); return -EIO; } @@ -207,7 +206,8 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_poweron adap=%p adap->dev=%p", adap, adap->dev); + deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", + adap, adap->dev); req = 0xBC; value = 1; /* power on */ @@ -245,7 +245,7 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) err("az6007_frontend_poweron failed!!!"); return -EIO; } - info("az6007_frontend_poweron: OK"); + deb_info("az6007_frontend_poweron: OK\n"); return 0; } @@ -258,7 +258,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) u16 index; int blen; - info("az6007_frontend_reset adap=%p adap->dev=%p", adap, adap->dev); + deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); /* reset demodulator */ req = 0xC0; @@ -295,7 +295,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) msleep_interruptible(200); - info("reset az6007 frontend"); + deb_info("reset az6007 frontend\n"); return 0; } @@ -361,8 +361,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) az6007_frontend_poweron(adap); az6007_frontend_reset(adap); - info("az6007_frontend_attach: drxk"); - + info("az6007: attaching demod drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap, &adap->fe2); if (!adap->fe) { @@ -370,7 +369,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) goto out_free; } - info("Setting hacks"); + deb_info("Setting hacks\n"); /* FIXME: do we need a pll semaphore? */ adap->fe->sec_priv = adap; @@ -379,7 +378,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; adap->fe2->id = 1; - info("az6007_frontend_attach: mt2063"); + info("az6007: attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe->ops.i2c_gate_ctrl) adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); @@ -513,7 +512,7 @@ err: mutex_unlock(&d->i2c_mutex); if (ret < 0) { - info("%s ERROR: %i\n", __func__, ret); + info("%s ERROR: %i", __func__, ret); return ret; } return num; @@ -538,11 +537,11 @@ int az6007_identify_state(struct usb_device *udev, 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, 6, USB_CTRL_GET_TIMEOUT); - info("FW GET_VERSION length: %d", ret); + deb_info("FW GET_VERSION length: %d\n", ret); *cold = ret <= 0; - info("cold: %d", *cold); + deb_info("cold: %d\n", *cold); return 0; } @@ -629,7 +628,7 @@ static struct usb_driver az6007_usb_driver = { static int __init az6007_usb_module_init(void) { int result; - info("az6007 usb module init"); + deb_info("az6007 usb module init\n"); result = usb_register(&az6007_usb_driver); if (result) { @@ -643,7 +642,7 @@ static int __init az6007_usb_module_init(void) static void __exit az6007_usb_module_exit(void) { /* deregister this driver from the USB subsystem */ - info("az6007 usb module exit"); + deb_info("az6007 usb module exit\n"); usb_deregister(&az6007_usb_driver); } -- cgit v1.2.3-70-g09d2 From da989e0bc7f2b3db3fea417c0bae3c20c6455995 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 24 Jul 2011 09:25:39 -0300 Subject: [media] drxk: Don't assume a default firmware name Move the ngene/ddbridge firmware into their drivers. There are two reasons for that: 1) The firmware used there didn't work for a few devices I tested here (Terratec H5, H6 and H7); 2) At least Terratec H7 doesn't seem to require a firmware for it to work. After this change, if firmware is not specified, the driver will use a rom-based firmware (this seems to be the case for Terratec H7, although I need to better check the USB dumps to be sure about that). In any case, the firmware seems to be optional, as the DRX-K driver don't return the firmware load error. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/ddbridge/ddbridge-core.c | 1 + drivers/media/dvb/dvb-usb/az6007.c | 8 +++++--- drivers/media/dvb/frontends/drxk_hard.c | 4 +--- drivers/media/dvb/ngene/ngene-cards.c | 1 + 4 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/ddbridge/ddbridge-core.c b/drivers/media/dvb/ddbridge/ddbridge-core.c index 2f31648bba9..243dbb37bd5 100644 --- a/drivers/media/dvb/ddbridge/ddbridge-core.c +++ b/drivers/media/dvb/ddbridge/ddbridge-core.c @@ -578,6 +578,7 @@ static int demod_attach_drxk(struct ddb_input *input) struct drxk_config config; memset(&config, 0, sizeof(config)); + config.microcode_name = "drxk_a3.mc"; config.adr = 0x29 + (input->nr & 1); fe = input->fe = dvb_attach(drxk_attach, &config, i2c); diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index bb597c67cc9..523972f9ef5 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -55,7 +55,8 @@ static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, - .microcode_name = "dvb-usb-terratec-h5-drxk.fw", + .max_size = 64, +// .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -127,7 +128,8 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, debug_dump(b, blen, deb_xfer); if (blen > 64) { - err("az6007: doesn't suport I2C transactions longer than 64 bytes\n"); + err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n", + blen); return -EOPNOTSUPP; } @@ -395,6 +397,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) adap->fe2->tuner_priv = adap->fe->tuner_priv; memcpy(&adap->fe2->ops.tuner_ops, &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); + return 0; out_free: @@ -572,7 +575,6 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - /* .caps = DVB_USB_ADAP_RECEIVES_204_BYTE_TS, */ .streaming_ctrl = az6007_streaming_ctrl, .frontend_attach = az6007_frontend_attach, diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 6980ed7b878..4b99255f7ba 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -6070,9 +6070,7 @@ static int init_drxk(struct drxk_state *state) if (status < 0) goto error; - if (!state->microcode_name) - load_microcode(state, "drxk_a3.mc"); - else + if (state->microcode_name) load_microcode(state, state->microcode_name); /* disable token-ring bus through OFDM block for possible ucode upload */ diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c index 8418c02bcef..7539a5d7102 100644 --- a/drivers/media/dvb/ngene/ngene-cards.c +++ b/drivers/media/dvb/ngene/ngene-cards.c @@ -216,6 +216,7 @@ static int demod_attach_drxk(struct ngene_channel *chan, struct drxk_config config; memset(&config, 0, sizeof(config)); + config.microcode_name = "drxk_a3.mc"; config.adr = 0x29 + (chan->number ^ 2); chan->fe = dvb_attach(drxk_attach, &config, i2c); -- cgit v1.2.3-70-g09d2 From c108a5a0ef1fc20f7ae36318dd154f40dcf1d345 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 10:38:20 -0300 Subject: [media] az6007: need to define drivers name before including dvb-usb.h Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 523972f9ef5..87dff933289 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -23,9 +23,9 @@ #include "drxk.h" #include "mt2063.h" #include "dvb_ca_en50221.h" -#include "dvb-usb.h" #define DVB_USB_LOG_PREFIX "az6007" +#include "dvb-usb.h" /* debug */ int dvb_usb_az6007_debug; -- cgit v1.2.3-70-g09d2 From 81091144ebdb7bdc6197559cd3547d8be7e4e18e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 11:07:20 -0300 Subject: [media] az6007: Fix some init sequences and use the right firmwares Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 105 +++++++++++++++---------------------- 1 file changed, 43 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 87dff933289..03e318d2d4b 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -56,7 +56,8 @@ static struct drxk_config terratec_h7_drxk = { .single_master = 1, .no_i2c_bridge = 0, .max_size = 64, -// .microcode_name = "dvb-usb-terratec-h5-drxk.fw", + .microcode_name = "dvb-usb-terratec-h7-drxk.fw", + .parallel_ts = 1, }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -200,53 +201,31 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return 0; } +#define AZ6007_POWER 0xbc +#define FX2_SCON1 0xc0 +#define AZ6007_TS_THROUGH 0xc7 + static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) { - int ret; - u8 req; - u16 value; - u16 index; - int blen; + struct dvb_usb_device *d = adap->dev; deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); - req = 0xBC; - value = 1; /* power on */ - index = 3; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } - - msleep_interruptible(200); - - req = 0xBC; - value = 0; /* power off */ - index = 3; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } - - msleep_interruptible(200); - - req = 0xBC; - value = 1; /* power on */ - index = 3; - blen = 0; + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + msleep(150); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + msleep(100); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + msleep(100); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + msleep(100); + az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + msleep (10); + az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + msleep (10); + az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_poweron failed!!!"); - return -EIO; - } deb_info("az6007_frontend_poweron: OK\n"); return 0; @@ -333,25 +312,6 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) return ret; } -static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap, int onoff) -{ - int ret; - u8 req; - u16 value; - u16 index; - int blen; - /* TS through */ - req = 0xC7; - value = onoff; - index = 0; - blen = 0; - - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); - if (ret != 0) - return -EIO; - return 0; -} - static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; @@ -409,6 +369,27 @@ out_free: return result; } +int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + if (!onoff) + return 0; + + + info("Sending poweron sequence"); + + az6007_usb_out_op(d, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + +#if 0 + // Seems to be a poweroff sequence + az6007_usb_out_op(d, 0xbc, 1, 3, NULL, 0); + az6007_usb_out_op(d, 0xbc, 1, 4, NULL, 0); + az6007_usb_out_op(d, 0xc0, 0, 3, NULL, 0); + az6007_usb_out_op(d, 0xc0, 1, 3, NULL, 0); + az6007_usb_out_op(d, 0xbc, 0, 1, NULL, 0); +#endif + return 0; +} + static struct dvb_usb_device_properties az6007_properties; static void az6007_usb_disconnect(struct usb_interface *intf) @@ -568,7 +549,7 @@ MODULE_DEVICE_TABLE(usb, az6007_usb_table); static struct dvb_usb_device_properties az6007_properties = { .caps = DVB_USB_IS_AN_I2C_ADAPTER, .usb_ctrl = CYPRESS_FX2, - .firmware = "dvb-usb-az6007-03.fw", + .firmware = "dvb-usb-terratec-h7-az6007.fw", .no_reconnect = 1, .identify_state = az6007_identify_state, @@ -592,7 +573,7 @@ static struct dvb_usb_device_properties az6007_properties = { .size_of_priv = sizeof(struct az6007_device_state), } }, - /* .power_ctrl = az6007_power_ctrl, */ + .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, .rc.legacy = { -- cgit v1.2.3-70-g09d2 From 3af2f4f15a61b55469a8512d186221eaf7652eec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 11:17:41 -0300 Subject: [media] az6007: Change the az6007 read/write routine parameter Use usb_device for those routines, as it allows using them on all places. While there, rename to better express the meaning. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 56 +++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 03e318d2d4b..f098e47102e 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -96,13 +96,13 @@ static struct mt2063_config az6007_mt2063_config = { }; /* check for mutex FIXME */ -static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, +static int az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret = -1; - ret = usb_control_msg(d->udev, - usb_rcvctrlpipe(d->udev, 0), + ret = usb_control_msg(udev, + usb_rcvctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_IN, value, index, b, blen, 5000); @@ -119,7 +119,7 @@ static int az6007_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, return ret; } -static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, +static int az6007_write(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -134,8 +134,8 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, return -EOPNOTSUPP; } - ret = usb_control_msg(d->udev, - usb_sndctrlpipe(d->udev, 0), + ret = usb_control_msg(udev, + usb_sndctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); @@ -168,7 +168,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) /* remove the following return to enabled remote querying */ - az6007_usb_in_op(d, READ_REMOTE_REQ, 0, 0, key, 10); + az6007_read(d->udev, READ_REMOTE_REQ, 0, 0, key, 10); deb_rc("remote query key: %x %d\n", key[1], key[1]); @@ -191,13 +191,13 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 v = onoff; - return az6007_usb_out_op(d,0xBC,v,3,NULL,1); + return az6007_write(d->udev,0xBC,v,3,NULL,1); } */ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { - az6007_usb_in_op(d, 0xb7, 6, 0, &mac[0], 6); + az6007_read(d->udev, 0xb7, 6, 0, &mac[0], 6); return 0; } @@ -212,19 +212,19 @@ static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", adap, adap->dev); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); msleep(150); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); msleep(100); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); msleep(100); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); msleep(100); - az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); msleep (10); - az6007_usb_out_op(d, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); msleep (10); - az6007_usb_out_op(d, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); deb_info("az6007_frontend_poweron: OK\n"); @@ -246,7 +246,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) value = 1; /* high */ index = 3; blen = 0; - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 1 !!!"); return -EIO; @@ -257,7 +257,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) index = 3; blen = 0; msleep_interruptible(200); - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 2 !!!"); return -EIO; @@ -268,7 +268,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) index = 3; blen = 0; - ret = az6007_usb_out_op(adap->dev, req, value, index, NULL, blen); + ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); if (ret != 0) { err("az6007_frontend_reset failed 3 !!!"); return -EIO; @@ -377,15 +377,15 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) info("Sending poweron sequence"); - az6007_usb_out_op(d, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence - az6007_usb_out_op(d, 0xbc, 1, 3, NULL, 0); - az6007_usb_out_op(d, 0xbc, 1, 4, NULL, 0); - az6007_usb_out_op(d, 0xc0, 0, 3, NULL, 0); - az6007_usb_out_op(d, 0xc0, 1, 3, NULL, 0); - az6007_usb_out_op(d, 0xbc, 0, 1, NULL, 0); + az6007_write(d->udev, 0xbc, 1, 3, NULL, 0); + az6007_write(d->udev, 0xbc, 1, 4, NULL, 0); + az6007_write(d->udev, 0xc0, 0, 3, NULL, 0); + az6007_write(d->udev, 0xc0, 1, 3, NULL, 0); + az6007_write(d->udev, 0xbc, 0, 1, NULL, 0); #endif return 0; } @@ -434,7 +434,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_usb_in_op(d, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, data, length); if (ret >= len) { for (j = 0; j < len; j++) { @@ -465,7 +465,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", data[j]); } - ret = az6007_usb_out_op(d, req, value, index, data, + ret = az6007_write(d->udev, req, value, index, data, length); } else { /* read bytes */ @@ -478,7 +478,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_usb_in_op(d, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = data[j + 5]; -- cgit v1.2.3-70-g09d2 From 3aecf2c5a9881024dc7742568146e2f9a10f19a6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 12:45:16 -0300 Subject: [media] az6007: Simplify the read/write logic This patch introduces no functional changes. It basically defines a macro for each different req found at the driver, and cleans the code to use them, making easier to understand the code. With regards to the IR handling code, although the original code doesn't define what's the request, it is clear, from the USB logs, that 0xc5 is for IR polling. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 185 +++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 98 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f098e47102e..8add81ade08 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -40,6 +40,17 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); +/* Known requests (Cypress FX2 firmware + az6007 "private" ones*/ + +#define FX2_OED 0xb5 +#define AZ6007_READ_DATA 0xb7 +#define AZ6007_I2C_RD 0xb9 +#define AZ6007_POWER 0xbc +#define AZ6007_I2C_WR 0xbd +#define FX2_SCON1 0xc0 +#define AZ6007_TS_THROUGH 0xc7 +#define AZ6007_READ_IR 0xc5 + struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; @@ -168,7 +179,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) /* remove the following return to enabled remote querying */ - az6007_read(d->udev, READ_REMOTE_REQ, 0, 0, key, 10); + az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); deb_rc("remote query key: %x %d\n", key[1], key[1]); @@ -187,127 +198,104 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) #endif } -/* +#if 0 int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { u8 v = onoff; - return az6007_write(d->udev,0xBC,v,3,NULL,1); + return az6007_write(d->udev, AZ6007_POWER, v , 3, NULL, 1); } -*/ +#endif static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { - az6007_read(d->udev, 0xb7, 6, 0, &mac[0], 6); - return 0; -} + int ret; + ret = az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); -#define AZ6007_POWER 0xbc -#define FX2_SCON1 0xc0 -#define AZ6007_TS_THROUGH 0xc7 + if (ret > 0) + deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", + __func__, mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + + return ret; +} static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) { - struct dvb_usb_device *d = adap->dev; + int ret; + struct usb_device *udev = adap->dev->udev; - deb_info("az6007_frontend_poweron adap=%p adap->dev=%p\n", - adap, adap->dev); + deb_info("%s: adap=%p adap->dev=%p\n", __func__, adap, adap->dev); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 2, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + if (ret < 0) + goto error; msleep(150); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 3, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 1, 4, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + goto error; msleep(100); - az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 0, 3, NULL, 0); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + goto error; msleep (10); - az6007_write(d->udev, FX2_SCON1 /* 0xc0 */, 1, 3, NULL, 0); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; msleep (10); - az6007_write(d->udev, AZ6007_POWER /* 0xbc */, 0, 0, NULL, 0); + ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - deb_info("az6007_frontend_poweron: OK\n"); +error: + if (ret < 0) + err("%s failed with error %d", __func__, ret); - return 0; + return ret; } static int az6007_frontend_reset(struct dvb_usb_adapter *adap) { + struct usb_device *udev = adap->dev->udev; int ret; - u8 req; - u16 value; - u16 index; - int blen; deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); /* reset demodulator */ - req = 0xC0; - value = 1; /* high */ - index = 3; - blen = 0; - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 1 !!!"); - return -EIO; - } + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + goto error; + msleep(200); + +error: + if (ret < 0) + err("%s failed with error %d", __func__, ret); - req = 0xC0; - value = 0; /* low */ - index = 3; - blen = 0; - msleep_interruptible(200); - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 2 !!!"); - return -EIO; - } - msleep_interruptible(200); - req = 0xC0; - value = 1; /* high */ - index = 3; - blen = 0; - - ret = az6007_write(adap->dev->udev, req, value, index, NULL, blen); - if (ret != 0) { - err("az6007_frontend_reset failed 3 !!!"); - return -EIO; - } - - msleep_interruptible(200); - - deb_info("reset az6007 frontend\n"); - - return 0; + return ret; } static int az6007_led_on_off(struct usb_interface *intf, int onoff) { - int ret = -1; - u8 req; - u16 value; - u16 index; - int blen; - /* TS through */ - req = 0xBC; - value = onoff; - index = 0; - blen = 0; - - ret = usb_control_msg(interface_to_usbdev(intf), - usb_rcvctrlpipe(interface_to_usbdev(intf), 0), - req, - USB_TYPE_VENDOR | USB_DIR_OUT, - value, index, NULL, blen, 2000); - - if (ret < 0) { - warn("usb in operation failed. (%d)", ret); - ret = -EIO; - } else - ret = 0; + struct usb_device *udev = interface_to_usbdev(intf); + int ret; - deb_xfer("in: req. %02x, val: %04x, ind: %04x, buffer: ", req, value, - index); + /* TS through */ + ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); + if (ret < 0) + err("%s failed with error %d", __func__, ret); return ret; } @@ -377,7 +365,7 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) info("Sending poweron sequence"); - az6007_write(d->udev, AZ6007_TS_THROUGH /* 0xc7 */, 0, 0, NULL, 0); + az6007_write(d->udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence @@ -429,7 +417,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer write+read addr=0x%x len=%d/%d: ", addr, msgs[i].len, msgs[i + 1].len); - req = 0xb9; + req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr | (1 << 8); length = 6 + msgs[i + 1].len; @@ -453,7 +441,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer write addr=0x%x len=%d: ", addr, msgs[i].len); - req = 0xbd; + req = AZ6007_I2C_WR; index = msgs[i].buf[0]; value = addr | (1 << 8); length = msgs[i].len - 1; @@ -473,7 +461,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], printk(KERN_DEBUG "az6007 I2C xfer read addr=0x%x len=%d: ", addr, msgs[i].len); - req = 0xb9; + req = AZ6007_I2C_RD; index = msgs[i].buf[0]; value = addr; length = msgs[i].len + 6; @@ -516,16 +504,17 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, struct dvb_usb_device_description **desc, int *cold) { - u8 b[16]; - s16 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), - 0xb7, USB_TYPE_VENDOR | USB_DIR_IN, 6, 0, b, - 6, USB_CTRL_GET_TIMEOUT); - - deb_info("FW GET_VERSION length: %d\n", ret); + int ret; + u8 mac[6]; - *cold = ret <= 0; + /* Try to read the mac address */ + ret = az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); + if (ret == 6) + *cold = 0; + else + *cold = 1; - deb_info("cold: %d\n", *cold); + deb_info("Device is on %s state\n", *cold? "warm" : "cold"); return 0; } -- cgit v1.2.3-70-g09d2 From ba02473eaaaa9e579a4bdbe9f15a5ad777764580 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 25 Jul 2011 12:49:46 -0300 Subject: [media] az6007: Simplify the code by removing an uneeded function Everything to reset the demod is already at az6007_frontend_poweron(). Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 29 ----------------------------- 1 file changed, 29 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 8add81ade08..912ba67bc39 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -259,34 +259,6 @@ error: return ret; } -static int az6007_frontend_reset(struct dvb_usb_adapter *adap) -{ - struct usb_device *udev = adap->dev->udev; - int ret; - - deb_info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); - - /* reset demodulator */ - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(200); - -error: - if (ret < 0) - err("%s failed with error %d", __func__, ret); - - return ret; -} - static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); @@ -309,7 +281,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) BUG_ON(!st); az6007_frontend_poweron(adap); - az6007_frontend_reset(adap); info("az6007: attaching demod drxk"); adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, -- cgit v1.2.3-70-g09d2 From 2d5161b7714ae75ac62cd58bf4c5c11ca6c2da59 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 29 Jul 2011 11:31:13 -0300 Subject: [media] az6007: Fix IR receive code The code still needs to be commented, as there's a mutex missing at the az6007_read() call. A mutex there is needed, in order to prevent RC (or CI) calls while other operations are in progress. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 912ba67bc39..c9743ee2ba7 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -49,7 +49,7 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define AZ6007_I2C_WR 0xbd #define FX2_SCON1 0xc0 #define AZ6007_TS_THROUGH 0xc7 -#define AZ6007_READ_IR 0xc5 +#define AZ6007_READ_IR 0xb4 struct az6007_device_state { struct dvb_ca_en50221 ca; @@ -172,30 +172,45 @@ static struct rc_map_table rc_map_az6007_table[] = { /* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { - return 0; -#if 0 + struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; u8 key[10]; int i; - /* remove the following return to enabled remote querying */ + /* + * FIXME: remove the following return to enabled remote querying + * The driver likely needs proper locking to avoid troubles between + * this call and other concurrent calls. + */ + return 0; az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); - deb_rc("remote query key: %x %d\n", key[1], key[1]); - if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; return 0; } - for (i = 0; i < ARRAY_SIZE(az6007_rc_keys); i++) - if (az6007_rc_keys[i].custom == key[1]) { + /* + * FIXME: need to make something useful with the keycodes and to + * convert it to the non-legacy mode. Yet, it is producing some + * debug info already, like: + * 88 04 eb 02 fd ff 00 82 63 82 (terratec IR) + * 88 04 eb 03 fc 00 00 82 63 82 (terratec IR) + * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) + * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity + */ + deb_rc("remote query key: %x %d\n", key[1], key[1]); + print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, key, 10); + + for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { + if (rc5_custom(&keymap[i]) == key[1]) { + *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; - *event = az6007_rc_keys[i].event; - break; + + return 0; } + } return 0; -#endif } #if 0 -- cgit v1.2.3-70-g09d2 From 9b01f3d498a9f39de1824609c08edbd137b774b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 29 Jul 2011 11:40:40 -0300 Subject: [media] az6007: improve the error messages for az6007 read/write calls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index c9743ee2ba7..c9b6f807790 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -110,16 +110,15 @@ static struct mt2063_config az6007_mt2063_config = { static int az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { - int ret = -1; + int ret; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), req, USB_TYPE_VENDOR | USB_DIR_IN, value, index, b, blen, 5000); - if (ret < 0) { - warn("usb in operation failed. (%d)", ret); + warn("usb read operation failed. (%d)", ret); return -EIO; } @@ -151,7 +150,7 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, USB_TYPE_VENDOR | USB_DIR_OUT, value, index, b, blen, 5000); if (ret != blen) { - err("usb out operation failed. (%d)", ret); + err("usb write operation failed. (%d)", ret); return -EIO; } -- cgit v1.2.3-70-g09d2 From 1c9a284fbd3d25dc1a1a1da32be1eaff021c4029 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sun, 31 Jul 2011 10:11:32 -0300 Subject: [media] az6007: Use the new MFE support at dvb-usb Use the newly dvb-usb MFE support added by changeset 9bd9e3bd2c57530dfe3057dd0aa9bdb37824925d. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 74 +++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index c9b6f807790..b667854bdbf 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -59,7 +59,7 @@ struct az6007_device_state { /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); struct semaphore pll_mutex; - bool dont_attach_fe1; + bool tuner_attached; }; static struct drxk_config terratec_h7_drxk = { @@ -290,56 +290,56 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; - int result; + /* FIXME: dvb-usb will call this function twice! */ + if (adap->fe[0]) + return 0; BUG_ON(!st); az6007_frontend_poweron(adap); - info("az6007: attaching demod drxk"); - adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, - &adap->dev->i2c_adap, &adap->fe2); - if (!adap->fe) { - result = -EINVAL; - goto out_free; - } - - deb_info("Setting hacks\n"); + info("attaching demod drxk"); + adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap, &adap->fe[1]); + if (!adap->fe[0]) + return -EINVAL; + adap->fe[0]->sec_priv = adap; /* FIXME: do we need a pll semaphore? */ - adap->fe->sec_priv = adap; sema_init(&st->pll_mutex, 1); - st->gate_ctrl = adap->fe->ops.i2c_gate_ctrl; - adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; - adap->fe2->id = 1; + st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; + adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; + adap->dont_attach_fe[1] = true; + + return 0; +} + +static int az6007_tuner_attach(struct dvb_usb_adapter *adap) +{ + struct az6007_device_state *st = adap->priv; + + if (st->tuner_attached) + return 0; + + st->tuner_attached = true; - info("az6007: attaching tuner mt2063"); + info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); - if (!dvb_attach(mt2063_attach, adap->fe, &az6007_mt2063_config, - &adap->dev->i2c_adap)) { - result = -EINVAL; + if (adap->fe[0]->ops.i2c_gate_ctrl) + adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1); + if (!dvb_attach(mt2063_attach, adap->fe[0], &az6007_mt2063_config, + &adap->dev->i2c_adap)) + return -EINVAL; - goto out_free; - } - if (adap->fe->ops.i2c_gate_ctrl) - adap->fe->ops.i2c_gate_ctrl(adap->fe, 0); + if (adap->fe[0]->ops.i2c_gate_ctrl) + adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0); /* Hack - needed due to drxk */ - adap->fe2->tuner_priv = adap->fe->tuner_priv; - memcpy(&adap->fe2->ops.tuner_ops, - &adap->fe->ops.tuner_ops, sizeof(adap->fe->ops.tuner_ops)); + adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv; + memcpy(&adap->fe[1]->ops.tuner_ops, + &adap->fe[0]->ops.tuner_ops, sizeof(adap->fe[0]->ops.tuner_ops)); return 0; - -out_free: - if (adap->fe) - dvb_frontend_detach(adap->fe); - adap->fe = NULL; - adap->fe2 = NULL; - - return result; } int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) @@ -530,7 +530,9 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { + .num_frontends = 2, .streaming_ctrl = az6007_streaming_ctrl, + .tuner_attach = az6007_tuner_attach, .frontend_attach = az6007_frontend_attach, /* parameter for the MPEG2-data transfer */ -- cgit v1.2.3-70-g09d2 From 781dacc82ac8105e19dd62e76b8d4278e680af81 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jan 2012 18:57:51 -0300 Subject: [media] az6007: Change it to use the MFE solution adopted at dvb-usb This driver were written to use a previous solution for MFE at dvb-usb. Due to the internal API changes, change the binding to work with the new way. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 42 +++++++++++++++----------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index b667854bdbf..92ded30b2cc 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -66,7 +66,7 @@ static struct drxk_config terratec_h7_drxk = { .adr = 0x29, .single_master = 1, .no_i2c_bridge = 0, - .max_size = 64, + .chunk_size = 64, .microcode_name = "dvb-usb-terratec-h7-drxk.fw", .parallel_ts = 1, }; @@ -290,26 +290,21 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->priv; - /* FIXME: dvb-usb will call this function twice! */ - if (adap->fe[0]) - return 0; - BUG_ON(!st); az6007_frontend_poweron(adap); info("attaching demod drxk"); - adap->fe[0] = dvb_attach(drxk_attach, &terratec_h7_drxk, - &adap->dev->i2c_adap, &adap->fe[1]); - if (!adap->fe[0]) + adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap); + if (!adap->fe_adap[0].fe) return -EINVAL; - adap->fe[0]->sec_priv = adap; + adap->fe_adap[0].fe->sec_priv = adap; /* FIXME: do we need a pll semaphore? */ sema_init(&st->pll_mutex, 1); - st->gate_ctrl = adap->fe[0]->ops.i2c_gate_ctrl; - adap->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; - adap->dont_attach_fe[1] = true; + st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl; + adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; return 0; } @@ -325,19 +320,15 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ - if (adap->fe[0]->ops.i2c_gate_ctrl) - adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 1); - if (!dvb_attach(mt2063_attach, adap->fe[0], &az6007_mt2063_config, + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); + if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, + &az6007_mt2063_config, &adap->dev->i2c_adap)) return -EINVAL; - if (adap->fe[0]->ops.i2c_gate_ctrl) - adap->fe[0]->ops.i2c_gate_ctrl(adap->fe[0], 0); - - /* Hack - needed due to drxk */ - adap->fe[1]->tuner_priv = adap->fe[0]->tuner_priv; - memcpy(&adap->fe[1]->ops.tuner_ops, - &adap->fe[0]->ops.tuner_ops, sizeof(adap->fe[0]->ops.tuner_ops)); + if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) + adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); return 0; } @@ -530,7 +521,8 @@ static struct dvb_usb_device_properties az6007_properties = { .num_adapters = 1, .adapter = { { - .num_frontends = 2, + .num_frontends = 1, + .fe = {{ .streaming_ctrl = az6007_streaming_ctrl, .tuner_attach = az6007_tuner_attach, .frontend_attach = az6007_frontend_attach, @@ -547,8 +539,8 @@ static struct dvb_usb_device_properties az6007_properties = { } }, .size_of_priv = sizeof(struct az6007_device_state), - } - }, + }} + } }, .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, -- cgit v1.2.3-70-g09d2 From 978c26c3672a15fd545da2e927467b5b6bd67acb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 16 Jan 2012 20:37:13 -0300 Subject: [media] az6007: Use a per device private struct Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 92ded30b2cc..342f9292c17 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -82,7 +82,7 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!adap) return -EINVAL; - st = adap->priv; + st = adap->dev->priv; if (!st) return -EINVAL; @@ -288,7 +288,7 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st = adap->dev->priv; BUG_ON(!st); @@ -311,7 +311,7 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) static int az6007_tuner_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->priv; + struct az6007_device_state *st = adap->dev->priv; if (st->tuner_attached) return 0; @@ -516,8 +516,8 @@ static struct dvb_usb_device_properties az6007_properties = { .usb_ctrl = CYPRESS_FX2, .firmware = "dvb-usb-terratec-h7-az6007.fw", .no_reconnect = 1, - - .identify_state = az6007_identify_state, + .size_of_priv = sizeof(struct az6007_device_state), + .identify_state = az6007_identify_state, .num_adapters = 1, .adapter = { { @@ -538,7 +538,6 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - .size_of_priv = sizeof(struct az6007_device_state), }} } }, .power_ctrl = az6007_power_ctrl, -- cgit v1.2.3-70-g09d2 From 67f04617377ecd4ee1547fd9ab3a97af38d572d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:30:58 -0300 Subject: [media] drxk: Allow setting it on dynamic_clock mode This is used on az6007. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk.h | 17 ++++++++++------- drivers/media/dvb/frontends/drxk_hard.c | 14 +++++++++----- 2 files changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 020981844a8..6b0fd2c5dcd 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -7,15 +7,17 @@ /** * struct drxk_config - Configure the initial parameters for DRX-K * - * adr: I2C Address of the DRX-K - * parallel_ts: true means that the device uses parallel TS, + * @adr: I2C Address of the DRX-K + * @parallel_ts: True means that the device uses parallel TS, * Serial otherwise. - * single_master: Device is on the single master mode - * no_i2c_bridge: Don't switch the I2C bridge to talk with tuner - * antenna_gpio: GPIO bit used to control the antenna - * antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 + * @dynamic_clk: True means that the clock will be dynamically + * adjusted. Static clock otherwise. + * @single_master: Device is on the single master mode + * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner + * @antenna_gpio: GPIO bit used to control the antenna + * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. - * microcode_name: Name of the firmware file with the microcode + * @microcode_name: Name of the firmware file with the microcode * * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is * UIO-3. @@ -25,6 +27,7 @@ struct drxk_config { bool single_master; bool no_i2c_bridge; bool parallel_ts; + bool dynamic_clk; bool antenna_dvbt; u16 antenna_gpio; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 4b99255f7ba..65703968d8a 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -650,9 +650,6 @@ static int init_state(struct drxk_state *state) u32 ulQual83 = DEFAULT_MER_83; u32 ulQual93 = DEFAULT_MER_93; - u32 ulDVBTStaticTSClock = 1; - u32 ulDVBCStaticTSClock = 1; - u32 ulMpegLockTimeOut = DEFAULT_DRXK_MPEG_LOCK_TIMEOUT; u32 ulDemodLockTimeOut = DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT; @@ -815,8 +812,7 @@ static int init_state(struct drxk_state *state) state->m_invertSTR = false; /* If TRUE; invert STR signals */ state->m_invertVAL = false; /* If TRUE; invert VAL signals */ state->m_invertCLK = (ulInvertTSClock != 0); /* If TRUE; invert CLK signals */ - state->m_DVBTStaticCLK = (ulDVBTStaticTSClock != 0); - state->m_DVBCStaticCLK = (ulDVBCStaticTSClock != 0); + /* If TRUE; static MPEG clockrate will be used; otherwise clockrate will adapt to the bitrate of the TS */ @@ -6390,6 +6386,14 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->antenna_dvbt = config->antenna_dvbt; state->m_ChunkSize = config->chunk_size; + if (config->dynamic_clk) { + state->m_DVBTStaticCLK = 0; + state->m_DVBCStaticCLK = 0; + } else { + state->m_DVBTStaticCLK = 1; + state->m_DVBCStaticCLK = 1; + } + if (config->parallel_ts) state->m_enableParallel = true; else -- cgit v1.2.3-70-g09d2 From 6e5caf8493fabbb1c6aec1cb98adb9667182a1c6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:36:26 -0300 Subject: [media] az6007: Use DRX-K dynamic clock mode Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 342f9292c17..00a0bf1c795 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -64,11 +64,12 @@ struct az6007_device_state { static struct drxk_config terratec_h7_drxk = { .adr = 0x29, - .single_master = 1, - .no_i2c_bridge = 0, + .parallel_ts = true, + .dynamic_clk = true, + .single_master = true, + .no_i2c_bridge = false, .chunk_size = 64, - .microcode_name = "dvb-usb-terratec-h7-drxk.fw", - .parallel_ts = 1, + .microcode_name = "dvb-usb-terratec-h7-az6007.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) -- cgit v1.2.3-70-g09d2 From 6fb65a66a227013ba1825efcf47e3c5df1a39131 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 19:13:07 -0300 Subject: [media] drxk: add support for Mpeg output clock drive strength config Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 3 +-- drivers/media/dvb/frontends/drxk.h | 4 +++- drivers/media/dvb/frontends/drxk_hard.c | 12 ++++++------ 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 00a0bf1c795..bf8d20151b0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -69,6 +69,7 @@ static struct drxk_config terratec_h7_drxk = { .single_master = true, .no_i2c_bridge = false, .chunk_size = 64, + .mpeg_out_clk_strength = 0x02, .microcode_name = "dvb-usb-terratec-h7-az6007.fw", }; @@ -278,12 +279,10 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); int ret; - /* TS through */ ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); if (ret < 0) err("%s failed with error %d", __func__, ret); - return ret; } diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index 6b0fd2c5dcd..ca921c77f71 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -17,6 +17,7 @@ * @antenna_gpio: GPIO bit used to control the antenna * @antenna_dvbt: GPIO bit for changing antenna to DVB-C. A value of 1 * means that 1=DVBC, 0 = DVBT. Zero means the opposite. + * @mpeg_out_clk_strength: DRXK Mpeg output clock drive strength. * @microcode_name: Name of the firmware file with the microcode * * On the *_gpio vars, bit 0 is UIO-1, bit 1 is UIO-2 and bit 2 is @@ -32,7 +33,8 @@ struct drxk_config { bool antenna_dvbt; u16 antenna_gpio; - int chunk_size; + u8 mpeg_out_clk_strength; + int chunk_size; const char *microcode_name; }; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 65703968d8a..d25b0d20038 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -91,10 +91,6 @@ bool IsA1WithRomCode(struct drxk_state *state) #define DRXK_MPEG_PARALLEL_OUTPUT_PIN_DRIVE_STRENGTH (0x03) #endif -#ifndef DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH -#define DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH (0x06) -#endif - #define DEFAULT_DRXK_MPEG_LOCK_TIMEOUT 700 #define DEFAULT_DRXK_DEMOD_LOCK_TIMEOUT 500 @@ -659,7 +655,6 @@ static int init_state(struct drxk_state *state) u32 ulGPIOCfg = 0x0113; u32 ulInvertTSClock = 0; u32 ulTSDataStrength = DRXK_MPEG_SERIAL_OUTPUT_PIN_DRIVE_STRENGTH; - u32 ulTSClockkStrength = DRXK_MPEG_OUTPUT_CLK_DRIVE_STRENGTH; u32 ulDVBTBitrate = 50000000; u32 ulDVBCBitrate = DRXK_QAM_SYMBOLRATE_MAX * 8; @@ -820,7 +815,6 @@ static int init_state(struct drxk_state *state) state->m_DVBCBitrate = ulDVBCBitrate; state->m_TSDataStrength = (ulTSDataStrength & 0x07); - state->m_TSClockkStrength = (ulTSClockkStrength & 0x07); /* Maximum bitrate in b/s in case static clockrate is selected */ state->m_mpegTsStaticBitrate = 19392658; @@ -6394,6 +6388,12 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->m_DVBCStaticCLK = 1; } + + if (config->mpeg_out_clk_strength) + state->m_TSClockkStrength = config->mpeg_out_clk_strength & 0x07; + else + state->m_TSClockkStrength = 0x06; + if (config->parallel_ts) state->m_enableParallel = true; else -- cgit v1.2.3-70-g09d2 From d585681374ed23a707b572a1199d510e518d7522 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 07:57:06 -0300 Subject: [media] drxk: Allow enabling MERR/MVAL cfg Those two settings are different when used with az6007. Add a config option to enable it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 1 + drivers/media/dvb/frontends/drxk.h | 2 ++ drivers/media/dvb/frontends/drxk_hard.c | 11 +++++++++-- drivers/media/dvb/frontends/drxk_hard.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index bf8d20151b0..81fdc90be44 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -67,6 +67,7 @@ static struct drxk_config terratec_h7_drxk = { .parallel_ts = true, .dynamic_clk = true, .single_master = true, + .enable_merr_cfg = true, .no_i2c_bridge = false, .chunk_size = 64, .mpeg_out_clk_strength = 0x02, diff --git a/drivers/media/dvb/frontends/drxk.h b/drivers/media/dvb/frontends/drxk.h index ca921c77f71..9d64e4fea06 100644 --- a/drivers/media/dvb/frontends/drxk.h +++ b/drivers/media/dvb/frontends/drxk.h @@ -12,6 +12,7 @@ * Serial otherwise. * @dynamic_clk: True means that the clock will be dynamically * adjusted. Static clock otherwise. + * @enable_merr_cfg: Enable SIO_PDR_PERR_CFG/SIO_PDR_MVAL_CFG. * @single_master: Device is on the single master mode * @no_i2c_bridge: Don't switch the I2C bridge to talk with tuner * @antenna_gpio: GPIO bit used to control the antenna @@ -29,6 +30,7 @@ struct drxk_config { bool no_i2c_bridge; bool parallel_ts; bool dynamic_clk; + bool enable_merr_cfg; bool antenna_dvbt; u16 antenna_gpio; diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index d25b0d20038..5fa192731fc 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -1179,6 +1179,7 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) int status = -1; u16 sioPdrMclkCfg = 0; u16 sioPdrMdxCfg = 0; + u16 err_cfg = 0; dprintk(1, ": mpeg %s, %s mode\n", mpegEnable ? "enable" : "disable", @@ -1244,12 +1245,17 @@ static int MPEGTSConfigurePins(struct drxk_state *state, bool mpegEnable) status = write16(state, SIO_PDR_MSTRT_CFG__A, sioPdrMdxCfg); if (status < 0) goto error; - status = write16(state, SIO_PDR_MERR_CFG__A, 0x0000); /* Disable */ + + if (state->enable_merr_cfg) + err_cfg = sioPdrMdxCfg; + + status = write16(state, SIO_PDR_MERR_CFG__A, err_cfg); if (status < 0) goto error; - status = write16(state, SIO_PDR_MVAL_CFG__A, 0x0000); /* Disable */ + status = write16(state, SIO_PDR_MVAL_CFG__A, err_cfg); if (status < 0) goto error; + if (state->m_enableParallel == true) { /* paralel -> enable MD1 to MD7 */ status = write16(state, SIO_PDR_MD1_CFG__A, sioPdrMdxCfg); @@ -6379,6 +6385,7 @@ struct dvb_frontend *drxk_attach(const struct drxk_config *config, state->antenna_gpio = config->antenna_gpio; state->antenna_dvbt = config->antenna_dvbt; state->m_ChunkSize = config->chunk_size; + state->enable_merr_cfg = config->enable_merr_cfg; if (config->dynamic_clk) { state->m_DVBTStaticCLK = 0; diff --git a/drivers/media/dvb/frontends/drxk_hard.h b/drivers/media/dvb/frontends/drxk_hard.h index 3a58b73eb9b..4bbf841de83 100644 --- a/drivers/media/dvb/frontends/drxk_hard.h +++ b/drivers/media/dvb/frontends/drxk_hard.h @@ -332,6 +332,7 @@ struct drxk_state { u16 UIO_mask; /* Bits used by UIO */ + bool enable_merr_cfg; bool single_master; bool no_i2c_bridge; bool antenna_dvbt; -- cgit v1.2.3-70-g09d2 From b19280cf2bee7df489f9488bda45220f8518e39f Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 20 Jan 2012 18:37:01 -0300 Subject: [media] az6007: code cleanups and fixes Several changes were needed to make az6007 to work, producing the same commands as the original driver. This patch does that. While here, be less verbose when debug is not enabled. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 148 +++++++++++++++++++++---------------- 1 file changed, 83 insertions(+), 65 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 81fdc90be44..f0e4c013bb5 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -54,12 +54,16 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; - u8 power_state; + unsigned warm : 1; /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); struct semaphore pll_mutex; bool tuner_attached; + + unsigned char data[4096]; + + struct usb_data_stream *stream; }; static struct drxk_config terratec_h7_drxk = { @@ -71,7 +75,7 @@ static struct drxk_config terratec_h7_drxk = { .no_i2c_bridge = false, .chunk_size = 64, .mpeg_out_clk_strength = 0x02, - .microcode_name = "dvb-usb-terratec-h7-az6007.fw", + .microcode_name = "dvb-usb-terratec-h7-drxk.fw", }; static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) @@ -162,7 +166,9 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { - return 0; + deb_info("%s: %s", __func__, onoff ? "enable" : "disable"); + + return az6007_write(adap->dev->udev, 0xbc, onoff, 0, NULL, 0); } /* keys for the enclosed remote control */ @@ -236,46 +242,6 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return ret; } -static int az6007_frontend_poweron(struct dvb_usb_adapter *adap) -{ - int ret; - struct usb_device *udev = adap->dev->udev; - - deb_info("%s: adap=%p adap->dev=%p\n", __func__, adap, adap->dev); - - ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); - if (ret < 0) - goto error; - msleep(150); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); - if (ret < 0) - goto error; - msleep(100); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); - if (ret < 0) - goto error; - msleep (10); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); - if (ret < 0) - goto error; - msleep (10); - ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - -error: - if (ret < 0) - err("%s failed with error %d", __func__, ret); - - return ret; -} - static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); @@ -293,9 +259,8 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) BUG_ON(!st); - az6007_frontend_poweron(adap); + deb_info("attaching demod drxk"); - info("attaching demod drxk"); adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, &adap->dev->i2c_adap); if (!adap->fe_adap[0].fe) @@ -319,11 +284,11 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) st->tuner_attached = true; - info("attaching tuner mt2063"); + deb_info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); - if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, + if (!dvb_attach(mt2063_attach, adap->fe_adap[0].fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) return -EINVAL; @@ -336,22 +301,69 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { - if (!onoff) - return 0; + struct az6007_device_state *st = d->priv; + struct usb_device *udev = d->udev; + int ret; + + deb_info("%s()\n", __func__); + + if (!st->warm) { + u8 data[6]; + + az6007_read(udev, FX2_OED, 1, 0, data, 1); /* {0x01} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 8160, data, 1); /* {0x20} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 0, data, 5); /* {0x00, 0x00, 0x00, 0x00, 0x0a} */ + az6007_read(udev, AZ6007_READ_DATA, 0, 4080, data, 6); /* {0x00, 0x08, 0x00, 0x0c, 0x22, 0x38} */ + + ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + if (ret < 0) + return ret; + msleep(60); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + return ret; + msleep(100); + ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + if (ret < 0) + return ret; + msleep(20); + ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + if (ret < 0) + return ret; + + msleep(400); + ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + if (ret < 0) + return ret; + msleep (150); + ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + if (ret < 0) + return ret; + msleep (430); + ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + if (ret < 0) + return ret; + st->warm = true; - info("Sending poweron sequence"); + return 0; + } - az6007_write(d->udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); + if (!onoff) + return 0; + + az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); #if 0 // Seems to be a poweroff sequence - az6007_write(d->udev, 0xbc, 1, 3, NULL, 0); - az6007_write(d->udev, 0xbc, 1, 4, NULL, 0); - az6007_write(d->udev, 0xc0, 0, 3, NULL, 0); - az6007_write(d->udev, 0xc0, 1, 3, NULL, 0); - az6007_write(d->udev, 0xbc, 0, 1, NULL, 0); + az6007_write(udev, 0xbc, 1, 3, NULL, 0); + az6007_write(udev, 0xbc, 1, 4, NULL, 0); + az6007_write(udev, 0xc0, 0, 3, NULL, 0); + az6007_write(udev, 0xc0, 1, 3, NULL, 0); + az6007_write(udev, 0xbc, 0, 1, NULL, 0); #endif + return 0; } @@ -367,13 +379,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); + struct az6007_device_state *st = d->priv; int i, j, len; int ret = 0; u16 index; u16 value; int length; u8 req, addr; - u8 data[512]; if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; @@ -399,11 +411,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_read(d->udev, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { - msgs[i + 1].buf[j] = data[j + 5]; + msgs[i + 1].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", @@ -426,11 +438,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "(0x%02x) ", msgs[i].buf[0]); for (j = 0; j < len; j++) { - data[j] = msgs[i].buf[j + 1]; + st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT "0x%02x ", data[j]); + printk(KERN_CONT "0x%02x ", st->data[j]); } - ret = az6007_write(d->udev, req, value, index, data, + ret = az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ @@ -443,13 +455,13 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_read(d->udev, req, value, index, data, + ret = az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { - msgs[i].buf[j] = data[j + 5]; + msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) printk(KERN_CONT - "0x%02x ", data[j + 5]); + "0x%02x ", st->data[j + 5]); } } if (dvb_usb_az6007_debug & 2) @@ -491,6 +503,12 @@ int az6007_identify_state(struct usb_device *udev, else *cold = 1; + if (*cold) { + az6007_write(udev, 0x09, 1, 0, NULL, 0); + az6007_write(udev, 0x00, 0, 0, NULL, 0); + az6007_write(udev, 0x00, 0, 0, NULL, 0); + } + deb_info("Device is on %s state\n", *cold? "warm" : "cold"); return 0; } -- cgit v1.2.3-70-g09d2 From 04e3ece7153054e2694a882f6ffa54941574049c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 10:35:12 -0300 Subject: [media] az6007: Driver cleanup Remove commented test code, remove unused poweroff stuff, and fix the copyright data. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 56 +++++++++----------------------------- 1 file changed, 13 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index f0e4c013bb5..534d3267c86 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -7,8 +7,9 @@ * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz * The original driver's license is GPL, as declared with MODULE_LICENSE() * - * Driver modifiyed by Mauro Carvalho Chehab in order - * to work with upstream drxk driver, and to fix some bugs. + * Copyright (c) 2010-2011 Mauro Carvalho Chehab + * Driver modified by in order to work with upstream drxk driver, and + * tons of bugs got fixed. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -58,7 +59,6 @@ struct az6007_device_state { /* Due to DRX-K - probably need changes */ int (*gate_ctrl) (struct dvb_frontend *, int); - struct semaphore pll_mutex; bool tuner_attached; unsigned char data[4096]; @@ -94,17 +94,11 @@ static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) if (!st) return -EINVAL; - if (enable) { -#if 0 - down(&st->pll_mutex); -#endif + if (enable) status = st->gate_ctrl(fe, 1); - } else { -#if 0 + else status = st->gate_ctrl(fe, 0); -#endif - up(&st->pll_mutex); - } + return status; } @@ -221,14 +215,6 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) return 0; } -#if 0 -int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) -{ - u8 v = onoff; - return az6007_write(d->udev, AZ6007_POWER, v , 3, NULL, 1); -} -#endif - static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { int ret; @@ -246,6 +232,7 @@ static int az6007_led_on_off(struct usb_interface *intf, int onoff) { struct usb_device *udev = interface_to_usbdev(intf); int ret; + /* TS through */ ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); if (ret < 0) @@ -257,8 +244,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->dev->priv; - BUG_ON(!st); - deb_info("attaching demod drxk"); adap->fe_adap[0].fe = dvb_attach(drxk_attach, &terratec_h7_drxk, @@ -267,8 +252,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) return -EINVAL; adap->fe_adap[0].fe->sec_priv = adap; - /* FIXME: do we need a pll semaphore? */ - sema_init(&st->pll_mutex, 1); st->gate_ctrl = adap->fe_adap[0].fe->ops.i2c_gate_ctrl; adap->fe_adap[0].fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; @@ -282,9 +265,8 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (st->tuner_attached) return 0; - st->tuner_attached = true; - deb_info("attaching tuner mt2063"); + /* Attach mt2063 to DVB-C frontend */ if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 1); @@ -296,6 +278,8 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); + st->tuner_attached = true; + return 0; } @@ -355,25 +339,9 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); -#if 0 - // Seems to be a poweroff sequence - az6007_write(udev, 0xbc, 1, 3, NULL, 0); - az6007_write(udev, 0xbc, 1, 4, NULL, 0); - az6007_write(udev, 0xc0, 0, 3, NULL, 0); - az6007_write(udev, 0xc0, 1, 3, NULL, 0); - az6007_write(udev, 0xbc, 0, 1, NULL, 0); -#endif - return 0; } -static struct dvb_usb_device_properties az6007_properties; - -static void az6007_usb_disconnect(struct usb_interface *intf) -{ - dvb_usb_device_exit(intf); -} - /* I2C */ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num) @@ -513,6 +481,8 @@ int az6007_identify_state(struct usb_device *udev, return 0; } +static struct dvb_usb_device_properties az6007_properties; + static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -589,7 +559,6 @@ static struct usb_driver az6007_usb_driver = { .name = "dvb_usb_az6007", .probe = az6007_usb_probe, .disconnect = dvb_usb_device_exit, - /* .disconnect = az6007_usb_disconnect, */ .id_table = az6007_usb_table, }; @@ -619,6 +588,7 @@ module_init(az6007_usb_module_init); module_exit(az6007_usb_module_exit); MODULE_AUTHOR("Henry Wang "); +MODULE_AUTHOR("Mauro Carvalho Chehab "); MODULE_DESCRIPTION("Driver for AzureWave 6007 DVB-C/T USB2.0 and clones"); MODULE_VERSION("1.1"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From a2c35d346d9e9555db930f9035d0e628bf7f3393 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 11:19:16 -0300 Subject: [media] az6007: Protect read/write calls with a mutex This will avoid interference with CI and IR I/O operations. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 122 +++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 534d3267c86..6177332a7a0 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -53,17 +53,11 @@ DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); #define AZ6007_READ_IR 0xb4 struct az6007_device_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - unsigned warm : 1; - - /* Due to DRX-K - probably need changes */ + struct mutex mutex; + struct dvb_ca_en50221 ca; + unsigned warm:1; int (*gate_ctrl) (struct dvb_frontend *, int); - bool tuner_attached; - unsigned char data[4096]; - - struct usb_data_stream *stream; }; static struct drxk_config terratec_h7_drxk = { @@ -107,8 +101,7 @@ static struct mt2063_config az6007_mt2063_config = { .refclock = 36125000, }; -/* check for mutex FIXME */ -static int az6007_read(struct usb_device *udev, u8 req, u16 value, +static int __az6007_read(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -130,7 +123,23 @@ static int az6007_read(struct usb_device *udev, u8 req, u16 value, return ret; } -static int az6007_write(struct usb_device *udev, u8 req, u16 value, +static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + struct az6007_device_state *st = d->priv; + int ret; + + if (mutex_lock_interruptible(&st->mutex) < 0) + return -EAGAIN; + + ret = __az6007_read(d->udev, req, value, index, b, blen); + + mutex_unlock(&st->mutex); + + return ret; +} + +static int __az6007_write(struct usb_device *udev, u8 req, u16 value, u16 index, u8 *b, int blen) { int ret; @@ -158,11 +167,29 @@ static int az6007_write(struct usb_device *udev, u8 req, u16 value, return 0; } +static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value, + u16 index, u8 *b, int blen) +{ + struct az6007_device_state *st = d->priv; + int ret; + + if (mutex_lock_interruptible(&st->mutex) < 0) + return -EAGAIN; + + ret = __az6007_write(d->udev, req, value, index, b, blen); + + mutex_unlock(&st->mutex); + + return ret; +} + static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) { + struct dvb_usb_device *d = adap->dev; + deb_info("%s: %s", __func__, onoff ? "enable" : "disable"); - return az6007_write(adap->dev->udev, 0xbc, onoff, 0, NULL, 0); + return az6007_write(d, 0xbc, onoff, 0, NULL, 0); } /* keys for the enclosed remote control */ @@ -185,7 +212,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) */ return 0; - az6007_read(d->udev, AZ6007_READ_IR, 0, 0, key, 10); + az6007_read(d, AZ6007_READ_IR, 0, 0, key, 10); if (key[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; @@ -218,7 +245,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { int ret; - ret = az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6); + ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret > 0) deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -228,18 +255,6 @@ static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) return ret; } -static int az6007_led_on_off(struct usb_interface *intf, int onoff) -{ - struct usb_device *udev = interface_to_usbdev(intf); - int ret; - - /* TS through */ - ret = az6007_write(udev, AZ6007_POWER, onoff, 0, NULL, 0); - if (ret < 0) - err("%s failed with error %d", __func__, ret); - return ret; -} - static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { struct az6007_device_state *st = adap->dev->priv; @@ -260,11 +275,6 @@ static int az6007_frontend_attach(struct dvb_usb_adapter *adap) static int az6007_tuner_attach(struct dvb_usb_adapter *adap) { - struct az6007_device_state *st = adap->dev->priv; - - if (st->tuner_attached) - return 0; - deb_info("attaching tuner mt2063"); /* Attach mt2063 to DVB-C frontend */ @@ -278,53 +288,45 @@ static int az6007_tuner_attach(struct dvb_usb_adapter *adap) if (adap->fe_adap[0].fe->ops.i2c_gate_ctrl) adap->fe_adap[0].fe->ops.i2c_gate_ctrl(adap->fe_adap[0].fe, 0); - st->tuner_attached = true; - return 0; } int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) { struct az6007_device_state *st = d->priv; - struct usb_device *udev = d->udev; int ret; deb_info("%s()\n", __func__); if (!st->warm) { - u8 data[6]; + mutex_init(&st->mutex); - az6007_read(udev, FX2_OED, 1, 0, data, 1); /* {0x01} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 8160, data, 1); /* {0x20} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 0, data, 5); /* {0x00, 0x00, 0x00, 0x00, 0x0a} */ - az6007_read(udev, AZ6007_READ_DATA, 0, 4080, data, 6); /* {0x00, 0x08, 0x00, 0x0c, 0x22, 0x38} */ - - ret = az6007_write(udev, AZ6007_POWER, 0, 2, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 0, 2, NULL, 0); if (ret < 0) return ret; msleep(60); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); if (ret < 0) return ret; msleep(100); - ret = az6007_write(udev, AZ6007_POWER, 1, 3, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 3, NULL, 0); if (ret < 0) return ret; msleep(20); - ret = az6007_write(udev, AZ6007_POWER, 1, 4, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 1, 4, NULL, 0); if (ret < 0) return ret; msleep(400); - ret = az6007_write(udev, FX2_SCON1, 0, 3, NULL, 0); + ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); if (ret < 0) return ret; msleep (150); - ret = az6007_write(udev, FX2_SCON1, 1, 3, NULL, 0); + ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); if (ret < 0) return ret; msleep (430); - ret = az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); + ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); if (ret < 0) return ret; @@ -336,8 +338,8 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) if (!onoff) return 0; - az6007_write(udev, AZ6007_POWER, 0, 0, NULL, 0); - az6007_write(udev, AZ6007_TS_THROUGH, 0, 0, NULL, 0); + az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); + az6007_write(d, AZ6007_TS_THROUGH, 0, 0, NULL, 0); return 0; } @@ -355,7 +357,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int length; u8 req, addr; - if (mutex_lock_interruptible(&d->i2c_mutex) < 0) + if (mutex_lock_interruptible(&st->mutex) < 0) return -EAGAIN; for (i = 0; i < num; i++) { @@ -379,7 +381,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = az6007_read(d->udev, req, value, index, st->data, + ret = __az6007_read(d->udev, req, value, index, st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { @@ -410,7 +412,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], if (dvb_usb_az6007_debug & 2) printk(KERN_CONT "0x%02x ", st->data[j]); } - ret = az6007_write(d->udev, req, value, index, st->data, + ret = __az6007_write(d->udev, req, value, index, st->data, length); } else { /* read bytes */ @@ -423,7 +425,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = az6007_read(d->udev, req, value, index, st->data, + ret = __az6007_read(d->udev, req, value, index, st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; @@ -438,7 +440,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], goto err; } err: - mutex_unlock(&d->i2c_mutex); + mutex_unlock(&st->mutex); if (ret < 0) { info("%s ERROR: %i", __func__, ret); @@ -465,16 +467,16 @@ int az6007_identify_state(struct usb_device *udev, u8 mac[6]; /* Try to read the mac address */ - ret = az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); + ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); if (ret == 6) *cold = 0; else *cold = 1; if (*cold) { - az6007_write(udev, 0x09, 1, 0, NULL, 0); - az6007_write(udev, 0x00, 0, 0, NULL, 0); - az6007_write(udev, 0x00, 0, 0, NULL, 0); + __az6007_write(udev, 0x09, 1, 0, NULL, 0); + __az6007_write(udev, 0x00, 0, 0, NULL, 0); + __az6007_write(udev, 0x00, 0, 0, NULL, 0); } deb_info("Device is on %s state\n", *cold? "warm" : "cold"); @@ -486,7 +488,7 @@ static struct dvb_usb_device_properties az6007_properties; static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - az6007_led_on_off(intf, 0); + struct usb_device *udev = interface_to_usbdev(intf); return dvb_usb_device_init(intf, &az6007_properties, THIS_MODULE, NULL, adapter_nr); -- cgit v1.2.3-70-g09d2 From 711e1398d3131fd83aee0a35d450c6e1a809bfb2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 11:53:18 -0300 Subject: [media] az6007: Be sure to use kmalloc'ed buffer for transfers USB data transfers may not work if the buffer is allocated at the stack. Be sure to use kmalloc on all places where a buffer is needed. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 6177332a7a0..142ef7b0c02 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -201,8 +201,8 @@ static struct rc_map_table rc_map_az6007_table[] = { /* remote control stuff (does not work with my box) */ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) { + struct az6007_device_state *st = d->priv; struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; - u8 key[10]; int i; /* @@ -212,9 +212,9 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) */ return 0; - az6007_read(d, AZ6007_READ_IR, 0, 0, key, 10); + az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); - if (key[1] == 0x44) { + if (st->data[1] == 0x44) { *state = REMOTE_NO_KEY_PRESSED; return 0; } @@ -228,11 +228,11 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity */ - deb_rc("remote query key: %x %d\n", key[1], key[1]); - print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, key, 10); + deb_rc("remote query key: %x %d\n", st->data[1], st->data[1]); + print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == key[1]) { + if (rc5_custom(&keymap[i]) == st->data[1]) { *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; @@ -244,8 +244,11 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) static int az6007_read_mac_addr(struct dvb_usb_device *d, u8 mac[6]) { + struct az6007_device_state *st = d->priv; int ret; - ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, mac, 6); + + ret = az6007_read(d, AZ6007_READ_DATA, 6, 0, st->data, 6); + memcpy(mac, st->data, sizeof(mac)); if (ret > 0) deb_info("%s: mac is %02x:%02x:%02x:%02x:%02x:%02x\n", @@ -464,7 +467,11 @@ int az6007_identify_state(struct usb_device *udev, struct dvb_usb_device_description **desc, int *cold) { int ret; - u8 mac[6]; + u8 *mac; + + mac = kmalloc(6, GFP_ATOMIC); + if (!mac) + return -ENOMEM; /* Try to read the mac address */ ret = __az6007_read(udev, AZ6007_READ_DATA, 6, 0, mac, 6); @@ -473,6 +480,8 @@ int az6007_identify_state(struct usb_device *udev, else *cold = 1; + kfree(mac); + if (*cold) { __az6007_write(udev, 0x09, 1, 0, NULL, 0); __az6007_write(udev, 0x00, 0, 0, NULL, 0); @@ -488,8 +497,6 @@ static struct dvb_usb_device_properties az6007_properties; static int az6007_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev(intf); - return dvb_usb_device_init(intf, &az6007_properties, THIS_MODULE, NULL, adapter_nr); } -- cgit v1.2.3-70-g09d2 From 9165144033944a4c650a9914888bf6b6f7328c7a Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:14:13 -0300 Subject: [media] az6007: Fix IR handling Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 142ef7b0c02..a8aedb87ae6 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -204,13 +204,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) struct az6007_device_state *st = d->priv; struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; int i; - - /* - * FIXME: remove the following return to enabled remote querying - * The driver likely needs proper locking to avoid troubles between - * this call and other concurrent calls. - */ - return 0; + unsigned code = 0; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); @@ -219,20 +213,21 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) return 0; } - /* - * FIXME: need to make something useful with the keycodes and to - * convert it to the non-legacy mode. Yet, it is producing some - * debug info already, like: - * 88 04 eb 02 fd ff 00 82 63 82 (terratec IR) - * 88 04 eb 03 fc 00 00 82 63 82 (terratec IR) - * 88 80 7e 0d f2 ff 00 82 63 82 (another NEC-extended based IR) - * I suspect that the IR data is at bytes 1 to 4, and byte 5 is parity - */ - deb_rc("remote query key: %x %d\n", st->data[1], st->data[1]); + if ((st->data[1] ^ st->data[2]) == 0xff) + code = st->data[1]; + else + code = st->data[1] << 8 | st->data[2]; + + if ((st->data[3] ^ st->data[4]) == 0xff) + code = code << 8 | st->data[3]; + else + code = code << 16 | st->data[3] << 8| st->data[4]; + + printk("remote query key: %04x\n", code); print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == st->data[1]) { + if (rc5_custom(&keymap[i]) == code) { *event = keymap[i].keycode; *state = REMOTE_KEY_PRESSED; -- cgit v1.2.3-70-g09d2 From d3d076aaa7d8a028ae4617f57c14727b473f848d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:20:30 -0300 Subject: [media] az6007: Convert IR to use the rc_core logic Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index a8aedb87ae6..2288916a2a4 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -192,26 +192,16 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) return az6007_write(d, 0xbc, onoff, 0, NULL, 0); } -/* keys for the enclosed remote control */ -static struct rc_map_table rc_map_az6007_table[] = { - {0x0001, KEY_1}, - {0x0002, KEY_2}, -}; - /* remote control stuff (does not work with my box) */ -static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) +static int az6007_rc_query(struct dvb_usb_device *d) { struct az6007_device_state *st = d->priv; - struct rc_map_table *keymap = d->props.rc.legacy.rc_map_table; - int i; unsigned code = 0; az6007_read(d, AZ6007_READ_IR, 0, 0, st->data, 10); - if (st->data[1] == 0x44) { - *state = REMOTE_NO_KEY_PRESSED; + if (st->data[1] == 0x44) return 0; - } if ((st->data[1] ^ st->data[2]) == 0xff) code = st->data[1]; @@ -224,16 +214,9 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 * event, int *state) code = code << 16 | st->data[3] << 8| st->data[4]; printk("remote query key: %04x\n", code); - print_hex_dump_bytes("Remote: ", DUMP_PREFIX_NONE, st->data, 10); - for (i = 0; i < d->props.rc.legacy.rc_map_size; i++) { - if (rc5_custom(&keymap[i]) == code) { - *event = keymap[i].keycode; - *state = REMOTE_KEY_PRESSED; + rc_keydown(d->rc_dev, code, st->data[5]); - return 0; - } - } return 0; } @@ -536,11 +519,12 @@ static struct dvb_usb_device_properties az6007_properties = { .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, - .rc.legacy = { - .rc_map_table = rc_map_az6007_table, - .rc_map_size = ARRAY_SIZE(rc_map_az6007_table), + .rc.core = { .rc_interval = 400, + .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .module_name = "az6007", .rc_query = az6007_rc_query, + .allowed_protos = RC_TYPE_NEC, }, .i2c_algo = &az6007_i2c_algo, -- cgit v1.2.3-70-g09d2 From 083995477d45ae087d3c4f99cf8ae95b9de84019 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 12:41:21 -0300 Subject: [media] az6007: Use the right keycode for Terratec H7 Instead of using a fake keycode, just for testing, use the right one, for Terratec H7. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 2 +- .../media/rc/keymaps/rc-nec-terratec-cinergy-xs.c | 52 ++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 2288916a2a4..14733b84e8b 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -521,7 +521,7 @@ static struct dvb_usb_device_properties az6007_properties = { .rc.core = { .rc_interval = 400, - .rc_codes = RC_MAP_DIB0700_NEC_TABLE, + .rc_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, .module_name = "az6007", .rc_query = az6007_rc_query, .allowed_protos = RC_TYPE_NEC, diff --git a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c index f3b86c8db67..8d4dae2e2ec 100644 --- a/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c +++ b/drivers/media/rc/keymaps/rc-nec-terratec-cinergy-xs.c @@ -18,6 +18,8 @@ */ static struct rc_map_table nec_terratec_cinergy_xs[] = { + + /* Terratec Grey IR, with most keys in orange */ { 0x1441, KEY_HOME}, { 0x1401, KEY_POWER2}, @@ -78,6 +80,56 @@ static struct rc_map_table nec_terratec_cinergy_xs[] = { { 0x144e, KEY_REWIND}, { 0x144f, KEY_FASTFORWARD}, { 0x145c, KEY_NEXT}, + + /* Terratec Black IR, with most keys in black */ + { 0x04eb01, KEY_POWER2}, + + { 0x04eb02, KEY_1}, + { 0x04eb03, KEY_2}, + { 0x04eb04, KEY_3}, + { 0x04eb05, KEY_4}, + { 0x04eb06, KEY_5}, + { 0x04eb07, KEY_6}, + { 0x04eb08, KEY_7}, + { 0x04eb09, KEY_8}, + { 0x04eb0a, KEY_9}, + { 0x04eb0c, KEY_0}, + + { 0x04eb0b, KEY_TEXT}, /* TXT */ + { 0x04eb0d, KEY_REFRESH}, /* Refresh */ + + { 0x04eb0e, KEY_HOME}, + { 0x04eb0f, KEY_EPG}, + + { 0x04eb10, KEY_UP}, + { 0x04eb11, KEY_LEFT}, + { 0x04eb12, KEY_OK}, + { 0x04eb13, KEY_RIGHT}, + { 0x04eb14, KEY_DOWN}, + + { 0x04eb15, KEY_BACKSPACE}, + { 0x04eb16, KEY_INFO}, + + { 0x04eb17, KEY_RED}, + { 0x04eb18, KEY_GREEN}, + { 0x04eb19, KEY_YELLOW}, + { 0x04eb1a, KEY_BLUE}, + + { 0x04eb1c, KEY_VOLUMEUP}, + { 0x04eb1e, KEY_VOLUMEDOWN}, + + { 0x04eb1d, KEY_MUTE}, + + { 0x04eb1b, KEY_CHANNELUP}, + { 0x04eb1f, KEY_CHANNELDOWN}, + + { 0x04eb40, KEY_RECORD}, + { 0x04eb4c, KEY_PLAY}, + { 0x04eb58, KEY_PAUSE}, + + { 0x04eb54, KEY_REWIND}, + { 0x04eb48, KEY_STOP}, + { 0x04eb5c, KEY_NEXT}, }; static struct rc_map_list nec_terratec_cinergy_xs_map = { -- cgit v1.2.3-70-g09d2 From 44744f9b982049da0f89c560d91bd2549aedf0a0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Jul 2011 18:33:26 -0300 Subject: [media] az6007: Enable the driver at the building system Add the corresponding entries to allow building this driver. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/Kconfig | 8 ++++++++ drivers/media/dvb/dvb-usb/Makefile | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 9f203c6767a..e894bad6538 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -361,6 +361,14 @@ config DVB_USB_EC168 help Say Y here to support the E3C EC168 DVB-T USB2.0 receiver. +config DVB_USB_AZ6007 + tristate "AzureWave 6007 and clones DVB-T/C USB2.0 support" + depends on DVB_USB + select DVB_DRXK if !DVB_FE_CUSTOMISE + select MEDIA_TUNER_MT2063 if !DVB_FE_CUSTOMISE + help + Say Y here to support theAfatech AF9005 based DVB-T/DVB-C receivers. + config DVB_USB_AZ6027 tristate "Azurewave DVB-S/S2 USB2.0 AZ6027 support" depends on DVB_USB diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 26c8b9e5705..d9549cb2769 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_DVB_USB_DIB0700) += dvb-usb-dib0700.o dvb-usb-opera-objs = opera1.o obj-$(CONFIG_DVB_USB_OPERA1) += dvb-usb-opera.o - dvb-usb-af9005-objs = af9005.o af9005-fe.o obj-$(CONFIG_DVB_USB_AF9005) += dvb-usb-af9005.o @@ -88,6 +87,9 @@ obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o dvb-usb-ec168-objs = ec168.o obj-$(CONFIG_DVB_USB_EC168) += dvb-usb-ec168.o +dvb-usb-az6007-objs = az6007.o +obj-$(CONFIG_DVB_USB_AZ6007) += dvb-usb-az6007.o + dvb-usb-az6027-objs = az6027.o obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o -- cgit v1.2.3-70-g09d2 From 9e5e3097a3febbf317abc6d1b07bc6c33b20c279 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 21 Jan 2012 13:52:39 -0200 Subject: [media] az6007: CodingStyle fixes Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/az6007.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index 14733b84e8b..02efd94dc72 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -211,9 +211,7 @@ static int az6007_rc_query(struct dvb_usb_device *d) if ((st->data[3] ^ st->data[4]) == 0xff) code = code << 8 | st->data[3]; else - code = code << 16 | st->data[3] << 8| st->data[4]; - - printk("remote query key: %04x\n", code); + code = code << 16 | st->data[3] << 8 | st->data[4]; rc_keydown(d->rc_dev, code, st->data[5]); @@ -302,11 +300,11 @@ int az6007_power_ctrl(struct dvb_usb_device *d, int onoff) ret = az6007_write(d, FX2_SCON1, 0, 3, NULL, 0); if (ret < 0) return ret; - msleep (150); + msleep(150); ret = az6007_write(d, FX2_SCON1, 1, 3, NULL, 0); if (ret < 0) return ret; - msleep (430); + msleep(430); ret = az6007_write(d, AZ6007_POWER, 0, 0, NULL, 0); if (ret < 0) return ret; @@ -362,8 +360,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr | (1 << 8); length = 6 + msgs[i + 1].len; len = msgs[i + 1].len; - ret = __az6007_read(d->udev, req, value, index, st->data, - length); + ret = __az6007_read(d->udev, req, value, index, + st->data, length); if (ret >= len) { for (j = 0; j < len; j++) { msgs[i + 1].buf[j] = st->data[j + 5]; @@ -391,10 +389,11 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], for (j = 0; j < len; j++) { st->data[j] = msgs[i].buf[j + 1]; if (dvb_usb_az6007_debug & 2) - printk(KERN_CONT "0x%02x ", st->data[j]); + printk(KERN_CONT "0x%02x ", + st->data[j]); } - ret = __az6007_write(d->udev, req, value, index, st->data, - length); + ret = __az6007_write(d->udev, req, value, index, + st->data, length); } else { /* read bytes */ if (dvb_usb_az6007_debug & 2) @@ -406,8 +405,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], value = addr; length = msgs[i].len + 6; len = msgs[i].len; - ret = __az6007_read(d->udev, req, value, index, st->data, - length); + ret = __az6007_read(d->udev, req, value, index, + st->data, length); for (j = 0; j < len; j++) { msgs[i].buf[j] = st->data[j + 5]; if (dvb_usb_az6007_debug & 2) @@ -466,7 +465,7 @@ int az6007_identify_state(struct usb_device *udev, __az6007_write(udev, 0x00, 0, 0, NULL, 0); } - deb_info("Device is on %s state\n", *cold? "warm" : "cold"); + deb_info("Device is on %s state\n", *cold ? "warm" : "cold"); return 0; } @@ -514,7 +513,7 @@ static struct dvb_usb_device_properties az6007_properties = { } } }, - }} + } } } }, .power_ctrl = az6007_power_ctrl, .read_mac_address = az6007_read_mac_addr, -- cgit v1.2.3-70-g09d2 From c6a32fcbbbc25d7d4e7178aa984e5ef186ee9589 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 20 Jan 2012 10:43:44 +0100 Subject: drm/i915: clarify gen2 pageflip cmd I've reviewed gen2 pageflip code to hunt down multiple prepare pageflip issues. The only thing I've found is a slight but functionally meaningless confusion about the length of the mi cmd. Fix it up and add a comment about what this dword should be (according to docs at least). Reviewed-by: Eric Anholt Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ebe71eda954..4247a7b1823 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7288,7 +7288,7 @@ static int intel_gen2_queue_flip(struct drm_device *dev, MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitches[0]); OUT_RING(obj->gtt_offset + offset); - OUT_RING(MI_NOOP); + OUT_RING(0); /* aux display base address, unused */ ADVANCE_LP_RING(); out: return ret; -- cgit v1.2.3-70-g09d2 From 47842649ef43ba4b81ac2486df8caa0934e01195 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Mon, 16 Jan 2012 11:57:54 -0800 Subject: drm/i915: properly mask and or watermark values for sprites Now that we're using the sprite WM fields, we need to take care not to clobber them in the main update_wm functions. While we're at it, make sure we mask out the old sprite wm value before or'ing in the new one when the sprite wm is updated. Signed-off-by: Jesse Barnes Reviewed-by: Keith Packard Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4247a7b1823..ec31350337d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4548,6 +4548,7 @@ void sandybridge_update_wm(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ + u32 val; int fbc_wm, plane_wm, cursor_wm; unsigned int enabled; @@ -4556,8 +4557,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEA_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEA_ILK); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEA_ILK, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe A -" " plane %d, " "cursor: %d\n", plane_wm, cursor_wm); @@ -4568,8 +4571,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEB_ILK, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEB_ILK); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEB_ILK, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe B -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); @@ -4582,8 +4587,10 @@ void sandybridge_update_wm(struct drm_device *dev) &sandybridge_display_wm_info, latency, &sandybridge_cursor_wm_info, latency, &plane_wm, &cursor_wm)) { - I915_WRITE(WM0_PIPEC_IVB, - (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + val = I915_READ(WM0_PIPEC_IVB); + val &= ~(WM0_PIPE_PLANE_MASK | WM0_PIPE_CURSOR_MASK); + I915_WRITE(WM0_PIPEC_IVB, val | + ((plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm)); DRM_DEBUG_KMS("FIFO watermarks For pipe C -" " plane %d, cursor: %d\n", plane_wm, cursor_wm); @@ -4727,6 +4734,7 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, { struct drm_i915_private *dev_priv = dev->dev_private; int latency = SNB_READ_WM0_LATENCY() * 100; /* In unit 0.1us */ + u32 val; int sprite_wm, reg; int ret; @@ -4753,7 +4761,9 @@ static void sandybridge_update_sprite_wm(struct drm_device *dev, int pipe, return; } - I915_WRITE(reg, I915_READ(reg) | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); + val = I915_READ(reg); + val &= ~WM0_PIPE_SPRITE_MASK; + I915_WRITE(reg, val | (sprite_wm << WM0_PIPE_SPRITE_SHIFT)); DRM_DEBUG_KMS("sprite watermarks For pipe %d - %d\n", pipe, sprite_wm); -- cgit v1.2.3-70-g09d2 From aca258482ed7c600b5aeed03aa8727d94d8dd07e Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Tue, 17 Jan 2012 15:25:45 -0200 Subject: drm/i915: print out which pixel format we do not support Otherwise, we are left with pretty bogus message saying that the pixel format is not supported while leaving the details to the telepatic powers. v2: use DRM_DEBUG_KMS instead of DRM_ERROR Signed-off-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ec31350337d..cfd3a87807f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7890,7 +7890,8 @@ int intel_framebuffer_init(struct drm_device *dev, case DRM_FORMAT_VYUY: break; default: - DRM_ERROR("unsupported pixel format\n"); + DRM_DEBUG_KMS("unsupported pixel format %u\n", + mode_cmd->pixel_format); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From d5ad34f7cb8b23ab165cabef69577a2a20d53195 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:09:18 +0000 Subject: regulator: Implement devm_regulator_free() Allow consumers to free regulators allocated using devm_regulator_get() if they need to. This will not normally be required. Signed-off-by: Mark Brown --- drivers/regulator/core.c | 28 ++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 1 + 2 files changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 214640db084..88bcb111ca6 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -1421,6 +1421,34 @@ void regulator_put(struct regulator *regulator) } EXPORT_SYMBOL_GPL(regulator_put); +static int devm_regulator_match(struct device *dev, void *res, void *data) +{ + struct regulator **r = res; + if (!r || !*r) { + WARN_ON(!r || !*r); + return 0; + } + return *r == data; +} + +/** + * devm_regulator_put - Resource managed regulator_put() + * @regulator: regulator to free + * + * Deallocate a regulator allocated with devm_regulator_get(). Normally + * this function will not need to be called and the resource management + * code will ensure that the resource is freed. + */ +void devm_regulator_put(struct regulator *regulator) +{ + int rc; + + rc = devres_destroy(regulator->dev, devm_regulator_release, + devm_regulator_match, regulator); + WARN_ON(rc); +} +EXPORT_SYMBOL_GPL(devm_regulator_put); + static int _regulator_can_change_status(struct regulator_dev *rdev) { if (!rdev->constraints) diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index bcfe1065876..60c2f996d89 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -137,6 +137,7 @@ struct regulator *__must_check devm_regulator_get(struct device *dev, struct regulator *__must_check regulator_get_exclusive(struct device *dev, const char *id); void regulator_put(struct regulator *regulator); +void devm_regulator_free(struct regulator *regulator); /* regulator output control and status */ int regulator_enable(struct regulator *regulator); -- cgit v1.2.3-70-g09d2 From e6e740304aa2a49ef09497e6c0bb906ed7987f6b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 20 Jan 2012 20:10:08 +0000 Subject: regulator: Provide devm_regulator_bulk_get() Allow drivers to benefit from both the bulk APIs and managed resources simultaneously. Signed-off-by: Mark Brown --- drivers/regulator/core.c | 46 ++++++++++++++++++++++++++++++++++++++ include/linux/regulator/consumer.h | 2 ++ 2 files changed, 48 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 88bcb111ca6..1432c22926b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2463,6 +2463,52 @@ err: } EXPORT_SYMBOL_GPL(regulator_bulk_get); +/** + * devm_regulator_bulk_get - managed get multiple regulator consumers + * + * @dev: Device to supply + * @num_consumers: Number of consumers to register + * @consumers: Configuration of consumers; clients are stored here. + * + * @return 0 on success, an errno on failure. + * + * This helper function allows drivers to get several regulator + * consumers in one operation with management, the regulators will + * automatically be freed when the device is unbound. If any of the + * regulators cannot be acquired then any regulators that were + * allocated will be freed before returning to the caller. + */ +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers) +{ + int i; + int ret; + + for (i = 0; i < num_consumers; i++) + consumers[i].consumer = NULL; + + for (i = 0; i < num_consumers; i++) { + consumers[i].consumer = devm_regulator_get(dev, + consumers[i].supply); + if (IS_ERR(consumers[i].consumer)) { + ret = PTR_ERR(consumers[i].consumer); + dev_err(dev, "Failed to get supply '%s': %d\n", + consumers[i].supply, ret); + consumers[i].consumer = NULL; + goto err; + } + } + + return 0; + +err: + for (i = 0; i < num_consumers && consumers[i].consumer; i++) + devm_regulator_put(consumers[i].consumer); + + return ret; +} +EXPORT_SYMBOL_GPL(devm_regulator_bulk_get); + static void regulator_bulk_enable_async(void *data, async_cookie_t cookie) { struct regulator_bulk_data *bulk = data; diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 60c2f996d89..35c42834ba3 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h @@ -148,6 +148,8 @@ int regulator_disable_deferred(struct regulator *regulator, int ms); int regulator_bulk_get(struct device *dev, int num_consumers, struct regulator_bulk_data *consumers); +int devm_regulator_bulk_get(struct device *dev, int num_consumers, + struct regulator_bulk_data *consumers); int regulator_bulk_enable(int num_consumers, struct regulator_bulk_data *consumers); int regulator_bulk_disable(int num_consumers, -- cgit v1.2.3-70-g09d2 From db3dbd093a7cbb201f169ace35f6cdff562e5a77 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:29 -0800 Subject: Input: nomadik-ske-keypad - do not assign driver's probe() method Because we are using platform_device_probe() to register the driver we do not need to assign driver's probe method. We also can mark ske_keypad_probe(), together with ske_keypad_chip_init(), as __init instead of __devinit. Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index 5a71e55c9c5..a804f7b815b 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -88,7 +88,7 @@ static void ske_keypad_set_bits(struct ske_keypad *keypad, u16 addr, * * Enable Multi key press detection, auto scan mode */ -static int __devinit ske_keypad_chip_init(struct ske_keypad *keypad) +static int __init ske_keypad_chip_init(struct ske_keypad *keypad) { u32 value; int timeout = 50; @@ -198,7 +198,7 @@ static irqreturn_t ske_keypad_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int __devinit ske_keypad_probe(struct platform_device *pdev) +static int __init ske_keypad_probe(struct platform_device *pdev) { const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; struct ske_keypad *keypad; @@ -387,7 +387,6 @@ static struct platform_driver ske_keypad_driver = { .pm = &ske_keypad_dev_pm_ops, #endif }, - .probe = ske_keypad_probe, .remove = __devexit_p(ske_keypad_remove), }; module_platform_driver(ske_keypad_driver); -- cgit v1.2.3-70-g09d2 From 89f0f170fbec6290637c3172cb08ddf31f211ef0 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: nomadik-ske-keypad - convert to using SIMPLE_DEV_PM_OPS Also proper guard for system suspend/resume methods is CONFIG_PM_SLEEP, not CONFIG_PM. Acked-by: Linus Walleij Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/nomadik-ske-keypad.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/nomadik-ske-keypad.c b/drivers/input/keyboard/nomadik-ske-keypad.c index a804f7b815b..91c2fcb8ca4 100644 --- a/drivers/input/keyboard/nomadik-ske-keypad.c +++ b/drivers/input/keyboard/nomadik-ske-keypad.c @@ -344,7 +344,7 @@ static int __devexit ske_keypad_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int ske_keypad_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); @@ -372,20 +372,16 @@ static int ske_keypad_resume(struct device *dev) return 0; } - -static const struct dev_pm_ops ske_keypad_dev_pm_ops = { - .suspend = ske_keypad_suspend, - .resume = ske_keypad_resume, -}; #endif +static SIMPLE_DEV_PM_OPS(ske_keypad_dev_pm_ops, + ske_keypad_suspend, ske_keypad_resume); + static struct platform_driver ske_keypad_driver = { .driver = { .name = "nmk-ske-keypad", .owner = THIS_MODULE, -#ifdef CONFIG_PM .pm = &ske_keypad_dev_pm_ops, -#endif }, .remove = __devexit_p(ske_keypad_remove), }; -- cgit v1.2.3-70-g09d2 From 3e8040b0a93cadeead148938188212ac7422a6bc Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: at32psif - convert to dev_pm_ops Convert driver to use dev_pm_ops instead of legacy PM infrastructure. Also make 'open' a bool since it is really a boolean. Signed-off-by: Dmitry Torokhov --- drivers/input/serio/at32psif.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/serio/at32psif.c b/drivers/input/serio/at32psif.c index 421a7442e46..d0d861fb5b8 100644 --- a/drivers/input/serio/at32psif.c +++ b/drivers/input/serio/at32psif.c @@ -98,9 +98,9 @@ struct psif { struct serio *io; void __iomem *regs; unsigned int irq; - unsigned int open; /* Prevent concurrent writes to PSIF THR. */ spinlock_t lock; + bool open; }; static irqreturn_t psif_interrupt(int irq, void *_ptr) @@ -164,7 +164,7 @@ static int psif_open(struct serio *io) psif_writel(psif, CR, PSIF_BIT(CR_TXEN) | PSIF_BIT(CR_RXEN)); psif_writel(psif, IER, PSIF_BIT(RXRDY)); - psif->open = 1; + psif->open = true; out: return retval; } @@ -173,7 +173,7 @@ static void psif_close(struct serio *io) { struct psif *psif = io->port_data; - psif->open = 0; + psif->open = false; psif_writel(psif, IDR, ~0UL); psif_writel(psif, CR, PSIF_BIT(CR_TXDIS) | PSIF_BIT(CR_RXDIS)); @@ -319,9 +319,10 @@ static int __exit psif_remove(struct platform_device *pdev) return 0; } -#ifdef CONFIG_PM -static int psif_suspend(struct platform_device *pdev, pm_message_t state) +#ifdef CONFIG_PM_SLEEP +static int psif_suspend(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct psif *psif = platform_get_drvdata(pdev); if (psif->open) { @@ -332,8 +333,9 @@ static int psif_suspend(struct platform_device *pdev, pm_message_t state) return 0; } -static int psif_resume(struct platform_device *pdev) +static int psif_resume(struct device *dev) { + struct platform_device *pdev = to_platform_device(dev); struct psif *psif = platform_get_drvdata(pdev); if (psif->open) { @@ -344,19 +346,17 @@ static int psif_resume(struct platform_device *pdev) return 0; } -#else -#define psif_suspend NULL -#define psif_resume NULL #endif +static SIMPLE_DEV_PM_OPS(psif_pm_ops, psif_suspend, psif_resume); + static struct platform_driver psif_driver = { .remove = __exit_p(psif_remove), .driver = { .name = "atmel_psif", .owner = THIS_MODULE, + .pm = &psif_pm_ops, }, - .suspend = psif_suspend, - .resume = psif_resume, }; module_platform_driver(psif_driver); -- cgit v1.2.3-70-g09d2 From 409e15442fc7f7ae9d025f3ea3fdf3c60070314f Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: q40kbd - convert driver to the split model Convert the driver to standard spilt model arch-specific code registers platform device to which driver code can bind later. Also request IRQ immediately upon binding to the device instead of doing this when serio port is being opened. Acked-by: Geert Uytterhoeven Signed-off-by: Dmitry Torokhov --- arch/m68k/q40/config.c | 13 ++++ drivers/input/serio/q40kbd.c | 139 ++++++++++++++++++++++++------------------- 2 files changed, 92 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c index ad10fecec2f..be936480b96 100644 --- a/arch/m68k/q40/config.c +++ b/arch/m68k/q40/config.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -329,3 +330,15 @@ static int q40_set_rtc_pll(struct rtc_pll_info *pll) } else return -EINVAL; } + +static __init int q40_add_kbd_device(void) +{ + struct platform_device *pdev; + + pdev = platform_device_register_simple("q40kbd", -1, NULL, 0); + if (IS_ERR(pdev)) + return PTR_ERR(pdev); + + return 0; +} +arch_initcall(q40_add_kbd_device); diff --git a/drivers/input/serio/q40kbd.c b/drivers/input/serio/q40kbd.c index 5eb84b3b67f..0c0df7f7380 100644 --- a/drivers/input/serio/q40kbd.c +++ b/drivers/input/serio/q40kbd.c @@ -44,26 +44,31 @@ #include #include +#define DRV_NAME "q40kbd" + MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("Q40 PS/2 keyboard controller driver"); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:" DRV_NAME); -static DEFINE_SPINLOCK(q40kbd_lock); -static struct serio *q40kbd_port; -static struct platform_device *q40kbd_device; +struct q40kbd { + struct serio *port; + spinlock_t lock; +}; static irqreturn_t q40kbd_interrupt(int irq, void *dev_id) { + struct q40kbd *q40kbd = dev_id; unsigned long flags; - spin_lock_irqsave(&q40kbd_lock, flags); + spin_lock_irqsave(&q40kbd->lock, flags); if (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG)) - serio_interrupt(q40kbd_port, master_inb(KEYCODE_REG), 0); + serio_interrupt(q40kbd->port, master_inb(KEYCODE_REG), 0); master_outb(-1, KEYBOARD_UNLOCK_REG); - spin_unlock_irqrestore(&q40kbd_lock, flags); + spin_unlock_irqrestore(&q40kbd->lock, flags); return IRQ_HANDLED; } @@ -72,17 +77,23 @@ static irqreturn_t q40kbd_interrupt(int irq, void *dev_id) * q40kbd_flush() flushes all data that may be in the keyboard buffers */ -static void q40kbd_flush(void) +static void q40kbd_flush(struct q40kbd *q40kbd) { int maxread = 100; unsigned long flags; - spin_lock_irqsave(&q40kbd_lock, flags); + spin_lock_irqsave(&q40kbd->lock, flags); while (maxread-- && (Q40_IRQ_KEYB_MASK & master_inb(INTERRUPT_REG))) master_inb(KEYCODE_REG); - spin_unlock_irqrestore(&q40kbd_lock, flags); + spin_unlock_irqrestore(&q40kbd->lock, flags); +} + +static void q40kbd_stop(void) +{ + master_outb(0, KEY_IRQ_ENABLE_REG); + master_outb(-1, KEYBOARD_UNLOCK_REG); } /* @@ -92,12 +103,9 @@ static void q40kbd_flush(void) static int q40kbd_open(struct serio *port) { - q40kbd_flush(); + struct q40kbd *q40kbd = port->port_data; - if (request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, "q40kbd", NULL)) { - printk(KERN_ERR "q40kbd.c: Can't get irq %d.\n", Q40_IRQ_KEYBOARD); - return -EBUSY; - } + q40kbd_flush(q40kbd); /* off we go */ master_outb(-1, KEYBOARD_UNLOCK_REG); @@ -108,36 +116,72 @@ static int q40kbd_open(struct serio *port) static void q40kbd_close(struct serio *port) { - master_outb(0, KEY_IRQ_ENABLE_REG); - master_outb(-1, KEYBOARD_UNLOCK_REG); - free_irq(Q40_IRQ_KEYBOARD, NULL); + struct q40kbd *q40kbd = port->port_data; - q40kbd_flush(); + q40kbd_stop(); + q40kbd_flush(q40kbd); } -static int __devinit q40kbd_probe(struct platform_device *dev) +static int __devinit q40kbd_probe(struct platform_device *pdev) { - q40kbd_port = kzalloc(sizeof(struct serio), GFP_KERNEL); - if (!q40kbd_port) - return -ENOMEM; - - q40kbd_port->id.type = SERIO_8042; - q40kbd_port->open = q40kbd_open; - q40kbd_port->close = q40kbd_close; - q40kbd_port->dev.parent = &dev->dev; - strlcpy(q40kbd_port->name, "Q40 Kbd Port", sizeof(q40kbd_port->name)); - strlcpy(q40kbd_port->phys, "Q40", sizeof(q40kbd_port->phys)); - - serio_register_port(q40kbd_port); + struct q40kbd *q40kbd; + struct serio *port; + int error; + + q40kbd = kzalloc(sizeof(struct q40kbd), GFP_KERNEL); + port = kzalloc(sizeof(struct serio), GFP_KERNEL); + if (!q40kbd || !port) { + error = -ENOMEM; + goto err_free_mem; + } + + q40kbd->port = port; + spin_lock_init(&q40kbd->lock); + + port->id.type = SERIO_8042; + port->open = q40kbd_open; + port->close = q40kbd_close; + port->port_data = q40kbd; + port->dev.parent = &pdev->dev; + strlcpy(port->name, "Q40 Kbd Port", sizeof(port->name)); + strlcpy(port->phys, "Q40", sizeof(port->phys)); + + q40kbd_stop(); + + error = request_irq(Q40_IRQ_KEYBOARD, q40kbd_interrupt, 0, + DRV_NAME, q40kbd); + if (error) { + dev_err(&pdev->dev, "Can't get irq %d.\n", Q40_IRQ_KEYBOARD); + goto err_free_mem; + } + + serio_register_port(q40kbd->port); + + platform_set_drvdata(pdev, q40kbd); printk(KERN_INFO "serio: Q40 kbd registered\n"); return 0; + +err_free_mem: + kfree(port); + kfree(q40kbd); + return error; } -static int __devexit q40kbd_remove(struct platform_device *dev) +static int __devexit q40kbd_remove(struct platform_device *pdev) { - serio_unregister_port(q40kbd_port); - + struct q40kbd *q40kbd = platform_get_drvdata(pdev); + + /* + * q40kbd_close() will be called as part of unregistering + * and will ensure that IRQ is turned off, so it is safe + * to unregister port first and free IRQ later. + */ + serio_unregister_port(q40kbd->port); + free_irq(Q40_IRQ_KEYBOARD, q40kbd); + kfree(q40kbd); + + platform_set_drvdata(pdev, NULL); return 0; } @@ -146,41 +190,16 @@ static struct platform_driver q40kbd_driver = { .name = "q40kbd", .owner = THIS_MODULE, }, - .probe = q40kbd_probe, .remove = __devexit_p(q40kbd_remove), }; static int __init q40kbd_init(void) { - int error; - - if (!MACH_IS_Q40) - return -ENODEV; - - error = platform_driver_register(&q40kbd_driver); - if (error) - return error; - - q40kbd_device = platform_device_alloc("q40kbd", -1); - if (!q40kbd_device) - goto err_unregister_driver; - - error = platform_device_add(q40kbd_device); - if (error) - goto err_free_device; - - return 0; - - err_free_device: - platform_device_put(q40kbd_device); - err_unregister_driver: - platform_driver_unregister(&q40kbd_driver); - return error; + return platform_driver_probe(&q40kbd_driver, q40kbd_probe); } static void __exit q40kbd_exit(void) { - platform_device_unregister(q40kbd_device); platform_driver_unregister(&q40kbd_driver); } -- cgit v1.2.3-70-g09d2 From 69898e512a4c27017aec43796bef8fe1dd1ec661 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: samsung-keypad - don't synchronise with runtime PM put We don't actually care if the device has been runtime suspended immediately so we can just drop the reference without waiting for any state change to be implemented. This may allow us to avoid some suspend/resume cycles and is a bit more friendly to the rest of the system. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/samsung-keypad.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index b746fce2d12..395b3af9f73 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c @@ -178,7 +178,7 @@ static irqreturn_t samsung_keypad_irq(int irq, void *dev_id) } while (key_down && !keypad->stopped); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); return IRQ_HANDLED; } @@ -202,7 +202,7 @@ static void samsung_keypad_start(struct samsung_keypad *keypad) /* KEYIFCOL reg clear. */ writel(0, keypad->base + SAMSUNG_KEYIFCOL); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); } static void samsung_keypad_stop(struct samsung_keypad *keypad) @@ -232,7 +232,7 @@ static void samsung_keypad_stop(struct samsung_keypad *keypad) */ enable_irq(keypad->irq); - pm_runtime_put_sync(&keypad->pdev->dev); + pm_runtime_put(&keypad->pdev->dev); } static int samsung_keypad_open(struct input_dev *input_dev) -- cgit v1.2.3-70-g09d2 From b6834b02e476ff0e99b6814665839e37affa31f0 Mon Sep 17 00:00:00 2001 From: Rakesh Iyer Date: Sun, 22 Jan 2012 23:27:54 -0800 Subject: Input: tegra-kbc - enable key interrupt for wakeup Enable keypress interrupt to support wakeup from low power state. Signed-off-by: Rakesh Iyer Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tegra-kbc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index a136e2e832b..b307a46ecef 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -48,6 +48,7 @@ #define KBC_FIFO_TH_CNT_SHIFT(cnt) (cnt << 14) #define KBC_DEBOUNCE_CNT_SHIFT(cnt) (cnt << 4) #define KBC_CONTROL_FIFO_CNT_INT_EN (1 << 3) +#define KBC_CONTROL_KEYPRESS_INT_EN (1 << 1) #define KBC_CONTROL_KBC_EN (1 << 0) /* KBC Interrupt Register */ @@ -356,6 +357,18 @@ static void tegra_kbc_set_fifo_interrupt(struct tegra_kbc *kbc, bool enable) writel(val, kbc->mmio + KBC_CONTROL_0); } +static void tegra_kbc_set_keypress_interrupt(struct tegra_kbc *kbc, bool enable) +{ + u32 val; + + val = readl(kbc->mmio + KBC_CONTROL_0); + if (enable) + val |= KBC_CONTROL_KEYPRESS_INT_EN; + else + val &= ~KBC_CONTROL_KEYPRESS_INT_EN; + writel(val, kbc->mmio + KBC_CONTROL_0); +} + static void tegra_kbc_keypress_timer(unsigned long data) { struct tegra_kbc *kbc = (struct tegra_kbc *)data; @@ -831,6 +844,8 @@ static int tegra_kbc_suspend(struct device *dev) msleep(30); kbc->keypress_caused_wake = false; + /* Enable keypress interrupt before going into suspend. */ + tegra_kbc_set_keypress_interrupt(kbc, true); enable_irq(kbc->irq); enable_irq_wake(kbc->irq); } else { @@ -852,6 +867,8 @@ static int tegra_kbc_resume(struct device *dev) if (device_may_wakeup(&pdev->dev)) { disable_irq_wake(kbc->irq); tegra_kbc_setup_wakekeys(kbc, false); + /* We will use fifo interrupts for key detection. */ + tegra_kbc_set_keypress_interrupt(kbc, false); /* Restore the resident time of continuous polling mode. */ writel(kbc->cp_to_wkup_dly, kbc->mmio + KBC_TO_CNT_0); -- cgit v1.2.3-70-g09d2 From 22f0d90a34827812413bb3fbeda6a2a79bb58423 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 12:01:14 +0000 Subject: regmap: Support register patch sets Device manufacturers frequently provide register sequences, usually not fully documented, to be run at startup in order to provide better defaults for devices (for example, improving performance in the light of silicon evaluation). Support such updates by allowing drivers to register update sets with the core. These updates will be written to the device immediately and will also be rewritten when the cache is synced. The assumption is that the reason for resyncing the cache will always be that the device has been powered off. If this turns out to not be the case then a separate operation can be provided. Currently the implementation only allows a single set of updates to be specified for a device, this could be extended in future. Signed-off-by: Mark Brown --- drivers/base/regmap/internal.h | 3 +++ drivers/base/regmap/regcache.c | 11 ++++++++ drivers/base/regmap/regmap.c | 58 ++++++++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 3 +++ 4 files changed, 75 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index 1a02b7537c8..d141b80479b 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h @@ -75,6 +75,9 @@ struct regmap { const void *reg_defaults_raw; void *cache; bool cache_dirty; + + struct reg_default *patch; + int patch_regs; }; struct regcache_ops { diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7..ce2034c10ff 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -268,6 +268,17 @@ int regcache_sync(struct regmap *map) map->cache_ops->name); name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); + + /* Apply any patch first */ + for (i = 0; i < map->patch_regs; i++) { + ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + map->patch[i].reg, map->patch[i].def, ret); + goto out; + } + } + if (!map->cache_dirty) goto out; if (map->cache_ops->sync) { diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..28e89fd7c28 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -669,6 +669,64 @@ int regmap_update_bits_check(struct regmap *map, unsigned int reg, } EXPORT_SYMBOL_GPL(regmap_update_bits_check); +/** + * regmap_register_patch: Register and apply register updates to be applied + * on device initialistion + * + * @map: Register map to apply updates to. + * @regs: Values to update. + * @num_regs: Number of entries in regs. + * + * Register a set of register updates to be applied to the device + * whenever the device registers are synchronised with the cache and + * apply them immediately. Typically this is used to apply + * corrections to be applied to the device defaults on startup, such + * as the updates some vendors provide to undocumented registers. + */ +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs) +{ + int i, ret; + bool bypass; + + /* If needed the implementation can be extended to support this */ + if (map->patch) + return -EBUSY; + + mutex_lock(&map->lock); + + bypass = map->cache_bypass; + + map->cache_bypass = true; + + /* Write out first; it's useful to apply even if we fail later. */ + for (i = 0; i < num_regs; i++) { + ret = _regmap_write(map, regs[i].reg, regs[i].def); + if (ret != 0) { + dev_err(map->dev, "Failed to write %x = %x: %d\n", + regs[i].reg, regs[i].def, ret); + goto out; + } + } + + map->patch = kcalloc(sizeof(struct reg_default), num_regs, GFP_KERNEL); + if (map->patch != NULL) { + memcpy(map->patch, regs, + num_regs * sizeof(struct reg_default)); + map->patch_regs = num_regs; + } else { + ret = -ENOMEM; + } + +out: + map->cache_bypass = bypass; + + mutex_unlock(&map->lock); + + return ret; +} +EXPORT_SYMBOL_GPL(regmap_register_patch); + static int __init regmap_initcall(void) { regmap_debugfs_initcall(); diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..860739a8a6d 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -149,6 +149,9 @@ void regcache_cache_only(struct regmap *map, bool enable); void regcache_cache_bypass(struct regmap *map, bool enable); void regcache_mark_dirty(struct regmap *map); +int regmap_register_patch(struct regmap *map, const struct reg_default *regs, + int num_regs); + /** * Description of an IRQ for the generic regmap irq_chip. * -- cgit v1.2.3-70-g09d2 From aa104b2fea3ced2a562c480448a2f346c3ab61f4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 23 Jan 2012 13:15:22 -0200 Subject: [media] cinergyT2-fe: Fix bandwdith settings Changeset 7830bbaff9f mangled the bandwidth field for CinergyT2. Properly fill it. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/cinergyT2-fe.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c index 8a57ed8272d..1efc028a76c 100644 --- a/drivers/media/dvb/dvb-usb/cinergyT2-fe.c +++ b/drivers/media/dvb/dvb-usb/cinergyT2-fe.c @@ -276,14 +276,15 @@ static int cinergyt2_fe_set_frontend(struct dvb_frontend *fe) param.flags = 0; switch (fep->bandwidth_hz) { + default: case 8000000: - param.bandwidth = 0; + param.bandwidth = 8; break; case 7000000: - param.bandwidth = 1; + param.bandwidth = 7; break; case 6000000: - param.bandwidth = 2; + param.bandwidth = 6; break; } -- cgit v1.2.3-70-g09d2 From 93596ef7db3e9bcc9306c3e93cf28ce1048858b6 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 8 Nov 2011 05:47:08 -0300 Subject: [media] omap_vout: fix section mismatch Fix the following warning by using platform_driver_probe() instead of platform_driver_register(): WARNING: drivers/media/video/omap/omap-vout.o(.data+0x24): Section mismatch in reference from the variable omap_vout_driver to the function .init.text:omap_vout_probe() The variable omap_vout_driver references the function __init omap_vout_probe() Signed-off-by: Tomi Valkeinen Acked-by: Vaibhav Hiremath Tested-by: Vaibhav Hiremath Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/omap/omap_vout.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 1fb7d5bd5ec..88cf9d95263 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -2268,13 +2268,12 @@ static struct platform_driver omap_vout_driver = { .driver = { .name = VOUT_NAME, }, - .probe = omap_vout_probe, .remove = omap_vout_remove, }; static int __init omap_vout_init(void) { - if (platform_driver_register(&omap_vout_driver) != 0) { + if (platform_driver_probe(&omap_vout_driver, omap_vout_probe) != 0) { printk(KERN_ERR VOUT_NAME ":Could not register Video driver\n"); return -EINVAL; } -- cgit v1.2.3-70-g09d2 From 583aa3a9b5ca846a84f7dd87bdc4b75dca07b011 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 11 Jan 2012 06:45:05 -0300 Subject: [media] V4L2: Add per-device-node capabilities If V4L2_CAP_DEVICE_CAPS is set, then the new device_caps field is filled with the capabilities of the opened device node. The capabilities field traditionally contains the capabilities of the physical device, being a superset of all capabilities available at the several device nodes. E.g., if you open /dev/video0, then if it contains VBI caps then that means that there is a corresponding vbi node as well. And the capabilities field of both the video and vbi nodes should contain identical caps. However, it would be very useful to also have a capabilities field that contains just the caps for the currently open device, hence the new CAP bit and field. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/media/v4l/compat.xml | 4 +++ Documentation/DocBook/media/v4l/v4l2.xml | 9 +++++- .../DocBook/media/v4l/vidioc-querycap.xml | 36 ++++++++++++++++++++-- drivers/media/video/cx231xx/cx231xx-417.c | 1 - drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 1 - drivers/media/video/v4l2-ioctl.c | 6 ++-- include/linux/videodev2.h | 29 +++++++++++------ 7 files changed, 69 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/Documentation/DocBook/media/v4l/compat.xml b/Documentation/DocBook/media/v4l/compat.xml index c736380b464..c93298ff327 100644 --- a/Documentation/DocBook/media/v4l/compat.xml +++ b/Documentation/DocBook/media/v4l/compat.xml @@ -2393,6 +2393,10 @@ details. to the User controls class. + + Added the device_caps field to struct v4l2_capabilities and added the new + V4L2_CAP_DEVICE_CAPS capability. + diff --git a/Documentation/DocBook/media/v4l/v4l2.xml b/Documentation/DocBook/media/v4l/v4l2.xml index e97c512861b..dce3fef15bc 100644 --- a/Documentation/DocBook/media/v4l/v4l2.xml +++ b/Documentation/DocBook/media/v4l/v4l2.xml @@ -127,6 +127,13 @@ structs, ioctls) must be noted in more detail in the history chapter (compat.xml), along with the possible impact on existing drivers and applications. --> + + 3.3 + 2012-01-11 + hv + Added device_caps field to struct v4l2_capabilities. + + 3.2 2011-08-26 @@ -417,7 +424,7 @@ and discussions on the V4L mailing list. Video for Linux Two API Specification - Revision 3.2 + Revision 3.3 &sub-common; diff --git a/Documentation/DocBook/media/v4l/vidioc-querycap.xml b/Documentation/DocBook/media/v4l/vidioc-querycap.xml index e3664d6f2de..4643505cd4c 100644 --- a/Documentation/DocBook/media/v4l/vidioc-querycap.xml +++ b/Documentation/DocBook/media/v4l/vidioc-querycap.xml @@ -124,12 +124,35 @@ printf ("Version: %u.%u.%u\n", __u32 capabilities - Device capabilities, see . + Available capabilities of the physical device as a whole, see . The same physical device can export + multiple devices in /dev (e.g. /dev/videoX, /dev/vbiY and /dev/radioZ). + The capabilities field should contain a union + of all capabilities available around the several V4L2 devices exported + to userspace. + For all those devices the capabilities field + returns the same set of capabilities. This allows applications to open + just one of the devices (typically the video device) and discover whether + video, vbi and/or radio are also supported. + __u32 - reserved[4] + device_caps + Device capabilities of the opened device, see . Should contain the available capabilities + of that specific device node. So, for example, device_caps + of a radio device will only contain radio related capabilities and + no video or vbi capabilities. This field is only set if the capabilities + field contains the V4L2_CAP_DEVICE_CAPS capability. + Only the capabilities field can have the + V4L2_CAP_DEVICE_CAPS capability, device_caps + will never set V4L2_CAP_DEVICE_CAPS. + + + + __u32 + reserved[3] Reserved for future extensions. Drivers must set this array to zero. @@ -276,6 +299,13 @@ linkend="async">asynchronous I/O methods. The device supports the streaming I/O method. + + V4L2_CAP_DEVICE_CAPS + 0x80000000 + The driver fills the device_caps + field. This capability can only appear in the capabilities + field and never in the device_caps field. + diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c index f8f0e59cd58..d4327dab5a3 100644 --- a/drivers/media/video/cx231xx/cx231xx-417.c +++ b/drivers/media/video/cx231xx/cx231xx-417.c @@ -1686,7 +1686,6 @@ static struct v4l2_capability pvr_capability = { .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | V4L2_CAP_STREAMING | V4L2_CAP_READWRITE), - .reserved = {0, 0, 0, 0} }; static int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap) diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c index 6d666174dbb..e1111d968a3 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c +++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c @@ -96,7 +96,6 @@ static struct v4l2_capability pvr_capability ={ .capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO | V4L2_CAP_READWRITE), - .reserved = {0,0,0,0} }; static struct v4l2_fmtdesc pvr_fmtdesc [] = { diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 3f623859a33..d0d7281e01e 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c @@ -540,10 +540,12 @@ static long __video_do_ioctl(struct file *file, if (!ret) dbgarg(cmd, "driver=%s, card=%s, bus=%s, " "version=0x%08x, " - "capabilities=0x%08x\n", + "capabilities=0x%08x, " + "device_caps=0x%08x\n", cap->driver, cap->card, cap->bus_info, cap->version, - cap->capabilities); + cap->capabilities, + cap->device_caps); break; } diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5e11f8a1f86..0db05033c2e 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -235,16 +235,25 @@ struct v4l2_fract { __u32 denominator; }; -/* - * D R I V E R C A P A B I L I T I E S - */ +/** + * struct v4l2_capability - Describes V4L2 device caps returned by VIDIOC_QUERYCAP + * + * @driver: name of the driver module (e.g. "bttv") + * @card: name of the card (e.g. "Hauppauge WinTV") + * @bus_info: name of the bus (e.g. "PCI:" + pci_name(pci_dev) ) + * @version: KERNEL_VERSION + * @capabilities: capabilities of the physical device as a whole + * @device_caps: capabilities accessed via this particular device (node) + * @reserved: reserved fields for future extensions + */ struct v4l2_capability { - __u8 driver[16]; /* i.e. "bttv" */ - __u8 card[32]; /* i.e. "Hauppauge WinTV" */ - __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */ - __u32 version; /* should use KERNEL_VERSION() */ - __u32 capabilities; /* Device capabilities */ - __u32 reserved[4]; + __u8 driver[16]; + __u8 card[32]; + __u8 bus_info[32]; + __u32 version; + __u32 capabilities; + __u32 device_caps; + __u32 reserved[3]; }; /* Values for 'capabilities' field */ @@ -274,6 +283,8 @@ struct v4l2_capability { #define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */ #define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */ +#define V4L2_CAP_DEVICE_CAPS 0x80000000 /* sets device capabilities field */ + /* * V I D E O I M A G E F O R M A T */ -- cgit v1.2.3-70-g09d2 From a8187c42fbe594754eadd37cf16d3ad7c704869d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 06:53:06 -0300 Subject: [media] vivi: set device_caps Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 7d754fbcccb..84ea88dc10a 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -819,8 +819,9 @@ static int vidioc_querycap(struct file *file, void *priv, strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | \ - V4L2_CAP_READWRITE; + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; + cap->device_caps = cap->capabilities; return 0; } -- cgit v1.2.3-70-g09d2 From d0c8b2d400279f7d4d530ede8c7cb66f75810007 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 7 Nov 2011 07:25:10 -0300 Subject: [media] ivtv: setup per-device caps Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-driver.h | 1 + drivers/media/video/ivtv/ivtv-ioctl.c | 7 +++++-- drivers/media/video/ivtv/ivtv-streams.c | 14 ++++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h index 06f3d78389b..20845d65d34 100644 --- a/drivers/media/video/ivtv/ivtv-driver.h +++ b/drivers/media/video/ivtv/ivtv-driver.h @@ -331,6 +331,7 @@ struct ivtv_stream { struct ivtv *itv; /* for ease of use */ const char *name; /* name of the stream */ int type; /* stream type */ + u32 caps; /* V4L2 capabilities */ struct v4l2_fh *fh; /* pointer to the streaming filehandle */ spinlock_t qlock; /* locks access to the queues */ diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index c4bc4814309..b0630773e50 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -754,12 +754,15 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) { - struct ivtv *itv = fh2id(fh)->itv; + struct ivtv_open_id *id = fh2id(file->private_data); + struct ivtv *itv = id->itv; + struct ivtv_stream *s = &itv->streams[id->type]; strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(itv->pdev)); - vcap->capabilities = itv->v4l2_cap; /* capabilities */ + vcap->capabilities = itv->v4l2_cap | V4L2_CAP_DEVICE_CAPS; + vcap->device_caps = s->caps; return 0; } diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c index c6e28b4ebbe..e5039f4f7f0 100644 --- a/drivers/media/video/ivtv/ivtv-streams.c +++ b/drivers/media/video/ivtv/ivtv-streams.c @@ -78,60 +78,73 @@ static struct { int num_offset; int dma, pio; enum v4l2_buf_type buf_type; + u32 v4l2_caps; const struct v4l2_file_operations *fops; } ivtv_stream_info[] = { { /* IVTV_ENC_STREAM_TYPE_MPG */ "encoder MPG", VFL_TYPE_GRABBER, 0, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_YUV */ "encoder YUV", VFL_TYPE_GRABBER, IVTV_V4L2_ENC_YUV_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_VBI */ "encoder VBI", VFL_TYPE_VBI, 0, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_VBI_CAPTURE, + V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_TUNER | + V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_PCM */ "encoder PCM", VFL_TYPE_GRABBER, IVTV_V4L2_ENC_PCM_OFFSET, PCI_DMA_FROMDEVICE, 0, V4L2_BUF_TYPE_PRIVATE, + V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_ENC_STREAM_TYPE_RAD */ "encoder radio", VFL_TYPE_RADIO, 0, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_PRIVATE, + V4L2_CAP_RADIO | V4L2_CAP_TUNER, &ivtv_v4l2_enc_fops }, { /* IVTV_DEC_STREAM_TYPE_MPG */ "decoder MPG", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_MPG_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_VBI */ "decoder VBI", VFL_TYPE_VBI, IVTV_V4L2_DEC_VBI_OFFSET, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_CAPTURE, + V4L2_CAP_SLICED_VBI_CAPTURE | V4L2_CAP_READWRITE, &ivtv_v4l2_enc_fops }, { /* IVTV_DEC_STREAM_TYPE_VOUT */ "decoder VOUT", VFL_TYPE_VBI, IVTV_V4L2_DEC_VOUT_OFFSET, PCI_DMA_NONE, 1, V4L2_BUF_TYPE_VBI_OUTPUT, + V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops }, { /* IVTV_DEC_STREAM_TYPE_YUV */ "decoder YUV", VFL_TYPE_GRABBER, IVTV_V4L2_DEC_YUV_OFFSET, PCI_DMA_TODEVICE, 0, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_AUDIO | V4L2_CAP_READWRITE, &ivtv_v4l2_dec_fops } }; @@ -149,6 +162,7 @@ static void ivtv_stream_init(struct ivtv *itv, int type) s->itv = itv; s->type = type; s->name = ivtv_stream_info[type].name; + s->caps = ivtv_stream_info[type].v4l2_caps; if (ivtv_stream_info[type].pio) s->dma = PCI_DMA_NONE; -- cgit v1.2.3-70-g09d2 From a8ea0218625699a5c635655a17b565bab5888ea1 Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Fri, 20 Jan 2012 19:07:18 -0300 Subject: [media] it913x v1.23 use it913x_config.chip_ver to select firmware As recommended by Jason at ITE, the chip version should select firmware. However, to continue to support IT9137 firmware with different configuration the driver will use udev->descriptor.idVendor to select the difference between IT9135 and IT9137. Signed-off-by: Malcolm Priestley Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/it913x.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c index 9f01cd7a6e3..50d578c7b8c 100644 --- a/drivers/media/dvb/dvb-usb/it913x.c +++ b/drivers/media/dvb/dvb-usb/it913x.c @@ -388,19 +388,12 @@ static int ite_firmware_select(struct usb_device *udev, { int sw; /* auto switch */ - if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135) - sw = IT9135_V1_FW; - else if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135_9005) + if (le16_to_cpu(udev->descriptor.idVendor) == USB_VID_KWORLD_2) + sw = IT9137_FW; + else if (it913x_config.chip_ver == 1) sw = IT9135_V1_FW; - else if (le16_to_cpu(udev->descriptor.idProduct) == - USB_PID_ITETECH_IT9135_9006) { + else sw = IT9135_V2_FW; - if (it913x_config.tuner_id_0 == 0) - it913x_config.tuner_id_0 = IT9135_60; - } else - sw = IT9137_FW; /* force switch */ if (dvb_usb_it913x_firmware != IT9135_AUTO) @@ -416,6 +409,8 @@ static int ite_firmware_select(struct usb_device *udev, it913x_config.firmware_ver = 1; it913x_config.adc_x2 = 1; props->firmware = fw_it9135_v2; + if (it913x_config.tuner_id_0 == 0) + it913x_config.tuner_id_0 = IT9135_60; break; case IT9137_FW: default: @@ -823,5 +818,5 @@ module_usb_driver(it913x_driver); MODULE_AUTHOR("Malcolm Priestley "); MODULE_DESCRIPTION("it913x USB 2 Driver"); -MODULE_VERSION("1.22"); +MODULE_VERSION("1.23"); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 91c6cc9b5c216bd067f9af2cc64fcbe190755865 Mon Sep 17 00:00:00 2001 From: Dan Magenheimer Date: Thu, 12 Jan 2012 14:03:25 -0500 Subject: mm: zcache/tmem/cleancache: s/flush/invalidate/ Complete the renaming from "flush" to "invalidate" across both tmem frontends (cleancache and frontswap) and both tmem backends (Xen and zcache), as required by akpm. This change is completely cosmetic. [v10: no change] [v9: akpm@linux-foundation.org: change "flush" to "invalidate", part 3] Signed-off-by: Dan Magenheimer Cc: Kamezawa Hiroyuki Cc: Jan Beulich Acked-by: Seth Jennings Cc: Jeremy Fitzhardinge Cc: Hugh Dickins Cc: Johannes Weiner Cc: Nitin Gupta Cc: Matthew Wilcox Cc: Chris Mason Cc: Rik Riel Cc: Andrew Morton [v11: Remove the frontswap part] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/staging/zcache/zcache-main.c | 10 +++++----- drivers/xen/tmem.c | 10 +++++----- include/linux/cleancache.h | 11 +++-------- mm/cleancache.c | 7 ++++--- 4 files changed, 17 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index 56c1f9c80dc..49c8791462f 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -1758,9 +1758,9 @@ static int zcache_cleancache_init_shared_fs(char *uuid, size_t pagesize) static struct cleancache_ops zcache_cleancache_ops = { .put_page = zcache_cleancache_put_page, .get_page = zcache_cleancache_get_page, - .flush_page = zcache_cleancache_flush_page, - .flush_inode = zcache_cleancache_flush_inode, - .flush_fs = zcache_cleancache_flush_fs, + .invalidate_page = zcache_cleancache_flush_page, + .invalidate_inode = zcache_cleancache_flush_inode, + .invalidate_fs = zcache_cleancache_flush_fs, .init_shared_fs = zcache_cleancache_init_shared_fs, .init_fs = zcache_cleancache_init_fs }; @@ -1868,8 +1868,8 @@ static void zcache_frontswap_init(unsigned ignored) static struct frontswap_ops zcache_frontswap_ops = { .put_page = zcache_frontswap_put_page, .get_page = zcache_frontswap_get_page, - .flush_page = zcache_frontswap_flush_page, - .flush_area = zcache_frontswap_flush_area, + .invalidate_page = zcache_frontswap_flush_page, + .invalidate_area = zcache_frontswap_flush_area, .init = zcache_frontswap_init }; diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c index d369965e8f8..17d9e37beba 100644 --- a/drivers/xen/tmem.c +++ b/drivers/xen/tmem.c @@ -242,9 +242,9 @@ __setup("nocleancache", no_cleancache); static struct cleancache_ops tmem_cleancache_ops = { .put_page = tmem_cleancache_put_page, .get_page = tmem_cleancache_get_page, - .flush_page = tmem_cleancache_flush_page, - .flush_inode = tmem_cleancache_flush_inode, - .flush_fs = tmem_cleancache_flush_fs, + .invalidate_page = tmem_cleancache_flush_page, + .invalidate_inode = tmem_cleancache_flush_inode, + .invalidate_fs = tmem_cleancache_flush_fs, .init_shared_fs = tmem_cleancache_init_shared_fs, .init_fs = tmem_cleancache_init_fs }; @@ -369,8 +369,8 @@ __setup("nofrontswap", no_frontswap); static struct frontswap_ops tmem_frontswap_ops = { .put_page = tmem_frontswap_put_page, .get_page = tmem_frontswap_get_page, - .flush_page = tmem_frontswap_flush_page, - .flush_area = tmem_frontswap_flush_area, + .invalidate_page = tmem_frontswap_flush_page, + .invalidate_area = tmem_frontswap_flush_area, .init = tmem_frontswap_init }; #endif diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h index 66fb63b243a..42e55deee75 100644 --- a/include/linux/cleancache.h +++ b/include/linux/cleancache.h @@ -28,14 +28,9 @@ struct cleancache_ops { pgoff_t, struct page *); void (*put_page)(int, struct cleancache_filekey, pgoff_t, struct page *); - /* - * NOTE: per akpm, flush_page, flush_inode and flush_fs will be - * renamed to invalidate_* in a later commit in which all - * dependencies (i.e Xen, zcache) will be renamed simultaneously - */ - void (*flush_page)(int, struct cleancache_filekey, pgoff_t); - void (*flush_inode)(int, struct cleancache_filekey); - void (*flush_fs)(int); + void (*invalidate_page)(int, struct cleancache_filekey, pgoff_t); + void (*invalidate_inode)(int, struct cleancache_filekey); + void (*invalidate_fs)(int); }; extern struct cleancache_ops diff --git a/mm/cleancache.c b/mm/cleancache.c index 237c6e0feea..b9c198bc698 100644 --- a/mm/cleancache.c +++ b/mm/cleancache.c @@ -161,7 +161,8 @@ void __cleancache_invalidate_page(struct address_space *mapping, if (pool_id >= 0) { VM_BUG_ON(!PageLocked(page)); if (cleancache_get_key(mapping->host, &key) >= 0) { - (*cleancache_ops.flush_page)(pool_id, key, page->index); + (*cleancache_ops.invalidate_page)(pool_id, + key, page->index); cleancache_flushes++; } } @@ -179,7 +180,7 @@ void __cleancache_invalidate_inode(struct address_space *mapping) struct cleancache_filekey key = { .u.key = { 0 } }; if (pool_id >= 0 && cleancache_get_key(mapping->host, &key) >= 0) - (*cleancache_ops.flush_inode)(pool_id, key); + (*cleancache_ops.invalidate_inode)(pool_id, key); } EXPORT_SYMBOL(__cleancache_invalidate_inode); @@ -193,7 +194,7 @@ void __cleancache_invalidate_fs(struct super_block *sb) if (sb->cleancache_poolid >= 0) { int old_poolid = sb->cleancache_poolid; sb->cleancache_poolid = -1; - (*cleancache_ops.flush_fs)(old_poolid); + (*cleancache_ops.invalidate_fs)(old_poolid); } } EXPORT_SYMBOL(__cleancache_invalidate_fs); -- cgit v1.2.3-70-g09d2 From 5fbebcbdb3730666c0d1d22021a90d8483fc8e02 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 Jan 2012 14:07:18 +0900 Subject: sh: intc: Make global intc controller counter static. No need to expose this globally since it's only used for core accounting. Signed-off-by: Paul Mundt --- drivers/sh/intc/core.c | 2 +- drivers/sh/intc/internals.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index e53e449b4ec..c64690dda4a 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -35,7 +35,7 @@ LIST_HEAD(intc_list); DEFINE_RAW_SPINLOCK(intc_big_lock); -unsigned int nr_intc_controllers; +static unsigned int nr_intc_controllers; /* * Default priority level diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index b0e9155ff73..422b72df089 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h @@ -157,7 +157,6 @@ void _intc_enable(struct irq_data *data, unsigned long handle); /* core.c */ extern struct list_head intc_list; extern raw_spinlock_t intc_big_lock; -extern unsigned int nr_intc_controllers; extern struct bus_type intc_subsys; unsigned int intc_get_dfl_prio_level(void); -- cgit v1.2.3-70-g09d2 From 5bbda4e4aca4591c85ee53dea157ca5fc9a23306 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 Jan 2012 14:54:10 +0900 Subject: sh: intc: Prefer IRQCHIP_SKIP_SET_WAKE over a dummy set_wake callback. It's possible to use IRQCHIP_SKIP_SET_WAKE to get the behaviour that we're after, without having to bother with a dummy ->set_wake() callback for the IRQ chip. Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index 7b246efa94e..3679645427c 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -58,11 +58,6 @@ static void intc_disable(struct irq_data *data) } } -static int intc_set_wake(struct irq_data *data, unsigned int on) -{ - return 0; /* allow wakeup, but setup hardware in intc_suspend() */ -} - #ifdef CONFIG_SMP /* * This is held with the irq desc lock held, so we don't require any @@ -225,8 +220,8 @@ struct irq_chip intc_irq_chip = { .irq_disable = intc_disable, .irq_shutdown = intc_disable, .irq_set_type = intc_set_type, - .irq_set_wake = intc_set_wake, #ifdef CONFIG_SMP .irq_set_affinity = intc_set_affinity, #endif + .flags = IRQCHIP_SKIP_SET_WAKE, }; -- cgit v1.2.3-70-g09d2 From 29775df10f02f614db870ff4acaf0b07dbed1547 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 Jan 2012 15:38:57 +0900 Subject: sh: intc: Kill off superfluous irq_shutdown hooking. This already gets handled via disable, as per the notes in linux/irq.h. Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index 3679645427c..d90cb7e4392 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -218,7 +218,6 @@ struct irq_chip intc_irq_chip = { .irq_mask_ack = intc_mask_ack, .irq_enable = intc_enable, .irq_disable = intc_disable, - .irq_shutdown = intc_disable, .irq_set_type = intc_set_type, #ifdef CONFIG_SMP .irq_set_affinity = intc_set_affinity, -- cgit v1.2.3-70-g09d2 From 30377642138aadeef35a31c2f90dba0b6fa7b91a Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 Jan 2012 16:55:57 +0900 Subject: sh: intc: Use IRQ_SET_MASK_OK_NOCOPY for intc_set_affinity. intc_set_affinity() updates the cpumask in place, so there's no need for the upper layer to do this itself. Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index d90cb7e4392..db10adf63dd 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -73,7 +73,7 @@ static int intc_set_affinity(struct irq_data *data, cpumask_copy(data->affinity, cpumask); - return 0; + return IRQ_SET_MASK_OK_NOCOPY; } #endif -- cgit v1.2.3-70-g09d2 From b59f9f9775e643435bba76e30e59e47c19c56dee Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 24 Jan 2012 17:41:55 +0900 Subject: sh: intc: optimize intc IRQ lookup This ensures that the sense/prio lists are sorted at registration time, enabling us to use a simple binary search for an optimized lookup (something that had been on the TODO for some time). Signed-off-by: Paul Mundt --- drivers/sh/intc/chip.c | 27 ++++++--------------------- drivers/sh/intc/core.c | 9 ++++++++- drivers/sh/intc/internals.h | 8 ++++++++ 3 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c index db10adf63dd..012df2676a2 100644 --- a/drivers/sh/intc/chip.c +++ b/drivers/sh/intc/chip.c @@ -2,13 +2,14 @@ * IRQ chip definitions for INTC IRQs. * * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009, 2010 Paul Mundt + * Copyright (C) 2009 - 2012 Paul Mundt * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive * for more details. */ #include +#include #include #include "internals.h" @@ -117,28 +118,12 @@ static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, unsigned int nr_hp, unsigned int irq) { - int i; - - /* - * this doesn't scale well, but... - * - * this function should only be used for cerain uncommon - * operations such as intc_set_priority() and intc_set_type() - * and in those rare cases performance doesn't matter that much. - * keeping the memory footprint low is more important. - * - * one rather simple way to speed this up and still keep the - * memory footprint down is to make sure the array is sorted - * and then perform a bisect to lookup the irq. - */ - for (i = 0; i < nr_hp; i++) { - if ((hp + i)->irq != irq) - continue; + struct intc_handle_int key; - return hp + i; - } + key.irq = irq; + key.handle = 0; - return NULL; + return bsearch(&key, hp, nr_hp, sizeof(*hp), intc_handle_int_cmp); } int intc_set_priority(unsigned int irq, unsigned int prio) diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index c64690dda4a..8e1fcd5e5f0 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -2,7 +2,7 @@ * Shared interrupt handling code for IPR and INTC2 types of IRQs. * * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009, 2010 Paul Mundt + * Copyright (C) 2009 - 2012 Paul Mundt * * Based on intc2.c and ipr.c * @@ -31,6 +31,7 @@ #include #include #include +#include #include "internals.h" LIST_HEAD(intc_list); @@ -267,6 +268,9 @@ int __init register_intc_controller(struct intc_desc *desc) k += save_reg(d, k, hw->prio_regs[i].set_reg, smp); k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp); } + + sort(d->prio, hw->nr_prio_regs, sizeof(*d->prio), + intc_handle_int_cmp, NULL); } if (hw->sense_regs) { @@ -277,6 +281,9 @@ int __init register_intc_controller(struct intc_desc *desc) for (i = 0; i < hw->nr_sense_regs; i++) k += save_reg(d, k, hw->sense_regs[i].reg, 0); + + sort(d->sense, hw->nr_sense_regs, sizeof(*d->sense), + intc_handle_int_cmp, NULL); } if (hw->subgroups) diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index 422b72df089..f034a979a16 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h @@ -108,6 +108,14 @@ static inline void activate_irq(int irq) #endif } +static inline int intc_handle_int_cmp(const void *a, const void *b) +{ + const struct intc_handle_int *_a = a; + const struct intc_handle_int *_b = b; + + return _a->irq - _b->irq; +} + /* access.c */ extern unsigned long (*intc_reg_fns[])(unsigned long addr, unsigned long h, unsigned long data); -- cgit v1.2.3-70-g09d2 From c688419141ad6134d7973fcf182e3719e98d7491 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:56 +0100 Subject: usb: gadget: dummy_hcd: initialize max_streams early While playing with uasp I noticed that it does not work with dummy_hcd. The problem is that uasp requires a stream capable endpoint which it is requesting at bind time like every other gadget. dummy_hcd however initializes the max_stream value after connect once it knows if it runs at SS or not. I don't think that it is might be wrong to initialize the stream capability even at HS speed. The gadget may not use this descriptor at HS speed so it should not cause any damage. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index db815c2da7e..5a21bf5c765 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -800,17 +800,10 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) static void dummy_udc_udpate_ep0(struct dummy *dum) { - u32 i; - - if (dum->gadget.speed == USB_SPEED_SUPER) { - for (i = 0; i < DUMMY_ENDPOINTS; i++) - dum->ep[i].ep.max_streams = 0x10; + if (dum->gadget.speed == USB_SPEED_SUPER) dum->ep[0].ep.maxpacket = 9; - } else { - for (i = 0; i < DUMMY_ENDPOINTS; i++) - dum->ep[i].ep.max_streams = 0; + else dum->ep[0].ep.maxpacket = 64; - } } static int dummy_pullup (struct usb_gadget *_gadget, int value) @@ -954,6 +947,7 @@ static void init_dummy_udc_hw(struct dummy *dum) ep->halted = ep->wedged = ep->already_seen = ep->setup_stage = 0; ep->ep.maxpacket = ~0; + ep->ep.max_streams = 16; ep->last_io = jiffies; ep->gadget = &dum->gadget; ep->desc = NULL; -- cgit v1.2.3-70-g09d2 From a04ce20d9f5e9484ed3879e1290bd05933cbbe2a Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:57 +0100 Subject: usb: gadget: dummy_hcd: move the transfer part into its own function This patch moves the part of the code which does the bare transfer into its function. It is a preparion for the implementation of sg support. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 5a21bf5c765..61e893ac254 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -1133,6 +1133,23 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) return rc; } +static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, + u32 len) +{ + void *ubuf, *rbuf; + int to_host; + + to_host = usb_pipein(urb->pipe); + rbuf = req->req.buf + req->req.actual; + ubuf = urb->transfer_buffer + urb->actual_length; + + if (to_host) + memcpy(ubuf, rbuf, len); + else + memcpy(rbuf, ubuf, len); + return len; +} + /* transfer up to a frame's worth; caller must own lock */ static int transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, @@ -1164,8 +1181,6 @@ top: if (unlikely (len == 0)) is_short = 1; else { - char *ubuf, *rbuf; - /* not enough bandwidth left? */ if (limit < ep->ep.maxpacket && limit < len) break; @@ -1180,13 +1195,8 @@ top: } is_short = (len % ep->ep.maxpacket) != 0; - /* else transfer packet(s) */ - ubuf = urb->transfer_buffer + urb->actual_length; - rbuf = req->req.buf + req->req.actual; - if (to_host) - memcpy (ubuf, rbuf, len); - else - memcpy (rbuf, ubuf, len); + len = dummy_perform_transfer(urb, req, len); + ep->last_io = jiffies; limit -= len; -- cgit v1.2.3-70-g09d2 From 14fce33a960afbcf91ef97135903092c33f6d076 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 19:30:50 +0100 Subject: usb: gadget: dummy_hcd: add sg support This patch adds sg support to dummy_hcd. It seems that uas is not able to work with a hcd which does not support sg only based transfers. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 80 +++++++++++++++++++++++++++++++++++------- 1 file changed, 67 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 61e893ac254..4973778b778 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,8 @@ static const char *const ep_name [] = { struct urbp { struct urb *urb; struct list_head urbp_list; + struct sg_mapping_iter miter; + u32 miter_started; }; @@ -1077,13 +1080,11 @@ static int dummy_urb_enqueue ( unsigned long flags; int rc; - if (!urb->transfer_buffer && urb->transfer_buffer_length) - return -EINVAL; - urbp = kmalloc (sizeof *urbp, mem_flags); if (!urbp) return -ENOMEM; urbp->urb = urb; + urbp->miter_started = 0; dum_hcd = hcd_to_dummy_hcd(hcd); spin_lock_irqsave(&dum_hcd->dum->lock, flags); @@ -1137,17 +1138,66 @@ static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, u32 len) { void *ubuf, *rbuf; + struct urbp *urbp = urb->hcpriv; int to_host; + struct sg_mapping_iter *miter = &urbp->miter; + u32 trans = 0; + u32 this_sg; + bool next_sg; to_host = usb_pipein(urb->pipe); rbuf = req->req.buf + req->req.actual; - ubuf = urb->transfer_buffer + urb->actual_length; - if (to_host) - memcpy(ubuf, rbuf, len); - else - memcpy(rbuf, ubuf, len); - return len; + if (!urb->num_sgs) { + ubuf = urb->transfer_buffer + urb->actual_length; + if (to_host) + memcpy(ubuf, rbuf, len); + else + memcpy(rbuf, ubuf, len); + return len; + } + + if (!urbp->miter_started) { + u32 flags = SG_MITER_ATOMIC; + + if (to_host) + flags |= SG_MITER_TO_SG; + else + flags |= SG_MITER_FROM_SG; + + sg_miter_start(miter, urb->sg, urb->num_sgs, flags); + urbp->miter_started = 1; + } + next_sg = sg_miter_next(miter); + if (next_sg == false) { + WARN_ON_ONCE(1); + return -EINVAL; + } + do { + ubuf = miter->addr; + this_sg = min_t(u32, len, miter->length); + miter->consumed = this_sg; + trans += this_sg; + + if (to_host) + memcpy(ubuf, rbuf, this_sg); + else + memcpy(rbuf, ubuf, this_sg); + len -= this_sg; + + if (!len) + break; + next_sg = sg_miter_next(miter); + if (next_sg == false) { + WARN_ON_ONCE(1); + return -EINVAL; + } + + rbuf += this_sg; + } while (1); + + sg_miter_stop(miter); + return trans; } /* transfer up to a frame's worth; caller must own lock */ @@ -1198,10 +1248,13 @@ top: len = dummy_perform_transfer(urb, req, len); ep->last_io = jiffies; - - limit -= len; - urb->actual_length += len; - req->req.actual += len; + if (len < 0) { + req->req.status = len; + } else { + limit -= len; + urb->actual_length += len; + req->req.actual += len; + } } /* short packets terminate, maybe with overflow/underflow. @@ -2212,6 +2265,7 @@ static int dummy_h_get_frame (struct usb_hcd *hcd) static int dummy_setup(struct usb_hcd *hcd) { + hcd->self.sg_tablesize = ~0; if (usb_hcd_is_primary_hcd(hcd)) { the_controller.hs_hcd = hcd_to_dummy_hcd(hcd); the_controller.hs_hcd->dum = &the_controller; -- cgit v1.2.3-70-g09d2 From d262127c330b852ce4b210a0b1b06e69d4d87704 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:14:59 +0100 Subject: usb: gadget: dummy_hcd: rename dummy_udc_udpate_ep0() to dummy_udc_update_ep0() This renames a function so "update" is spelled properly. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 4973778b778..a40dc6a4c9e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -801,7 +801,7 @@ static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) return 0; } -static void dummy_udc_udpate_ep0(struct dummy *dum) +static void dummy_udc_update_ep0(struct dummy *dum) { if (dum->gadget.speed == USB_SPEED_SUPER) dum->ep[0].ep.maxpacket = 9; @@ -825,7 +825,7 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) dum->driver->max_speed); else dum->gadget.speed = USB_SPEED_FULL; - dummy_udc_udpate_ep0(dum); + dummy_udc_update_ep0(dum); if (dum->gadget.speed < dum->driver->max_speed) dev_dbg(udc_dev(dum), "This device can perform faster" -- cgit v1.2.3-70-g09d2 From d81f3e4f5792acab5929ef99aad6ca5e21a31a0e Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 9 Jan 2012 13:15:00 +0100 Subject: usb: gadget: dummy_hcd: make alloc/free streams static There is no reason why dummy_alloc_streams() and dummy_free_streams() are global. Make them static instead. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index a40dc6a4c9e..626473238b3 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -2286,7 +2286,7 @@ static int dummy_setup(struct usb_hcd *hcd) } /* Change a group of bulk endpoints to support multiple stream IDs */ -int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, +static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, unsigned int num_streams, gfp_t mem_flags) { @@ -2298,7 +2298,7 @@ int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, } /* Reverts a group of bulk endpoints back to not using stream IDs. */ -int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, +static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags) { -- cgit v1.2.3-70-g09d2 From 10800f2ca1a78e24cf92dc5e16a68a9b78f91bbe Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 4 Jan 2012 10:20:09 +0300 Subject: usb: gadget: mv_udc: remove unneeded NULL check We've dereferenced req already, and we checked for bogus parameters at the start of the function. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/mv_udc_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index f97e737d26f..8dd398b99e2 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c @@ -771,8 +771,7 @@ mv_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) udc->ep0_state = DATA_STATE_XMIT; /* irq handler advances the queue */ - if (req != NULL) - list_add_tail(&req->queue, &ep->queue); + list_add_tail(&req->queue, &ep->queue); spin_unlock_irqrestore(&udc->lock, flags); return 0; -- cgit v1.2.3-70-g09d2 From 53069af3fa8ba2849cd4785160690873995d4f39 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 5 Jan 2012 15:37:18 +0900 Subject: usb: renesas_usbhs: add IRQ resource decoding for IRQF_SHARED In case of the SH7757, the irq number of USB module and SUDMAC are the same. So, we have to set the IRQF_SHARED in such a case. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/common.c | 11 ++++++----- drivers/usb/renesas_usbhs/common.h | 1 + drivers/usb/renesas_usbhs/mod.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index e9a5b1d2615..a165490bae4 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c @@ -413,8 +413,7 @@ static int usbhs_probe(struct platform_device *pdev) struct renesas_usbhs_platform_info *info = pdev->dev.platform_data; struct renesas_usbhs_driver_callback *dfunc; struct usbhs_priv *priv; - struct resource *res; - unsigned int irq; + struct resource *res, *irq_res; int ret; /* check platform information */ @@ -426,8 +425,8 @@ static int usbhs_probe(struct platform_device *pdev) /* platform data */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - irq = platform_get_irq(pdev, 0); - if (!res || (int)irq <= 0) { + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res || !irq_res) { dev_err(&pdev->dev, "Not enough Renesas USB platform resources.\n"); return -ENODEV; } @@ -476,7 +475,9 @@ static int usbhs_probe(struct platform_device *pdev) /* * priv settings */ - priv->irq = irq; + priv->irq = irq_res->start; + if (irq_res->flags & IORESOURCE_IRQ_SHAREABLE) + priv->irqflags = IRQF_SHARED; priv->pdev = pdev; INIT_DELAYED_WORK(&priv->notify_hotplug_work, usbhsc_notify_hotplug); spin_lock_init(usbhs_priv_to_lock(priv)); diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index d79b3e27db9..3f3ccd35875 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h @@ -242,6 +242,7 @@ struct usbhs_priv { void __iomem *base; unsigned int irq; + unsigned long irqflags; struct renesas_usbhs_platform_callback pfunc; struct renesas_usbhs_driver_param dparam; diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 1b97fb12694..0871e816df4 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -152,7 +152,7 @@ int usbhs_mod_probe(struct usbhs_priv *priv) /* irq settings */ ret = request_irq(priv->irq, usbhs_interrupt, - 0, dev_name(dev), priv); + priv->irqflags, dev_name(dev), priv); if (ret) { dev_err(dev, "irq request err\n"); goto mod_init_gadget_err; -- cgit v1.2.3-70-g09d2 From 5ea4399457f730b4614d0632ceefd3e8f53fb1e6 Mon Sep 17 00:00:00 2001 From: "Shimoda, Yoshihiro" Date: Thu, 5 Jan 2012 15:37:22 +0900 Subject: usb: renesas_usbhs: add support for SUDMAC The SUDMAC uses 8-bit width only. So, when the driver uses SUDMAC, we have to clear the MBW_32. Signed-off-by: Yoshihiro Shimoda Signed-off-by: Felipe Balbi --- drivers/usb/renesas_usbhs/fifo.c | 6 +++++- include/linux/usb/renesas_usbhs.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 72339bd6fca..03a9cc529c8 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -23,6 +23,7 @@ #define usbhsf_get_cfifo(p) (&((p)->fifo_info.cfifo)) #define usbhsf_get_d0fifo(p) (&((p)->fifo_info.d0fifo)) #define usbhsf_get_d1fifo(p) (&((p)->fifo_info.d1fifo)) +#define usbhsf_is_cfifo(p, f) (usbhsf_get_cfifo(p) == f) #define usbhsf_fifo_is_busy(f) ((f)->pipe) /* see usbhs_pipe_select_fifo */ @@ -305,7 +306,10 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, } /* "base" will be used below */ - usbhs_write(priv, fifo->sel, base | MBW_32); + if (usbhs_get_dparam(priv, has_sudmac) && !usbhsf_is_cfifo(priv, fifo)) + usbhs_write(priv, fifo->sel, base); + else + usbhs_write(priv, fifo->sel, base | MBW_32); /* check ISEL and CURPIPE value */ while (timeout--) { diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index 0d3f9887925..547e59cc00e 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h @@ -149,6 +149,7 @@ struct renesas_usbhs_driver_param { * option: */ u32 has_otg:1; /* for controlling PWEN/EXTLP */ + u32 has_sudmac:1; /* for SUDMAC */ }; /* -- cgit v1.2.3-70-g09d2 From 2d4172c938745cfa51c4a91406efb584549c1024 Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sun, 8 Jan 2012 21:57:55 +0100 Subject: usb: s3c-hsudc: Use helper functions instead of generic container_of The helper functions were definied but never used until now. Signed-off-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index df8661d266c..41b3a583c1a 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -759,7 +759,7 @@ static int s3c_hsudc_ep_enable(struct usb_ep *_ep, unsigned long flags; u32 ecr = 0; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); if (!_ep || !desc || hsep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT || hsep->bEndpointAddress != desc->bEndpointAddress @@ -853,7 +853,7 @@ static void s3c_hsudc_free_request(struct usb_ep *ep, struct usb_request *_req) { struct s3c_hsudc_req *hsreq; - hsreq = container_of(_req, struct s3c_hsudc_req, req); + hsreq = our_req(_req); WARN_ON(!list_empty(&hsreq->queue)); kfree(hsreq); } @@ -876,12 +876,12 @@ static int s3c_hsudc_queue(struct usb_ep *_ep, struct usb_request *_req, u32 offset; u32 csr; - hsreq = container_of(_req, struct s3c_hsudc_req, req); + hsreq = our_req(_req); if ((!_req || !_req->complete || !_req->buf || !list_empty(&hsreq->queue))) return -EINVAL; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); hsudc = hsep->dev; if (!hsudc->driver || hsudc->gadget.speed == USB_SPEED_UNKNOWN) return -ESHUTDOWN; @@ -935,7 +935,7 @@ static int s3c_hsudc_dequeue(struct usb_ep *_ep, struct usb_request *_req) struct s3c_hsudc_req *hsreq; unsigned long flags; - hsep = container_of(_ep, struct s3c_hsudc_ep, ep); + hsep = our_ep(_ep); if (!_ep || hsep->ep.name == ep0name) return -EINVAL; -- cgit v1.2.3-70-g09d2 From 294f78ec493e69b55bcba566d4fe264d041aba8d Mon Sep 17 00:00:00 2001 From: Heiko Stübner Date: Sun, 8 Jan 2012 21:58:28 +0100 Subject: usb: s3c-hsudc: add basic runtime_pm calls This will enable the system to check for activity of the usb gadget and also in a later patch to control the usbphy power-domain. When handling the power domain there, it will be possible to remove another reference to architecture code. Signed-off-by: Heiko Stuebner Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c-hsudc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 41b3a583c1a..5e8729374fb 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c @@ -30,6 +30,7 @@ #include #include #include +#include #include @@ -1178,6 +1179,9 @@ static int s3c_hsudc_start(struct usb_gadget *gadget, dev_info(hsudc->dev, "bound driver %s\n", driver->driver.name); s3c_hsudc_reconfig(hsudc); + + pm_runtime_get_sync(hsudc->dev); + s3c_hsudc_init_phy(); if (hsudc->pd->gpio_init) hsudc->pd->gpio_init(); @@ -1208,6 +1212,9 @@ static int s3c_hsudc_stop(struct usb_gadget *gadget, hsudc->gadget.dev.driver = NULL; hsudc->gadget.speed = USB_SPEED_UNKNOWN; s3c_hsudc_uninit_phy(); + + pm_runtime_put(hsudc->dev); + if (hsudc->pd->gpio_uninit) hsudc->pd->gpio_uninit(); s3c_hsudc_stop_activity(hsudc); @@ -1362,6 +1369,8 @@ static int __devinit s3c_hsudc_probe(struct platform_device *pdev) if (ret) goto err_add_udc; + pm_runtime_enable(dev); + return 0; err_add_udc: device_unregister(&hsudc->gadget.dev); -- cgit v1.2.3-70-g09d2 From c50a3bff0edb0acd49d8033a12ea4668e09a31ad Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:05 +0900 Subject: usb: gadget: pch_udc: Fix disconnect issue ISSUE: When the driver notifies a gadget of a disconnect event, a system rarely freezes. CAUSE: When the driver calls dev->driver->disconnect(), it is not calling spin_unlock(). Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index a3fcaae4bc2..6a44c921d13 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2335,8 +2335,11 @@ static void pch_udc_svc_ur_interrupt(struct pch_udc_dev *dev) /* Complete request queue */ empty_req_queue(ep); } - if (dev->driver && dev->driver->disconnect) + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } } /** -- cgit v1.2.3-70-g09d2 From c802672cd36cd063bfd54d54c8c34825ab5b2357 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:06 +0900 Subject: usb: gadget: pch_udc: Fix wrong return value ISSUE: If the return value of pch_udc_pcd_init() is False, the return value of this function is unsettled. Since pch_udc_pcd_init() always returns 0, there is not actually the issue. CAUSE: If pch_udc_pcd_init() is True, the variable, retval, is not set for an appropriate value. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 6a44c921d13..96606b6cff4 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2915,8 +2915,10 @@ static int pch_udc_probe(struct pci_dev *pdev, } pch_udc = dev; /* initialize the hardware */ - if (pch_udc_pcd_init(dev)) + if (pch_udc_pcd_init(dev)) { + retval = -ENODEV; goto finished; + } if (request_irq(pdev->irq, pch_udc_isr, IRQF_SHARED, KBUILD_MODNAME, dev)) { dev_err(&pdev->dev, "%s: request_irq(%d) fail\n", __func__, -- cgit v1.2.3-70-g09d2 From 84566abba058b2aae8d603dfa90b5a3778a6714f Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:07 +0900 Subject: usb: gadget: pch_udc: Fix USB suspend issue ISSUE: After USB Suspend, a system rarely freezes. CAUSE: When USB Suspend occurred, the driver is not notifying a gadget of the event. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 96606b6cff4..842ca6349a9 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2475,8 +2475,15 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) if (dev_intr & UDC_DEVINT_SC) pch_udc_svc_cfg_interrupt(dev); /* USB Suspend interrupt */ - if (dev_intr & UDC_DEVINT_US) + if (dev_intr & UDC_DEVINT_US) { + if (dev->driver + && dev->driver->suspend) { + spin_unlock(&dev->lock); + dev->driver->suspend(&dev->gadget); + spin_lock(&dev->lock); + } dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); + } /* Clear the SOF interrupt, if enabled */ if (dev_intr & UDC_DEVINT_SOF) dev_dbg(&dev->pdev->dev, "SOF\n"); -- cgit v1.2.3-70-g09d2 From 1c575d2d2e3ff2a7cb3c2e2165064199cfd8ad32 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:08 +0900 Subject: usb: gadget: pch_udc: Fix usb/gadget/pch_udc: Fix ether gadget connect/disconnect issue ISSUE: After a USB cable is connect/disconnected, the system rarely freezes. CAUSE: Since the USB device controller cannot know to disconnect the USB cable, when it is used without detecting VBUS by GPIO, the UDC driver does not notify to USB Gadget. Since USB Gadget cannot know to disconnect, a false setting occurred when the USB cable is connected/disconnect repeatedly. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 70 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 842ca6349a9..c2f19752c07 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -311,6 +311,7 @@ struct pch_udc_ep { * @registered: driver regsitered with system * @suspended: driver in suspended state * @connected: gadget driver associated + * @vbus_session: required vbus_session state * @set_cfg_not_acked: pending acknowledgement 4 setup * @waiting_zlp_ack: pending acknowledgement 4 ZLP * @data_requests: DMA pool for data requests @@ -337,6 +338,7 @@ struct pch_udc_dev { registered:1, suspended:1, connected:1, + vbus_session:1, set_cfg_not_acked:1, waiting_zlp_ack:1; struct pci_pool *data_requests; @@ -553,6 +555,31 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); } +/** + * pch_udc_reconnect() - This API initializes usb device controller, + * and clear the disconnect status. + * @dev: Reference to pch_udc_regs structure + */ +static void pch_udc_init(struct pch_udc_dev *dev); +static void pch_udc_reconnect(struct pch_udc_dev *dev) +{ + pch_udc_init(dev); + + /* enable device interrupts */ + /* pch_udc_enable_interrupts() */ + pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, + UDC_DEVINT_UR | UDC_DEVINT_US | + UDC_DEVINT_ENUM | + UDC_DEVINT_SI | UDC_DEVINT_SC); + + /* Clear the disconnect */ + pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); + pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_SD); + mdelay(1); + /* Resume USB signalling */ + pch_udc_bit_clr(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); +} + /** * pch_udc_vbus_session() - set or clearr the disconnect status. * @dev: Reference to pch_udc_regs structure @@ -563,10 +590,18 @@ static void pch_udc_clear_disconnect(struct pch_udc_dev *dev) static inline void pch_udc_vbus_session(struct pch_udc_dev *dev, int is_active) { - if (is_active) - pch_udc_clear_disconnect(dev); - else + if (is_active) { + pch_udc_reconnect(dev); + dev->vbus_session = 1; + } else { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } pch_udc_set_disconnect(dev); + dev->vbus_session = 0; + } } /** @@ -1126,7 +1161,17 @@ static int pch_udc_pcd_pullup(struct usb_gadget *gadget, int is_on) if (!gadget) return -EINVAL; dev = container_of(gadget, struct pch_udc_dev, gadget); - pch_udc_vbus_session(dev, is_on); + if (is_on) { + pch_udc_reconnect(dev); + } else { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + pch_udc_set_disconnect(dev); + } + return 0; } @@ -2482,6 +2527,15 @@ static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) dev->driver->suspend(&dev->gadget); spin_lock(&dev->lock); } + + if (dev->vbus_session == 0) { + if (dev->driver && dev->driver->disconnect) { + spin_unlock(&dev->lock); + dev->driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + pch_udc_reconnect(dev); + } dev_dbg(&dev->pdev->dev, "USB_SUSPEND\n"); } /* Clear the SOF interrupt, if enabled */ @@ -2509,6 +2563,14 @@ static irqreturn_t pch_udc_isr(int irq, void *pdev) dev_intr = pch_udc_read_device_interrupts(dev); ep_intr = pch_udc_read_ep_interrupts(dev); + /* For a hot plug, this find that the controller is hung up. */ + if (dev_intr == ep_intr) + if (dev_intr == pch_udc_readl(dev, UDC_DEVCFG_ADDR)) { + dev_dbg(&dev->pdev->dev, "UDC: Hung up\n"); + /* The controller is reset */ + pch_udc_writel(dev, UDC_SRST, UDC_SRST_ADDR); + return IRQ_HANDLED; + } if (dev_intr) /* Clear device interrupts */ pch_udc_write_device_interrupts(dev, dev_intr); -- cgit v1.2.3-70-g09d2 From 833310402c54ad9b676b465fc53ad276b13d36be Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:09 +0900 Subject: usb: gadget: pch_udc: Reduce redundant interrupt ISSUE: USB Suspend interrupts occur frequently. CAUSE: When it is called pch_udc_reconnect() in USB Suspend, it repeats reset and Suspend. SOLUTION: pch_udc_reconnect() does not enable all interrupts. When an enumeration event occurred the driver enables all interrupts. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index c2f19752c07..4da98141e05 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -568,9 +568,7 @@ static void pch_udc_reconnect(struct pch_udc_dev *dev) /* enable device interrupts */ /* pch_udc_enable_interrupts() */ pch_udc_bit_clr(dev, UDC_DEVIRQMSK_ADDR, - UDC_DEVINT_UR | UDC_DEVINT_US | - UDC_DEVINT_ENUM | - UDC_DEVINT_SI | UDC_DEVINT_SC); + UDC_DEVINT_UR | UDC_DEVINT_ENUM); /* Clear the disconnect */ pch_udc_bit_set(dev, UDC_DEVCTL_ADDR, UDC_DEVCTL_RES); @@ -2419,6 +2417,11 @@ static void pch_udc_svc_enum_interrupt(struct pch_udc_dev *dev) pch_udc_set_dma(dev, DMA_DIR_TX); pch_udc_set_dma(dev, DMA_DIR_RX); pch_udc_ep_set_rrdy(&(dev->ep[UDC_EP0OUT_IDX])); + + /* enable device interrupts */ + pch_udc_enable_interrupts(dev, UDC_DEVINT_UR | UDC_DEVINT_US | + UDC_DEVINT_ES | UDC_DEVINT_ENUM | + UDC_DEVINT_SI | UDC_DEVINT_SC); } /** -- cgit v1.2.3-70-g09d2 From 9645f7d3dab346a9d442dca1688740551b8c55f2 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Thu, 12 Jan 2012 11:27:10 +0900 Subject: usb: gadget: pch_udc: Add debug message ISSUE: Adding debugging messages. CAUSE: The debugging messages are added to make sure of that major interrupt events are occurring. Signed-off-by: Tomoya MORINAGA Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pch_udc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 4da98141e05..82416aae816 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c @@ -2511,11 +2511,15 @@ static void pch_udc_svc_cfg_interrupt(struct pch_udc_dev *dev) static void pch_udc_dev_isr(struct pch_udc_dev *dev, u32 dev_intr) { /* USB Reset Interrupt */ - if (dev_intr & UDC_DEVINT_UR) + if (dev_intr & UDC_DEVINT_UR) { pch_udc_svc_ur_interrupt(dev); + dev_dbg(&dev->pdev->dev, "USB_RESET\n"); + } /* Enumeration Done Interrupt */ - if (dev_intr & UDC_DEVINT_ENUM) + if (dev_intr & UDC_DEVINT_ENUM) { pch_udc_svc_enum_interrupt(dev); + dev_dbg(&dev->pdev->dev, "USB_ENUM\n"); + } /* Set Interface Interrupt */ if (dev_intr & UDC_DEVINT_SI) pch_udc_svc_intf_interrupt(dev); -- cgit v1.2.3-70-g09d2 From a54c979fed31b4230b2e63132f7167206e4e5d69 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 21:51:47 +0100 Subject: usb: gadget: dummy_hcd: complete stream support dummy_hcd provides (alloc|free)_stream() callbacks but there are not doing anything. The transfer side also lacks matching of streams. This patch changes this and implements stream allocation / de-allocation support and proper urb <=> req matching. The UDC side exposes a limit of 16 streams. DWC3, the only USB3 UDC has no limitations in this regard except that it _needs_ to know that streams will be used at the ep_enable time. At the host side, there is no real limit either: XHCI can allocate any number of streams as long as it does not run out of memory. The UAS gadget currently requests 16 streams and the UAS host side fallbacks from the requested 256 down to 16 which is fine. From the UASP point of view (the only specified user), the number of used streams does not really matter. The only limitation is that the host may not use a higher stream than the gadget requested and can deal with. The dummy stream support has been modelled after current UAS + XHCI + DWC3 + UASP usage which helps me testing: - the device announces that each ep supports 16 streams (even it could more than that). - the device side looks into Companion descriptor at ep_enable time and enables them according to it. - the host side tries to enable the requested number of streams but the upper limit is the Comanion descriptor. None (zero streams) is an error condition, less is okay. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 197 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 181 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 626473238b3..e57989ccc0e 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -88,6 +88,7 @@ struct dummy_ep { unsigned wedged : 1; unsigned already_seen : 1; unsigned setup_stage : 1; + unsigned stream_en:1; }; struct dummy_request { @@ -169,6 +170,8 @@ struct dummy_hcd { struct usb_device *udev; struct list_head urbp_list; + u32 stream_en_ep; + u8 num_stream[30 / 2]; unsigned active:1; unsigned old_active:1; @@ -514,8 +517,16 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) _ep->maxpacket = max; ep->desc = desc; + if (usb_ss_max_streams(_ep->comp_desc)) { + if (!usb_endpoint_xfer_bulk(desc)) { + dev_err(udc_dev(dum), "Can't enable stream support on " + "non-bulk ep %s\n", _ep->name); + return -EINVAL; + } + ep->stream_en = 1; + } - dev_dbg (udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d\n", + dev_dbg(udc_dev(dum), "enabled %s (ep%d%s-%s) maxpacket %d stream %s\n", _ep->name, desc->bEndpointAddress & 0x0f, (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", @@ -534,7 +545,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) val = "ctrl"; break; }; val; }), - max); + max, ep->stream_en ? "enabled" : "disabled"); /* at this point real hardware should be NAKing transfers * to that endpoint, until a buffer is queued to it. @@ -559,6 +570,7 @@ static int dummy_disable (struct usb_ep *_ep) spin_lock_irqsave (&dum->lock, flags); ep->desc = NULL; + ep->stream_en = 0; retval = 0; nuke (dum, ep); spin_unlock_irqrestore (&dum->lock, flags); @@ -1058,6 +1070,16 @@ static struct platform_driver dummy_udc_driver = { /*-------------------------------------------------------------------------*/ +static unsigned int dummy_get_ep_idx(const struct usb_endpoint_descriptor *desc) +{ + unsigned int index; + + index = usb_endpoint_num(desc) << 1; + if (usb_endpoint_dir_in(desc)) + index |= 1; + return index; +} + /* MASTER/HOST SIDE DRIVER * * this uses the hcd framework to hook up to host side drivers. @@ -1070,6 +1092,81 @@ static struct platform_driver dummy_udc_driver = { * usb 2.0 rules. */ +static int dummy_ep_stream_en(struct dummy_hcd *dum_hcd, struct urb *urb) +{ + const struct usb_endpoint_descriptor *desc = &urb->ep->desc; + u32 index; + + if (!usb_endpoint_xfer_bulk(desc)) + return 0; + + index = dummy_get_ep_idx(desc); + return (1 << index) & dum_hcd->stream_en_ep; +} + +/* + * The max stream number is saved as a nibble so for the 30 possible endpoints + * we only 15 bytes of memory. Therefore we are limited to max 16 streams (0 + * means we use only 1 stream). The maximum according to the spec is 16bit so + * if the 16 stream limit is about to go, the array size should be incremented + * to 30 elements of type u16. + */ +static int get_max_streams_for_pipe(struct dummy_hcd *dum_hcd, + unsigned int pipe) +{ + int max_streams; + + max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; + if (usb_pipeout(pipe)) + max_streams >>= 4; + else + max_streams &= 0xf; + max_streams++; + return max_streams; +} + +static void set_max_streams_for_pipe(struct dummy_hcd *dum_hcd, + unsigned int pipe, unsigned int streams) +{ + int max_streams; + + streams--; + max_streams = dum_hcd->num_stream[usb_pipeendpoint(pipe)]; + if (usb_pipeout(pipe)) { + streams <<= 4; + max_streams &= 0xf; + } else { + max_streams &= 0xf0; + } + max_streams |= streams; + dum_hcd->num_stream[usb_pipeendpoint(pipe)] = max_streams; +} + +static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb) +{ + unsigned int max_streams; + int enabled; + + enabled = dummy_ep_stream_en(dum_hcd, urb); + if (!urb->stream_id) { + if (enabled) + return -EINVAL; + return 0; + } + if (!enabled) + return -EINVAL; + + max_streams = get_max_streams_for_pipe(dum_hcd, + usb_pipeendpoint(urb->pipe)); + if (urb->stream_id > max_streams) { + dev_err(dummy_dev(dum_hcd), "Stream id %d is out of range.\n", + urb->stream_id); + BUG(); + return -EINVAL; + } + return 0; +} + static int dummy_urb_enqueue ( struct usb_hcd *hcd, struct urb *urb, @@ -1088,6 +1185,13 @@ static int dummy_urb_enqueue ( dum_hcd = hcd_to_dummy_hcd(hcd); spin_lock_irqsave(&dum_hcd->dum->lock, flags); + + rc = dummy_validate_stream(dum_hcd, urb); + if (rc) { + kfree(urbp); + goto done; + } + rc = usb_hcd_link_urb_to_ep(hcd, urb); if (rc) { kfree(urbp); @@ -1201,10 +1305,10 @@ static int dummy_perform_transfer(struct urb *urb, struct dummy_request *req, } /* transfer up to a frame's worth; caller must own lock */ -static int -transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, - int *status) +static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb, + struct dummy_ep *ep, int limit, int *status) { + struct dummy *dum = dum_hcd->dum; struct dummy_request *req; top: @@ -1214,6 +1318,11 @@ top: int is_short, to_host; int rescan = 0; + if (dummy_ep_stream_en(dum_hcd, urb)) { + if ((urb->stream_id != req->req.stream_id)) + continue; + } + /* 1..N packets of ep->ep.maxpacket each ... the last one * may be short (including zero length). * @@ -1744,7 +1853,7 @@ restart: default: treat_control_like_bulk: ep->last_io = jiffies; - total = transfer(dum, urb, ep, limit, &status); + total = transfer(dum_hcd, urb, ep, limit, &status); break; } @@ -2201,6 +2310,7 @@ static int dummy_start_ss(struct dummy_hcd *dum_hcd) dum_hcd->timer.function = dummy_timer; dum_hcd->timer.data = (unsigned long)dum_hcd; dum_hcd->rh_state = DUMMY_RH_RUNNING; + dum_hcd->stream_en_ep = 0; INIT_LIST_HEAD(&dum_hcd->urbp_list); dummy_hcd_to_hcd(dum_hcd)->power_budget = POWER_BUDGET; dummy_hcd_to_hcd(dum_hcd)->state = HC_STATE_RUNNING; @@ -2290,11 +2400,46 @@ static int dummy_alloc_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, unsigned int num_streams, gfp_t mem_flags) { - if (hcd->speed != HCD_USB3) - dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), - "%s() - ERROR! Not supported for USB2.0 roothub\n", - __func__); - return 0; + struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); + unsigned long flags; + int max_stream; + int ret_streams = num_streams; + unsigned int index; + unsigned int i; + + if (!num_eps) + return -EINVAL; + + spin_lock_irqsave(&dum_hcd->dum->lock, flags); + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + if ((1 << index) & dum_hcd->stream_en_ep) { + ret_streams = -EINVAL; + goto out; + } + max_stream = usb_ss_max_streams(&eps[i]->ss_ep_comp); + if (!max_stream) { + ret_streams = -EINVAL; + goto out; + } + if (max_stream < ret_streams) { + dev_dbg(dummy_dev(dum_hcd), "Ep 0x%x only supports %u " + "stream IDs.\n", + eps[i]->desc.bEndpointAddress, + max_stream); + ret_streams = max_stream; + } + } + + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + dum_hcd->stream_en_ep |= 1 << index; + set_max_streams_for_pipe(dum_hcd, + usb_endpoint_num(&eps[i]->desc), ret_streams); + } +out: + spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); + return ret_streams; } /* Reverts a group of bulk endpoints back to not using stream IDs. */ @@ -2302,11 +2447,31 @@ static int dummy_free_streams(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint **eps, unsigned int num_eps, gfp_t mem_flags) { - if (hcd->speed != HCD_USB3) - dev_dbg(dummy_dev(hcd_to_dummy_hcd(hcd)), - "%s() - ERROR! Not supported for USB2.0 roothub\n", - __func__); - return 0; + struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); + unsigned long flags; + int ret; + unsigned int index; + unsigned int i; + + spin_lock_irqsave(&dum_hcd->dum->lock, flags); + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + if (!((1 << index) & dum_hcd->stream_en_ep)) { + ret = -EINVAL; + goto out; + } + } + + for (i = 0; i < num_eps; i++) { + index = dummy_get_ep_idx(&eps[i]->desc); + dum_hcd->stream_en_ep &= ~(1 << index); + set_max_streams_for_pipe(dum_hcd, + usb_endpoint_num(&eps[i]->desc), 0); + } + ret = 0; +out: + spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); + return ret; } static struct hc_driver dummy_hcd = { -- cgit v1.2.3-70-g09d2 From 59f08e6d2015a16fb4856f910ef0660d13a0c767 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Jan 2012 12:53:14 +0100 Subject: usb: dummy_hcd: use usb_endpoint_type() This patch makes use of usb_endpoint_type() instead of the open coding. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index e57989ccc0e..fd4d86a5714 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -447,7 +447,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) * especially for "ep9out" style fixed function ones.) */ retval = -EINVAL; - switch (desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: if (strstr (ep->ep.name, "-iso") || strstr (ep->ep.name, "-int")) { @@ -531,7 +531,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) desc->bEndpointAddress & 0x0f, (desc->bEndpointAddress & USB_DIR_IN) ? "in" : "out", ({ char *val; - switch (desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: val = "bulk"; break; @@ -1439,7 +1439,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) limit += limit * tmp; } if (dum->gadget.speed == USB_SPEED_SUPER) { - switch (ep->desc->bmAttributes & 0x03) { + switch (usb_endpoint_type(ep->desc)) { case USB_ENDPOINT_XFER_ISOC: /* Sec. 4.4.8.2 USB3.0 Spec */ limit = 3 * 16 * 1024 * 8; -- cgit v1.2.3-70-g09d2 From 18f2cbaa2b9617eed20789ce40878920a8ea6beb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Thu, 12 Jan 2012 12:53:15 +0100 Subject: usb: gadget: dummy_hcd: clean up checkpatch This patch converts checkpatch output of |./scripts/checkpatch.pl drivers/usb/gadget/dummy_hcd.c -file from |total: 22 errors, 174 warnings, 2642 lines checked to |total: 0 errors, 0 warnings, 2632 lines checked Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Felipe Balbi --- drivers/usb/gadget/dummy_hcd.c | 432 ++++++++++++++++++++--------------------- 1 file changed, 211 insertions(+), 221 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index fd4d86a5714..67573e5f2a1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -42,25 +42,24 @@ #include #include -#include +#include #include #include #include - #define DRIVER_DESC "USB Host+Gadget Emulator" #define DRIVER_VERSION "02 May 2005" #define POWER_BUDGET 500 /* in mA; use 8 for low-power port testing */ -static const char driver_name [] = "dummy_hcd"; -static const char driver_desc [] = "USB Host+Gadget Emulator"; +static const char driver_name[] = "dummy_hcd"; +static const char driver_desc[] = "USB Host+Gadget Emulator"; -static const char gadget_name [] = "dummy_udc"; +static const char gadget_name[] = "dummy_udc"; -MODULE_DESCRIPTION (DRIVER_DESC); -MODULE_AUTHOR ("David Brownell"); -MODULE_LICENSE ("GPL"); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_AUTHOR("David Brownell"); +MODULE_LICENSE("GPL"); struct dummy_hcd_module_parameters { bool is_super_speed; @@ -84,10 +83,10 @@ struct dummy_ep { struct usb_gadget *gadget; const struct usb_endpoint_descriptor *desc; struct usb_ep ep; - unsigned halted : 1; - unsigned wedged : 1; - unsigned already_seen : 1; - unsigned setup_stage : 1; + unsigned halted:1; + unsigned wedged:1; + unsigned already_seen:1; + unsigned setup_stage:1; unsigned stream_en:1; }; @@ -96,15 +95,15 @@ struct dummy_request { struct usb_request req; }; -static inline struct dummy_ep *usb_ep_to_dummy_ep (struct usb_ep *_ep) +static inline struct dummy_ep *usb_ep_to_dummy_ep(struct usb_ep *_ep) { - return container_of (_ep, struct dummy_ep, ep); + return container_of(_ep, struct dummy_ep, ep); } static inline struct dummy_request *usb_request_to_dummy_request (struct usb_request *_req) { - return container_of (_req, struct dummy_request, req); + return container_of(_req, struct dummy_request, req); } /*-------------------------------------------------------------------------*/ @@ -123,9 +122,9 @@ static inline struct dummy_request *usb_request_to_dummy_request * configurations, illegal or unsupported packet lengths, and so on. */ -static const char ep0name [] = "ep0"; +static const char ep0name[] = "ep0"; -static const char *const ep_name [] = { +static const char *const ep_name[] = { ep0name, /* everyone has ep0 */ /* act like a net2280: high speed, six configurable endpoints */ @@ -184,12 +183,12 @@ struct dummy { /* * SLAVE/GADGET side support */ - struct dummy_ep ep [DUMMY_ENDPOINTS]; + struct dummy_ep ep[DUMMY_ENDPOINTS]; int address; struct usb_gadget gadget; struct usb_gadget_driver *driver; struct dummy_request fifo_req; - u8 fifo_buf [FIFO_SIZE]; + u8 fifo_buf[FIFO_SIZE]; u16 devstatus; unsigned udc_suspended:1; unsigned pullup:1; @@ -216,14 +215,14 @@ static inline struct device *dummy_dev(struct dummy_hcd *dum) return dummy_hcd_to_hcd(dum)->self.controller; } -static inline struct device *udc_dev (struct dummy *dum) +static inline struct device *udc_dev(struct dummy *dum) { return dum->gadget.dev.parent; } -static inline struct dummy *ep_to_dummy (struct dummy_ep *ep) +static inline struct dummy *ep_to_dummy(struct dummy_ep *ep) { - return container_of (ep->gadget, struct dummy, gadget); + return container_of(ep->gadget, struct dummy, gadget); } static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) @@ -235,9 +234,9 @@ static inline struct dummy_hcd *gadget_to_dummy_hcd(struct usb_gadget *gadget) return dum->hs_hcd; } -static inline struct dummy *gadget_dev_to_dummy (struct device *dev) +static inline struct dummy *gadget_dev_to_dummy(struct device *dev) { - return container_of (dev, struct dummy, gadget.dev); + return container_of(dev, struct dummy, gadget.dev); } static struct dummy the_controller; @@ -247,24 +246,23 @@ static struct dummy the_controller; /* SLAVE/GADGET SIDE UTILITY ROUTINES */ /* called with spinlock held */ -static void nuke (struct dummy *dum, struct dummy_ep *ep) +static void nuke(struct dummy *dum, struct dummy_ep *ep) { - while (!list_empty (&ep->queue)) { + while (!list_empty(&ep->queue)) { struct dummy_request *req; - req = list_entry (ep->queue.next, struct dummy_request, queue); - list_del_init (&req->queue); + req = list_entry(ep->queue.next, struct dummy_request, queue); + list_del_init(&req->queue); req->req.status = -ESHUTDOWN; - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); } } /* caller must hold lock */ -static void -stop_activity (struct dummy *dum) +static void stop_activity(struct dummy *dum) { struct dummy_ep *ep; @@ -274,8 +272,8 @@ stop_activity (struct dummy *dum) /* The timer is left running so that outstanding URBs can fail */ /* nuke any pending requests first, so driver i/o is quiesced */ - list_for_each_entry (ep, &dum->gadget.ep_list, ep.ep_list) - nuke (dum, ep); + list_for_each_entry(ep, &dum->gadget.ep_list, ep.ep_list) + nuke(dum, ep); /* driver now does any non-usb quiescing necessary */ } @@ -410,8 +408,8 @@ static void set_link_state(struct dummy_hcd *dum_hcd) #define is_enabled(dum) \ (dum->port_status & USB_PORT_STAT_ENABLE) -static int -dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) +static int dummy_enable(struct usb_ep *_ep, + const struct usb_endpoint_descriptor *desc) { struct dummy *dum; struct dummy_hcd *dum_hcd; @@ -419,11 +417,11 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) unsigned max; int retval; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || !desc || ep->desc || _ep->name == ep0name || desc->bDescriptorType != USB_DT_ENDPOINT) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; @@ -449,8 +447,8 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) retval = -EINVAL; switch (usb_endpoint_type(desc)) { case USB_ENDPOINT_XFER_BULK: - if (strstr (ep->ep.name, "-iso") - || strstr (ep->ep.name, "-int")) { + if (strstr(ep->ep.name, "-iso") + || strstr(ep->ep.name, "-int")) { goto done; } switch (dum->gadget.speed) { @@ -472,7 +470,7 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) } break; case USB_ENDPOINT_XFER_INT: - if (strstr (ep->ep.name, "-iso")) /* bulk is ok */ + if (strstr(ep->ep.name, "-iso")) /* bulk is ok */ goto done; /* real hardware might not handle all packet sizes */ switch (dum->gadget.speed) { @@ -492,8 +490,8 @@ dummy_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) } break; case USB_ENDPOINT_XFER_ISOC: - if (strstr (ep->ep.name, "-bulk") - || strstr (ep->ep.name, "-int")) + if (strstr(ep->ep.name, "-bulk") + || strstr(ep->ep.name, "-int")) goto done; /* real hardware might not handle all packet sizes */ switch (dum->gadget.speed) { @@ -556,68 +554,65 @@ done: return retval; } -static int dummy_disable (struct usb_ep *_ep) +static int dummy_disable(struct usb_ep *_ep) { struct dummy_ep *ep; struct dummy *dum; unsigned long flags; int retval; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || !ep->desc || _ep->name == ep0name) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); ep->desc = NULL; ep->stream_en = 0; retval = 0; - nuke (dum, ep); - spin_unlock_irqrestore (&dum->lock, flags); + nuke(dum, ep); + spin_unlock_irqrestore(&dum->lock, flags); - dev_dbg (udc_dev(dum), "disabled %s\n", _ep->name); + dev_dbg(udc_dev(dum), "disabled %s\n", _ep->name); return retval; } -static struct usb_request * -dummy_alloc_request (struct usb_ep *_ep, gfp_t mem_flags) +static struct usb_request *dummy_alloc_request(struct usb_ep *_ep, + gfp_t mem_flags) { struct dummy_ep *ep; struct dummy_request *req; if (!_ep) return NULL; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); req = kzalloc(sizeof(*req), mem_flags); if (!req) return NULL; - INIT_LIST_HEAD (&req->queue); + INIT_LIST_HEAD(&req->queue); return &req->req; } -static void -dummy_free_request (struct usb_ep *_ep, struct usb_request *_req) +static void dummy_free_request(struct usb_ep *_ep, struct usb_request *_req) { struct dummy_ep *ep; struct dummy_request *req; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!ep || !_req || (!ep->desc && _ep->name != ep0name)) return; - req = usb_request_to_dummy_request (_req); - WARN_ON (!list_empty (&req->queue)); - kfree (req); + req = usb_request_to_dummy_request(_req); + WARN_ON(!list_empty(&req->queue)); + kfree(req); } -static void -fifo_complete (struct usb_ep *ep, struct usb_request *req) +static void fifo_complete(struct usb_ep *ep, struct usb_request *req) { } -static int -dummy_queue (struct usb_ep *_ep, struct usb_request *_req, +static int dummy_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t mem_flags) { struct dummy_ep *ep; @@ -626,49 +621,48 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, struct dummy_hcd *dum_hcd; unsigned long flags; - req = usb_request_to_dummy_request (_req); - if (!_req || !list_empty (&req->queue) || !_req->complete) + req = usb_request_to_dummy_request(_req); + if (!_req || !list_empty(&req->queue) || !_req->complete) return -EINVAL; - ep = usb_ep_to_dummy_ep (_ep); + ep = usb_ep_to_dummy_ep(_ep); if (!_ep || (!ep->desc && _ep->name != ep0name)) return -EINVAL; - dum = ep_to_dummy (ep); + dum = ep_to_dummy(ep); dum_hcd = gadget_to_dummy_hcd(&dum->gadget); if (!dum->driver || !is_enabled(dum_hcd)) return -ESHUTDOWN; #if 0 - dev_dbg (udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", + dev_dbg(udc_dev(dum), "ep %p queue req %p to %s, len %d buf %p\n", ep, _req, _ep->name, _req->length, _req->buf); #endif - _req->status = -EINPROGRESS; _req->actual = 0; - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); /* implement an emulated single-request FIFO */ if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && - list_empty (&dum->fifo_req.queue) && - list_empty (&ep->queue) && + list_empty(&dum->fifo_req.queue) && + list_empty(&ep->queue) && _req->length <= FIFO_SIZE) { req = &dum->fifo_req; req->req = *_req; req->req.buf = dum->fifo_buf; - memcpy (dum->fifo_buf, _req->buf, _req->length); + memcpy(dum->fifo_buf, _req->buf, _req->length); req->req.context = dum; req->req.complete = fifo_complete; list_add_tail(&req->queue, &ep->queue); - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); _req->actual = _req->length; _req->status = 0; - _req->complete (_ep, _req); - spin_lock (&dum->lock); + _req->complete(_ep, _req); + spin_lock(&dum->lock); } else list_add_tail(&req->queue, &ep->queue); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); /* real hardware would likely enable transfers here, in case * it'd been left NAKing. @@ -676,7 +670,7 @@ dummy_queue (struct usb_ep *_ep, struct usb_request *_req, return 0; } -static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) +static int dummy_dequeue(struct usb_ep *_ep, struct usb_request *_req) { struct dummy_ep *ep; struct dummy *dum; @@ -686,31 +680,31 @@ static int dummy_dequeue (struct usb_ep *_ep, struct usb_request *_req) if (!_ep || !_req) return retval; - ep = usb_ep_to_dummy_ep (_ep); - dum = ep_to_dummy (ep); + ep = usb_ep_to_dummy_ep(_ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; - local_irq_save (flags); - spin_lock (&dum->lock); - list_for_each_entry (req, &ep->queue, queue) { + local_irq_save(flags); + spin_lock(&dum->lock); + list_for_each_entry(req, &ep->queue, queue) { if (&req->req == _req) { - list_del_init (&req->queue); + list_del_init(&req->queue); _req->status = -ECONNRESET; retval = 0; break; } } - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); if (retval == 0) { - dev_dbg (udc_dev(dum), + dev_dbg(udc_dev(dum), "dequeued req %p from %s, len %d buf %p\n", req, _ep->name, _req->length, _req->buf); - _req->complete (_ep, _req); + _req->complete(_ep, _req); } - local_irq_restore (flags); + local_irq_restore(flags); return retval; } @@ -722,14 +716,14 @@ dummy_set_halt_and_wedge(struct usb_ep *_ep, int value, int wedged) if (!_ep) return -EINVAL; - ep = usb_ep_to_dummy_ep (_ep); - dum = ep_to_dummy (ep); + ep = usb_ep_to_dummy_ep(_ep); + dum = ep_to_dummy(ep); if (!dum->driver) return -ESHUTDOWN; if (!value) ep->halted = ep->wedged = 0; else if (ep->desc && (ep->desc->bEndpointAddress & USB_DIR_IN) && - !list_empty (&ep->queue)) + !list_empty(&ep->queue)) return -EAGAIN; else { ep->halted = 1; @@ -770,15 +764,15 @@ static const struct usb_ep_ops dummy_ep_ops = { /*-------------------------------------------------------------------------*/ /* there are both host and device side versions of this call ... */ -static int dummy_g_get_frame (struct usb_gadget *_gadget) +static int dummy_g_get_frame(struct usb_gadget *_gadget) { struct timeval tv; - do_gettimeofday (&tv); + do_gettimeofday(&tv); return tv.tv_usec / 1000; } -static int dummy_wakeup (struct usb_gadget *_gadget) +static int dummy_wakeup(struct usb_gadget *_gadget) { struct dummy_hcd *dum_hcd; @@ -801,11 +795,11 @@ static int dummy_wakeup (struct usb_gadget *_gadget) return 0; } -static int dummy_set_selfpowered (struct usb_gadget *_gadget, int value) +static int dummy_set_selfpowered(struct usb_gadget *_gadget, int value) { struct dummy *dum; - dum = (gadget_to_dummy_hcd(_gadget))->dum; + dum = gadget_to_dummy_hcd(_gadget)->dum; if (value) dum->devstatus |= (1 << USB_DEVICE_SELF_POWERED); else @@ -821,7 +815,7 @@ static void dummy_udc_update_ep0(struct dummy *dum) dum->ep[0].ep.maxpacket = 64; } -static int dummy_pullup (struct usb_gadget *_gadget, int value) +static int dummy_pullup(struct usb_gadget *_gadget, int value) { struct dummy_hcd *dum_hcd; struct dummy *dum; @@ -846,10 +840,10 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) } dum_hcd = gadget_to_dummy_hcd(_gadget); - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); dum->pullup = (value != 0); set_link_state(dum_hcd); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); usb_hcd_poll_rh_status(dummy_hcd_to_hcd(dum_hcd)); return 0; @@ -872,16 +866,16 @@ static const struct usb_gadget_ops dummy_ops = { /*-------------------------------------------------------------------------*/ /* "function" sysfs attribute */ -static ssize_t -show_function (struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_function(struct device *dev, struct device_attribute *attr, + char *buf) { - struct dummy *dum = gadget_dev_to_dummy (dev); + struct dummy *dum = gadget_dev_to_dummy(dev); if (!dum->driver || !dum->driver->function) return 0; - return scnprintf (buf, PAGE_SIZE, "%s\n", dum->driver->function); + return scnprintf(buf, PAGE_SIZE, "%s\n", dum->driver->function); } -static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); +static DEVICE_ATTR(function, S_IRUGO, show_function, NULL); /*-------------------------------------------------------------------------*/ @@ -916,7 +910,7 @@ static int dummy_udc_start(struct usb_gadget *g, dum->devstatus = 0; dum->driver = driver; - dev_dbg (udc_dev(dum), "binding gadget driver '%s'\n", + dev_dbg(udc_dev(dum), "binding gadget driver '%s'\n", driver->driver.name); return 0; } @@ -927,7 +921,7 @@ static int dummy_udc_stop(struct usb_gadget *g, struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); struct dummy *dum = dum_hcd->dum; - dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", + dev_dbg(udc_dev(dum), "unregister gadget driver '%s'\n", driver->driver.name); dum->driver = NULL; @@ -940,8 +934,7 @@ static int dummy_udc_stop(struct usb_gadget *g, /* The gadget structure is stored inside the hcd structure and will be * released along with it. */ -static void -dummy_gadget_release (struct device *dev) +static void dummy_gadget_release(struct device *dev) { return; } @@ -978,7 +971,7 @@ static void init_dummy_udc_hw(struct dummy *dum) #endif } -static int dummy_udc_probe (struct platform_device *pdev) +static int dummy_udc_probe(struct platform_device *pdev) { struct dummy *dum = &the_controller; int rc; @@ -990,7 +983,7 @@ static int dummy_udc_probe (struct platform_device *pdev) dev_set_name(&dum->gadget.dev, "gadget"); dum->gadget.dev.parent = &pdev->dev; dum->gadget.dev.release = dummy_gadget_release; - rc = device_register (&dum->gadget.dev); + rc = device_register(&dum->gadget.dev); if (rc < 0) { put_device(&dum->gadget.dev); return rc; @@ -1002,7 +995,7 @@ static int dummy_udc_probe (struct platform_device *pdev) if (rc < 0) goto err_udc; - rc = device_create_file (&dum->gadget.dev, &dev_attr_function); + rc = device_create_file(&dum->gadget.dev, &dev_attr_function); if (rc < 0) goto err_dev; platform_set_drvdata(pdev, dum); @@ -1015,14 +1008,14 @@ err_udc: return rc; } -static int dummy_udc_remove (struct platform_device *pdev) +static int dummy_udc_remove(struct platform_device *pdev) { - struct dummy *dum = platform_get_drvdata (pdev); + struct dummy *dum = platform_get_drvdata(pdev); usb_del_gadget_udc(&dum->gadget); - platform_set_drvdata (pdev, NULL); - device_remove_file (&dum->gadget.dev, &dev_attr_function); - device_unregister (&dum->gadget.dev); + platform_set_drvdata(pdev, NULL); + device_remove_file(&dum->gadget.dev, &dev_attr_function); + device_unregister(&dum->gadget.dev); return 0; } @@ -1167,7 +1160,7 @@ static int dummy_validate_stream(struct dummy_hcd *dum_hcd, struct urb *urb) return 0; } -static int dummy_urb_enqueue ( +static int dummy_urb_enqueue( struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags @@ -1177,7 +1170,7 @@ static int dummy_urb_enqueue ( unsigned long flags; int rc; - urbp = kmalloc (sizeof *urbp, mem_flags); + urbp = kmalloc(sizeof *urbp, mem_flags); if (!urbp) return -ENOMEM; urbp->urb = urb; @@ -1206,7 +1199,7 @@ static int dummy_urb_enqueue ( list_add_tail(&urbp->urbp_list, &dum_hcd->urbp_list); urb->hcpriv = urbp; - if (usb_pipetype (urb->pipe) == PIPE_CONTROL) + if (usb_pipetype(urb->pipe) == PIPE_CONTROL) urb->error_count = 1; /* mark as a new urb */ /* kick the scheduler, it'll do the rest */ @@ -1313,7 +1306,7 @@ static int transfer(struct dummy_hcd *dum_hcd, struct urb *urb, top: /* if there's no request queued, the device is NAKing; return */ - list_for_each_entry (req, &ep->queue, queue) { + list_for_each_entry(req, &ep->queue, queue) { unsigned host_len, dev_len, len; int is_short, to_host; int rescan = 0; @@ -1332,18 +1325,18 @@ top: */ host_len = urb->transfer_buffer_length - urb->actual_length; dev_len = req->req.length - req->req.actual; - len = min (host_len, dev_len); + len = min(host_len, dev_len); /* FIXME update emulated data toggle too */ - to_host = usb_pipein (urb->pipe); - if (unlikely (len == 0)) + to_host = usb_pipein(urb->pipe); + if (unlikely(len == 0)) is_short = 1; else { /* not enough bandwidth left? */ if (limit < ep->ep.maxpacket && limit < len) break; - len = min (len, (unsigned) limit); + len = min_t(unsigned, len, limit); if (len == 0) break; @@ -1404,11 +1397,11 @@ top: /* device side completion --> continuable */ if (req->req.status != -EINPROGRESS) { - list_del_init (&req->queue); + list_del_init(&req->queue); - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); /* requests might have been unlinked... */ rescan = 1; @@ -1425,7 +1418,7 @@ top: return limit; } -static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) +static int periodic_bytes(struct dummy *dum, struct dummy_ep *ep) { int limit = ep->ep.maxpacket; @@ -1461,7 +1454,7 @@ static int periodic_bytes (struct dummy *dum, struct dummy_ep *ep) USB_PORT_STAT_SUSPEND)) \ == (USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE)) -static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) +static struct dummy_ep *find_endpoint(struct dummy *dum, u8 address) { int i; @@ -1469,9 +1462,9 @@ static struct dummy_ep *find_endpoint (struct dummy *dum, u8 address) dum->ss_hcd : dum->hs_hcd))) return NULL; if ((address & ~USB_DIR_IN) == 0) - return &dum->ep [0]; + return &dum->ep[0]; for (i = 1; i < DUMMY_ENDPOINTS; i++) { - struct dummy_ep *ep = &dum->ep [i]; + struct dummy_ep *ep = &dum->ep[i]; if (!ep->desc) continue; @@ -1701,19 +1694,19 @@ static void dummy_timer(unsigned long _dum_hcd) /* FIXME if HZ != 1000 this will probably misbehave ... */ /* look at each urb queued by the host side driver */ - spin_lock_irqsave (&dum->lock, flags); + spin_lock_irqsave(&dum->lock, flags); if (!dum_hcd->udev) { dev_err(dummy_dev(dum_hcd), "timer fired with no URBs pending?\n"); - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); return; } for (i = 0; i < DUMMY_ENDPOINTS; i++) { - if (!ep_name [i]) + if (!ep_name[i]) break; - dum->ep [i].already_seen = 0; + dum->ep[i].already_seen = 0; } restart: @@ -1730,7 +1723,7 @@ restart: goto return_urb; else if (dum_hcd->rh_state != DUMMY_RH_RUNNING) continue; - type = usb_pipetype (urb->pipe); + type = usb_pipetype(urb->pipe); /* used up this frame's non-periodic bandwidth? * FIXME there's infinite bandwidth for control and @@ -1741,7 +1734,7 @@ restart: /* find the gadget's ep for this request (if configured) */ address = usb_pipeendpoint (urb->pipe); - if (usb_pipein (urb->pipe)) + if (usb_pipein(urb->pipe)) address |= USB_DIR_IN; ep = find_endpoint(dum, address); if (!ep) { @@ -1756,7 +1749,7 @@ restart: if (ep->already_seen) continue; ep->already_seen = 1; - if (ep == &dum->ep [0] && urb->error_count) { + if (ep == &dum->ep[0] && urb->error_count) { ep->setup_stage = 1; /* a new urb */ urb->error_count = 0; } @@ -1770,21 +1763,21 @@ restart: /* FIXME make sure both ends agree on maxpacket */ /* handle control requests */ - if (ep == &dum->ep [0] && ep->setup_stage) { + if (ep == &dum->ep[0] && ep->setup_stage) { struct usb_ctrlrequest setup; int value = 1; - setup = *(struct usb_ctrlrequest*) urb->setup_packet; + setup = *(struct usb_ctrlrequest *) urb->setup_packet; /* paranoia, in case of stale queued data */ - list_for_each_entry (req, &ep->queue, queue) { - list_del_init (&req->queue); + list_for_each_entry(req, &ep->queue, queue) { + list_del_init(&req->queue); req->req.status = -EOVERFLOW; - dev_dbg (udc_dev(dum), "stale req = %p\n", + dev_dbg(udc_dev(dum), "stale req = %p\n", req); - spin_unlock (&dum->lock); - req->req.complete (&ep->ep, &req->req); - spin_lock (&dum->lock); + spin_unlock(&dum->lock); + req->req.complete(&ep->ep, &req->req); + spin_lock(&dum->lock); ep->already_seen = 0; goto restart; } @@ -1804,10 +1797,10 @@ restart: * until setup() returns; no reentrancy issues etc. */ if (value > 0) { - spin_unlock (&dum->lock); - value = dum->driver->setup (&dum->gadget, + spin_unlock(&dum->lock); + value = dum->driver->setup(&dum->gadget, &setup); - spin_lock (&dum->lock); + spin_lock(&dum->lock); if (value >= 0) { /* no delays (max 64KB data stage) */ @@ -1819,7 +1812,7 @@ restart: if (value < 0) { if (value != -EOPNOTSUPP) - dev_dbg (udc_dev(dum), + dev_dbg(udc_dev(dum), "setup --> %d\n", value); status = -EPIPE; @@ -1831,14 +1824,14 @@ restart: /* non-control requests */ limit = total; - switch (usb_pipetype (urb->pipe)) { + switch (usb_pipetype(urb->pipe)) { case PIPE_ISOCHRONOUS: /* FIXME is it urb->interval since the last xfer? * use urb->iso_frame_desc[i]. * complete whether or not ep has requests queued. * report random errors, to debug drivers. */ - limit = max (limit, periodic_bytes (dum, ep)); + limit = max(limit, periodic_bytes(dum, ep)); status = -ENOSYS; break; @@ -1846,12 +1839,11 @@ restart: /* FIXME is it urb->interval since the last xfer? * this almost certainly polls too fast. */ - limit = max (limit, periodic_bytes (dum, ep)); + limit = max(limit, periodic_bytes(dum, ep)); /* FALLTHROUGH */ - // case PIPE_BULK: case PIPE_CONTROL: default: - treat_control_like_bulk: +treat_control_like_bulk: ep->last_io = jiffies; total = transfer(dum_hcd, urb, ep, limit, &status); break; @@ -1862,15 +1854,15 @@ restart: continue; return_urb: - list_del (&urbp->urbp_list); - kfree (urbp); + list_del(&urbp->urbp_list); + kfree(urbp); if (ep) ep->already_seen = ep->setup_stage = 0; usb_hcd_unlink_urb_from_ep(dummy_hcd_to_hcd(dum_hcd), urb); - spin_unlock (&dum->lock); + spin_unlock(&dum->lock); usb_hcd_giveback_urb(dummy_hcd_to_hcd(dum_hcd), urb, status); - spin_lock (&dum->lock); + spin_lock(&dum->lock); goto restart; } @@ -1883,7 +1875,7 @@ return_urb: mod_timer(&dum_hcd->timer, jiffies + msecs_to_jiffies(1)); } - spin_unlock_irqrestore (&dum->lock, flags); + spin_unlock_irqrestore(&dum->lock, flags); } /*-------------------------------------------------------------------------*/ @@ -1895,7 +1887,7 @@ return_urb: | USB_PORT_STAT_C_OVERCURRENT \ | USB_PORT_STAT_C_RESET) << 16) -static int dummy_hub_status (struct usb_hcd *hcd, char *buf) +static int dummy_hub_status(struct usb_hcd *hcd, char *buf) { struct dummy_hcd *dum_hcd; unsigned long flags; @@ -1919,7 +1911,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) dum_hcd->port_status); retval = 1; if (dum_hcd->rh_state == DUMMY_RH_SUSPENDED) - usb_hcd_resume_root_hub (hcd); + usb_hcd_resume_root_hub(hcd); } done: spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); @@ -1938,10 +1930,9 @@ ss_hub_descriptor(struct usb_hub_descriptor *desc) desc->u.ss.DeviceRemovable = 0xffff; } -static inline void -hub_descriptor (struct usb_hub_descriptor *desc) +static inline void hub_descriptor(struct usb_hub_descriptor *desc) { - memset (desc, 0, sizeof *desc); + memset(desc, 0, sizeof *desc); desc->bDescriptorType = 0x29; desc->bDescLength = 9; desc->wHubCharacteristics = cpu_to_le16(0x0001); @@ -1950,7 +1941,7 @@ hub_descriptor (struct usb_hub_descriptor *desc) desc->u.hs.DeviceRemovable[1] = 0xff; } -static int dummy_hub_control ( +static int dummy_hub_control( struct usb_hcd *hcd, u16 typeReq, u16 wValue, @@ -2018,7 +2009,7 @@ static int dummy_hub_control ( hub_descriptor((struct usb_hub_descriptor *) buf); break; case GetHubStatus: - *(__le32 *) buf = cpu_to_le32 (0); + *(__le32 *) buf = cpu_to_le32(0); break; case GetPortStatus: if (wIndex != 1) @@ -2060,8 +2051,8 @@ static int dummy_hub_control ( } } set_link_state(dum_hcd); - ((__le16 *) buf)[0] = cpu_to_le16 (dum_hcd->port_status); - ((__le16 *) buf)[1] = cpu_to_le16 (dum_hcd->port_status >> 16); + ((__le16 *) buf)[0] = cpu_to_le16(dum_hcd->port_status); + ((__le16 *) buf)[1] = cpu_to_le16(dum_hcd->port_status >> 16); break; case SetHubFeature: retval = -EPIPE; @@ -2195,15 +2186,15 @@ error: spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); if ((dum_hcd->port_status & PORT_C_MASK) != 0) - usb_hcd_poll_rh_status (hcd); + usb_hcd_poll_rh_status(hcd); return retval; } -static int dummy_bus_suspend (struct usb_hcd *hcd) +static int dummy_bus_suspend(struct usb_hcd *hcd) { struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq(&dum_hcd->dum->lock); dum_hcd->rh_state = DUMMY_RH_SUSPENDED; @@ -2213,12 +2204,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) return 0; } -static int dummy_bus_resume (struct usb_hcd *hcd) +static int dummy_bus_resume(struct usb_hcd *hcd) { struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); int rc = 0; - dev_dbg (&hcd->self.root_hub->dev, "%s\n", __func__); + dev_dbg(&hcd->self.root_hub->dev, "%s\n", __func__); spin_lock_irq(&dum_hcd->dum->lock); if (!HCD_HW_ACCESSIBLE(hcd)) { @@ -2236,55 +2227,54 @@ static int dummy_bus_resume (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static inline ssize_t -show_urb (char *buf, size_t size, struct urb *urb) +static inline ssize_t show_urb(char *buf, size_t size, struct urb *urb) { - int ep = usb_pipeendpoint (urb->pipe); + int ep = usb_pipeendpoint(urb->pipe); - return snprintf (buf, size, + return snprintf(buf, size, "urb/%p %s ep%d%s%s len %d/%d\n", urb, ({ char *s; - switch (urb->dev->speed) { - case USB_SPEED_LOW: + switch (urb->dev->speed) { + case USB_SPEED_LOW: s = "ls"; break; - case USB_SPEED_FULL: + case USB_SPEED_FULL: s = "fs"; break; - case USB_SPEED_HIGH: + case USB_SPEED_HIGH: s = "hs"; break; - case USB_SPEED_SUPER: + case USB_SPEED_SUPER: s = "ss"; break; - default: + default: s = "?"; break; }; s; }), - ep, ep ? (usb_pipein (urb->pipe) ? "in" : "out") : "", + ep, ep ? (usb_pipein(urb->pipe) ? "in" : "out") : "", ({ char *s; \ - switch (usb_pipetype (urb->pipe)) { \ - case PIPE_CONTROL: \ + switch (usb_pipetype(urb->pipe)) { \ + case PIPE_CONTROL: \ s = ""; \ break; \ - case PIPE_BULK: \ + case PIPE_BULK: \ s = "-bulk"; \ break; \ - case PIPE_INTERRUPT: \ + case PIPE_INTERRUPT: \ s = "-int"; \ break; \ - default: \ + default: \ s = "-iso"; \ break; \ - }; s;}), + }; s; }), urb->actual_length, urb->transfer_buffer_length); } -static ssize_t -show_urbs (struct device *dev, struct device_attribute *attr, char *buf) +static ssize_t show_urbs(struct device *dev, struct device_attribute *attr, + char *buf) { - struct usb_hcd *hcd = dev_get_drvdata (dev); + struct usb_hcd *hcd = dev_get_drvdata(dev); struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); struct urbp *urbp; size_t size = 0; @@ -2294,7 +2284,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) list_for_each_entry(urbp, &dum_hcd->urbp_list, urbp_list) { size_t temp; - temp = show_urb (buf, PAGE_SIZE - size, urbp->urb); + temp = show_urb(buf, PAGE_SIZE - size, urbp->urb); buf += temp; size += temp; } @@ -2302,7 +2292,7 @@ show_urbs (struct device *dev, struct device_attribute *attr, char *buf) return size; } -static DEVICE_ATTR (urbs, S_IRUGO, show_urbs, NULL); +static DEVICE_ATTR(urbs, S_IRUGO, show_urbs, NULL); static int dummy_start_ss(struct dummy_hcd *dum_hcd) { @@ -2356,11 +2346,11 @@ static int dummy_start(struct usb_hcd *hcd) return device_create_file(dummy_dev(dum_hcd), &dev_attr_urbs); } -static void dummy_stop (struct usb_hcd *hcd) +static void dummy_stop(struct usb_hcd *hcd) { struct dummy *dum; - dum = (hcd_to_dummy_hcd(hcd))->dum; + dum = hcd_to_dummy_hcd(hcd)->dum; device_remove_file(dummy_dev(hcd_to_dummy_hcd(hcd)), &dev_attr_urbs); usb_gadget_unregister_driver(dum->driver); dev_info(dummy_dev(hcd_to_dummy_hcd(hcd)), "stopped\n"); @@ -2368,9 +2358,9 @@ static void dummy_stop (struct usb_hcd *hcd) /*-------------------------------------------------------------------------*/ -static int dummy_h_get_frame (struct usb_hcd *hcd) +static int dummy_h_get_frame(struct usb_hcd *hcd) { - return dummy_g_get_frame (NULL); + return dummy_g_get_frame(NULL); } static int dummy_setup(struct usb_hcd *hcd) @@ -2485,13 +2475,13 @@ static struct hc_driver dummy_hcd = { .start = dummy_start, .stop = dummy_stop, - .urb_enqueue = dummy_urb_enqueue, - .urb_dequeue = dummy_urb_dequeue, + .urb_enqueue = dummy_urb_enqueue, + .urb_dequeue = dummy_urb_dequeue, - .get_frame_number = dummy_h_get_frame, + .get_frame_number = dummy_h_get_frame, - .hub_status_data = dummy_hub_status, - .hub_control = dummy_hub_control, + .hub_status_data = dummy_hub_status, + .hub_control = dummy_hub_control, .bus_suspend = dummy_bus_suspend, .bus_resume = dummy_bus_resume, @@ -2546,7 +2536,7 @@ static int dummy_hcd_remove(struct platform_device *pdev) { struct dummy *dum; - dum = (hcd_to_dummy_hcd(platform_get_drvdata(pdev)))->dum; + dum = hcd_to_dummy_hcd(platform_get_drvdata(pdev))->dum; if (dum->ss_hcd) { usb_remove_hcd(dummy_hcd_to_hcd(dum->ss_hcd)); @@ -2562,15 +2552,15 @@ static int dummy_hcd_remove(struct platform_device *pdev) return 0; } -static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) +static int dummy_hcd_suspend(struct platform_device *pdev, pm_message_t state) { struct usb_hcd *hcd; struct dummy_hcd *dum_hcd; int rc = 0; - dev_dbg (&pdev->dev, "%s\n", __func__); + dev_dbg(&pdev->dev, "%s\n", __func__); - hcd = platform_get_drvdata (pdev); + hcd = platform_get_drvdata(pdev); dum_hcd = hcd_to_dummy_hcd(hcd); if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); @@ -2580,15 +2570,15 @@ static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) return rc; } -static int dummy_hcd_resume (struct platform_device *pdev) +static int dummy_hcd_resume(struct platform_device *pdev) { struct usb_hcd *hcd; - dev_dbg (&pdev->dev, "%s\n", __func__); + dev_dbg(&pdev->dev, "%s\n", __func__); - hcd = platform_get_drvdata (pdev); + hcd = platform_get_drvdata(pdev); set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); - usb_hcd_poll_rh_status (hcd); + usb_hcd_poll_rh_status(hcd); return 0; } @@ -2608,11 +2598,11 @@ static struct platform_driver dummy_hcd_driver = { static struct platform_device *the_udc_pdev; static struct platform_device *the_hcd_pdev; -static int __init init (void) +static int __init init(void) { int retval = -ENOMEM; - if (usb_disabled ()) + if (usb_disabled()) return -ENODEV; if (!mod_data.is_high_speed && mod_data.is_super_speed) @@ -2671,13 +2661,13 @@ err_alloc_udc: platform_device_put(the_hcd_pdev); return retval; } -module_init (init); +module_init(init); -static void __exit cleanup (void) +static void __exit cleanup(void) { platform_device_unregister(the_udc_pdev); platform_device_unregister(the_hcd_pdev); platform_driver_unregister(&dummy_udc_driver); platform_driver_unregister(&dummy_hcd_driver); } -module_exit (cleanup); +module_exit(cleanup); -- cgit v1.2.3-70-g09d2 From 54b8360ffd4c8b2c128ca25233b8c6876fb92d30 Mon Sep 17 00:00:00 2001 From: Michal Nazarewicz Date: Fri, 13 Jan 2012 15:05:16 +0100 Subject: usb: gadget: update Michal Nazarewicz's email address The m.nazarewicz@samsung.com email address is no longer valid, so this commit replaces it with mina86@mina86.com which is employer-agnostic and thus should be valid for foreseeable feature. Signed-off-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_acm.c | 2 +- drivers/usb/gadget/f_fs.c | 2 +- drivers/usb/gadget/f_mass_storage.c | 2 +- drivers/usb/gadget/f_rndis.c | 2 +- drivers/usb/gadget/g_ffs.c | 2 +- drivers/usb/gadget/mass_storage.c | 2 +- drivers/usb/gadget/multi.c | 2 +- drivers/usb/gadget/storage_common.c | 2 +- tools/usb/ffs-test.c | 2 +- tools/usb/testusb.c | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index 3f8849339ad..e4821219546 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c @@ -5,7 +5,7 @@ * Copyright (C) 2008 by David Brownell * Copyright (C) 2008 by Nokia Corporation * Copyright (C) 2009 by Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * Author: Michal Nazarewicz (mina86@mina86.com) * * This software is distributed under the terms of the GNU General * Public License ("GPL") as published by the Free Software Foundation, diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index f63dc6c150d..7e2216f1bbe 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -2,7 +2,7 @@ * f_fs.c -- user mode file system API for USB composite function controllers * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * Based on inode.c (GadgetFS) which was: * Copyright (C) 2003-2004 David Brownell diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6353eca1e85..6cde0217a8d 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 704d1d94f72..7b1cf18df5e 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -5,7 +5,7 @@ * Copyright (C) 2003-2004 Robert Schwebel, Benedikt Spranger * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * Author: Michal Nazarewicz (mina86@mina86.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 0519d77915e..331cd6729d3 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -2,7 +2,7 @@ * g_ffs.c -- user mode file system API for USB composite function controllers * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/usb/gadget/mass_storage.c b/drivers/usb/gadget/mass_storage.c index e24f72f82a4..1f376eba31f 100644 --- a/drivers/usb/gadget/mass_storage.c +++ b/drivers/usb/gadget/mass_storage.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * All rights reserved. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/usb/gadget/multi.c b/drivers/usb/gadget/multi.c index 7e7f515b8b1..c37fb33a3d1 100644 --- a/drivers/usb/gadget/multi.c +++ b/drivers/usb/gadget/multi.c @@ -4,7 +4,7 @@ * Copyright (C) 2008 David Brownell * Copyright (C) 2008 Nokia Corporation * Copyright (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * Author: Michal Nazarewicz (mina86@mina86.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index c7f291a331d..9d450feaaea 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -3,7 +3,7 @@ * * Copyright (C) 2003-2008 Alan Stern * Copyeight (C) 2009 Samsung Electronics - * Author: Michal Nazarewicz (m.nazarewicz@samsung.com) + * Author: Michal Nazarewicz (mina86@mina86.com) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/usb/ffs-test.c b/tools/usb/ffs-test.c index b9c79863169..53452c35d5e 100644 --- a/tools/usb/ffs-test.c +++ b/tools/usb/ffs-test.c @@ -2,7 +2,7 @@ * ffs-test.c.c -- user mode filesystem api for usb composite function * * Copyright (C) 2010 Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/tools/usb/testusb.c b/tools/usb/testusb.c index f08e8946384..6e0f56701e4 100644 --- a/tools/usb/testusb.c +++ b/tools/usb/testusb.c @@ -3,7 +3,7 @@ /* * Copyright (c) 2002 by David Brownell * Copyright (c) 2010 by Samsung Electronics - * Author: Michal Nazarewicz + * Author: Michal Nazarewicz * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the -- cgit v1.2.3-70-g09d2 From fcc0bb5ace11e6d0a27bdbdbf2e5e6d361a4e701 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 21:54:46 +0100 Subject: usb: gadget: f_mass_storage: remove one FSG_NO_INTR_EP Remove one define of FSG_NO_INTR_EP and we still have that we can use. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_mass_storage.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index 6cde0217a8d..82462714582 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c @@ -304,7 +304,6 @@ static const char fsg_string_interface[] = "Mass Storage"; -#define FSG_NO_INTR_EP 1 #define FSG_NO_DEVICE_STRINGS 1 #define FSG_NO_OTG 1 #define FSG_NO_INTR_EP 1 -- cgit v1.2.3-70-g09d2 From f557978745bbea2e7305588d33aac60f4dd42447 Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Thu, 12 Jan 2012 15:21:38 +0200 Subject: usb: musb: drop superfluous pm_runtime calls around musb_shutdown Since commit 4f9edd2d7e8d "usb: musb: Fix the crash issue during reboot" musb_shutdown() does pm_runtime_get_sync/pm_runtime_put by itself, so this no longer needs to be done by the caller. Also, musb_exit_debugfs() doesn't access the device, so just drop those runtime_pm calls. Signed-off-by: Grazvydas Ignotas Reviewed-by: Shubhrajyoti D Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_core.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 56cf0243979..6a929859b55 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -2111,11 +2111,9 @@ static int __exit musb_remove(struct platform_device *pdev) * - Peripheral mode: peripheral is deactivated (or never-activated) * - OTG mode: both roles are deactivated (or never-activated) */ - pm_runtime_get_sync(musb->controller); musb_exit_debugfs(musb); musb_shutdown(pdev); - pm_runtime_put(musb->controller); musb_free(musb); iounmap(ctrl_base); device_init_wakeup(&pdev->dev, 0); -- cgit v1.2.3-70-g09d2 From 7a950ea81de6cbf96e721599bfacdb409908cd00 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:48 +0530 Subject: ath6kl: Make sure to delete rx aggregation timer in aggr_reset_state() The timer which is used to flush rx aggregation frames needs to be disabled when resetting the aggregation state. This is found in code review. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index dd633714260..cb7421a3161 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1685,6 +1685,11 @@ void aggr_reset_state(struct aggr_info *aggr_info) { u8 tid; + if (aggr_info->timer_scheduled) { + del_timer(&aggr_info->timer); + aggr_info->timer_scheduled = false; + } + for (tid = 0; tid < NUM_OF_TIDS; tid++) aggr_delete_tid_state(aggr_info, tid); } -- cgit v1.2.3-70-g09d2 From 0e7de662bcf33567cc957995c38dc10959cc22bf Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:49 +0530 Subject: ath6kl: Fix memory leak when unloading ath6kl_sdio The patch "ath6kl: create core.c" removes wiphy_free() from ath6kl_cfg80211_cleanup() and misses to free wiphy in ath6kl_sdio_remove(). This patch fixes this regression. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 7bb61077c40..d9f55914b89 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -1314,6 +1314,7 @@ static void ath6kl_sdio_remove(struct sdio_func *func) cancel_work_sync(&ar_sdio->wr_async_work); ath6kl_core_cleanup(ar_sdio->ar); + ath6kl_core_destroy(ar_sdio->ar); kfree(ar_sdio->dma_buffer); kfree(ar_sdio); -- cgit v1.2.3-70-g09d2 From 7baef812eb5f02ccacf6fac3888c1cfa36293e91 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:50 +0530 Subject: ath6kl: Define a structure for connection specific aggregation information This patch just groups connection specific aggregation information from struct aggr_info into a new structure (struct aggr_info_conn) so that, in softAP mode, this can be used when each connected station is made to have it's own aggregation state. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- drivers/net/wireless/ath/ath6kl/core.h | 11 +- drivers/net/wireless/ath/ath6kl/txrx.c | 166 ++++++++++++++++------------- 3 files changed, 98 insertions(+), 81 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 594d246da8e..8bf447a6a84 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2694,7 +2694,7 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar) static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif) { - vif->aggr_cntxt = aggr_init(vif->ndev); + vif->aggr_cntxt = aggr_init(vif); if (!vif->aggr_cntxt) { ath6kl_err("failed to initialize aggr\n"); return -ENOMEM; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 67b22e4bbcc..1b9054f8f4e 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -242,14 +242,19 @@ struct rxtid_stats { u32 num_bar; }; -struct aggr_info { +struct aggr_info_conn { u8 aggr_sz; u8 timer_scheduled; struct timer_list timer; struct net_device *dev; struct rxtid rx_tid[NUM_OF_TIDS]; - struct sk_buff_head free_q; struct rxtid_stats stat[NUM_OF_TIDS]; + struct aggr_info *aggr_info; +}; + +struct aggr_info { + struct aggr_info_conn *aggr_conn; + struct sk_buff_head rx_amsdu_freeq; }; struct ath6kl_wep_key { @@ -707,7 +712,7 @@ struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar); void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); -struct aggr_info *aggr_init(struct net_device *dev); +struct aggr_info *aggr_init(struct ath6kl_vif *vif); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index cb7421a3161..8407d0103dc 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -819,10 +819,12 @@ static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr) { struct sk_buff *skb = NULL; - if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + if (skb_queue_len(&p_aggr->rx_amsdu_freeq) < + (AGGR_NUM_OF_FREE_NETBUFS >> 2)) + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, + AGGR_NUM_OF_FREE_NETBUFS); - skb = skb_dequeue(&p_aggr->free_q); + skb = skb_dequeue(&p_aggr->rx_amsdu_freeq); return skb; } @@ -998,12 +1000,14 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, struct skb_hold_q *node; u16 idx, idx_end, seq_end; struct rxtid_stats *stats; + struct aggr_info_conn *agg_conn; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + agg_conn = p_aggr->aggr_conn; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); @@ -1048,7 +1052,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, stats->num_delivered += skb_queue_len(&rxtid->q); while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb); + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, @@ -1062,9 +1066,10 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, u16 idx, st, cur, end; bool is_queued = false; u16 extended_end; + struct aggr_info_conn *agg_conn = agg_info->aggr_conn; - rxtid = &agg_info->rx_tid[tid]; - stats = &agg_info->stat[tid]; + rxtid = &agg_conn->rx_tid[tid]; + stats = &agg_conn->stat[tid]; stats->num_into_aggr++; @@ -1074,7 +1079,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, is_queued = true; stats->num_amsdu++; while ((skb = skb_dequeue(&rxtid->q))) - ath6kl_deliver_frames_to_nw_stack(agg_info->dev, + ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } return is_queued; @@ -1152,7 +1157,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, aggr_deque_frms(agg_info, tid, 0, 1); - if (agg_info->timer_scheduled) + if (agg_conn->timer_scheduled) rxtid->progress = true; else for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) { @@ -1163,8 +1168,8 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, * the frame doesn't remain stuck * forever. */ - agg_info->timer_scheduled = true; - mod_timer(&agg_info->timer, + agg_conn->timer_scheduled = true; + mod_timer(&agg_conn->timer, (jiffies + HZ * (AGGR_RX_TIMEOUT) / 1000)); rxtid->progress = false; @@ -1525,13 +1530,13 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) static void aggr_timeout(unsigned long arg) { u8 i, j; - struct aggr_info *p_aggr = (struct aggr_info *) arg; + struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg; struct rxtid *rxtid; struct rxtid_stats *stats; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; - stats = &p_aggr->stat[i]; + rxtid = &aggr_conn->rx_tid[i]; + stats = &aggr_conn->stat[i]; if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress) continue; @@ -1542,18 +1547,18 @@ static void aggr_timeout(unsigned long arg) rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO)); - aggr_deque_frms(p_aggr, i, 0, 0); + aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0); } - p_aggr->timer_scheduled = false; + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; if (rxtid->aggr && rxtid->hold_q) { for (j = 0; j < rxtid->hold_q_sz; j++) { if (rxtid->hold_q[j].skb) { - p_aggr->timer_scheduled = true; + aggr_conn->timer_scheduled = true; rxtid->timer_mon = true; rxtid->progress = false; break; @@ -1565,24 +1570,24 @@ static void aggr_timeout(unsigned long arg) } } - if (p_aggr->timer_scheduled) - mod_timer(&p_aggr->timer, + if (aggr_conn->timer_scheduled) + mod_timer(&aggr_conn->timer, jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT)); } -static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) +static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) { struct rxtid *rxtid; struct rxtid_stats *stats; - if (!p_aggr || tid >= NUM_OF_TIDS) + if (!aggr_conn || tid >= NUM_OF_TIDS) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (rxtid->aggr) - aggr_deque_frms(p_aggr, tid, 0, 0); + aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0); rxtid->aggr = false; rxtid->progress = false; @@ -1601,22 +1606,25 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = vif->aggr_cntxt; + struct aggr_info_conn *aggr_conn; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; - stats = &p_aggr->stat[tid]; + aggr_conn = p_aggr->aggr_conn; + + rxtid = &aggr_conn->rx_tid[tid]; + stats = &aggr_conn->stat[tid]; if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n", __func__, win_sz, tid); if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); rxtid->seq_next = seq_no; hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q); @@ -1632,31 +1640,23 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, rxtid->aggr = true; } -struct aggr_info *aggr_init(struct net_device *dev) +static void aggr_conn_init(struct ath6kl_vif *vif, + struct aggr_info_conn *aggr_conn) { - struct aggr_info *p_aggr = NULL; struct rxtid *rxtid; u8 i; - p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); - if (!p_aggr) { - ath6kl_err("failed to alloc memory for aggr_node\n"); - return NULL; - } - - p_aggr->aggr_sz = AGGR_SZ_DEFAULT; - p_aggr->dev = dev; - init_timer(&p_aggr->timer); - p_aggr->timer.function = aggr_timeout; - p_aggr->timer.data = (unsigned long) p_aggr; - - p_aggr->timer_scheduled = false; - skb_queue_head_init(&p_aggr->free_q); + aggr_conn->aggr_sz = AGGR_SZ_DEFAULT; + aggr_conn->dev = vif->ndev; + init_timer(&aggr_conn->timer); + aggr_conn->timer.function = aggr_timeout; + aggr_conn->timer.data = (unsigned long) aggr_conn; + aggr_conn->aggr_info = vif->aggr_cntxt; - ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS); + aggr_conn->timer_scheduled = false; for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &p_aggr->rx_tid[i]; + rxtid = &aggr_conn->rx_tid[i]; rxtid->aggr = false; rxtid->progress = false; rxtid->timer_mon = false; @@ -1664,6 +1664,30 @@ struct aggr_info *aggr_init(struct net_device *dev) spin_lock_init(&rxtid->lock); } +} + +struct aggr_info *aggr_init(struct ath6kl_vif *vif) +{ + struct aggr_info *p_aggr = NULL; + + p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL); + if (!p_aggr) { + ath6kl_err("failed to alloc memory for aggr_node\n"); + return NULL; + } + + p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!p_aggr->aggr_conn) { + ath6kl_err("failed to alloc memory for connection specific aggr info\n"); + kfree(p_aggr); + return NULL; + } + + aggr_conn_init(vif, p_aggr->aggr_conn); + + skb_queue_head_init(&p_aggr->rx_amsdu_freeq); + ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS); + return p_aggr; } @@ -1671,27 +1695,32 @@ void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) { struct aggr_info *p_aggr = vif->aggr_cntxt; struct rxtid *rxtid; + struct aggr_info_conn *aggr_conn; - if (!p_aggr) + if (!p_aggr || !p_aggr->aggr_conn) return; - rxtid = &p_aggr->rx_tid[tid]; + aggr_conn = p_aggr->aggr_conn; + rxtid = &aggr_conn->rx_tid[tid]; if (rxtid->aggr) - aggr_delete_tid_state(p_aggr, tid); + aggr_delete_tid_state(aggr_conn, tid); } void aggr_reset_state(struct aggr_info *aggr_info) { u8 tid; - if (aggr_info->timer_scheduled) { - del_timer(&aggr_info->timer); - aggr_info->timer_scheduled = false; + if (!aggr_info || !aggr_info->aggr_conn) + return; + + if (aggr_info->aggr_conn->timer_scheduled) { + del_timer(&aggr_info->aggr_conn->timer); + aggr_info->aggr_conn->timer_scheduled = false; } for (tid = 0; tid < NUM_OF_TIDS; tid++) - aggr_delete_tid_state(aggr_info, tid); + aggr_delete_tid_state(aggr_info->aggr_conn, tid); } /* clean up our amsdu buffer list */ @@ -1718,28 +1747,11 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) void aggr_module_destroy(struct aggr_info *aggr_info) { - struct rxtid *rxtid; - u8 i, k; - - if (!aggr_info) + if (!aggr_info || !aggr_info->aggr_conn) return; - if (aggr_info->timer_scheduled) { - del_timer(&aggr_info->timer); - aggr_info->timer_scheduled = false; - } - - for (i = 0; i < NUM_OF_TIDS; i++) { - rxtid = &aggr_info->rx_tid[i]; - if (rxtid->hold_q) { - for (k = 0; k < rxtid->hold_q_sz; k++) - dev_kfree_skb(rxtid->hold_q[k].skb); - kfree(rxtid->hold_q); - } - - skb_queue_purge(&rxtid->q); - } - - skb_queue_purge(&aggr_info->free_q); + aggr_reset_state(aggr_info); + skb_queue_purge(&aggr_info->rx_amsdu_freeq); + kfree(aggr_info->aggr_conn); kfree(aggr_info); } -- cgit v1.2.3-70-g09d2 From 17741c8db4f53200a51600d1644ee6a2b76f0984 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:51 +0530 Subject: ath6kl: Pass vif instead of ar to ath6kl_add_new_sta() This will be used when initializing station specific aggregation information. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/main.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 3a3b2cc9940..acb4acb7171 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -52,10 +52,11 @@ struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid) return conn; } -static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie, - size_t ielen, u8 keymgmt, u8 ucipher, u8 auth, - u8 apsd_info) +static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, + u8 *wpaie, size_t ielen, u8 keymgmt, + u8 ucipher, u8 auth, u8 apsd_info) { + struct ath6kl *ar = vif->ar; struct ath6kl_sta *sta; u8 free_slot; @@ -430,7 +431,6 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, u8 keymgmt, u8 ucipher, u8 auth, u8 assoc_req_len, u8 *assoc_info, u8 apsd_info) { - struct ath6kl *ar = vif->ar; u8 *ies = NULL, *wpa_ie = NULL, *pos; size_t ies_len = 0; struct station_info sinfo; @@ -484,7 +484,7 @@ void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr, pos += 2 + pos[1]; } - ath6kl_add_new_sta(ar, mac_addr, aid, wpa_ie, + ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie, wpa_ie ? 2 + wpa_ie[1] : 0, keymgmt, ucipher, auth, apsd_info); -- cgit v1.2.3-70-g09d2 From 3fdc099109e75359e5de54c56478c06255850741 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:52 +0530 Subject: ath6kl: Fix bug in using tid given by addba/delba req events The tid which is given in addba/delba req event is not just tid but also muxed with the assoc id (MSB 4 bits) which can be used to determine the corresponding connected station in softap mode. The actual tid is LSB 4 bits. Using the tid as it is with rx_tid[] would result in OOB or invalid memory access in AP mode. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/txrx.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 8407d0103dc..8cf7b2fa0f4 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -17,6 +17,17 @@ #include "core.h" #include "debug.h" +/* + * tid - tid_mux0..tid_mux3 + * aid - tid_mux4..tid_mux7 + */ +#define ATH6KL_TID_MASK 0xf + +static inline u8 ath6kl_get_tid(u8 tid_mux) +{ + return tid_mux & ATH6KL_TID_MASK; +} + static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *map_no) { @@ -1602,7 +1613,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) memset(stats, 0, sizeof(struct rxtid_stats)); } -void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, +void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, u8 win_sz) { struct aggr_info *p_aggr = vif->aggr_cntxt; @@ -1610,12 +1621,17 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid, u16 seq_no, struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; + u8 tid; if (!p_aggr || !p_aggr->aggr_conn) return; aggr_conn = p_aggr->aggr_conn; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + rxtid = &aggr_conn->rx_tid[tid]; stats = &aggr_conn->stat[tid]; @@ -1691,15 +1707,20 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) return p_aggr; } -void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid) +void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) { struct aggr_info *p_aggr = vif->aggr_cntxt; struct rxtid *rxtid; struct aggr_info_conn *aggr_conn; + u8 tid; if (!p_aggr || !p_aggr->aggr_conn) return; + tid = ath6kl_get_tid(tid_mux); + if (tid >= NUM_OF_TIDS) + return; + aggr_conn = p_aggr->aggr_conn; rxtid = &aggr_conn->rx_tid[tid]; -- cgit v1.2.3-70-g09d2 From 1d2a4456de20db73362c86c88fe9c02169f29d0a Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Sat, 21 Jan 2012 15:22:53 +0530 Subject: ath6kl: Fix bug in maintaining aggregation state in AP mode Currently rx aggregation related states are maintained per vif, but this will not properly work when operating in AP mode. Aggregation is completely broken when more than one 11n stations are connected to AP mode vif. Fix this issue by keeping station specific aggregation state in sta_list. Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 5 ++ drivers/net/wireless/ath/ath6kl/core.c | 7 ++ drivers/net/wireless/ath/ath6kl/core.h | 4 +- drivers/net/wireless/ath/ath6kl/init.c | 4 ++ drivers/net/wireless/ath/ath6kl/main.c | 7 +- drivers/net/wireless/ath/ath6kl/txrx.c | 106 ++++++++++++++++++----------- 6 files changed, 88 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 8bf447a6a84..fed7b8077f5 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -2871,6 +2871,11 @@ struct ath6kl *ath6kl_cfg80211_create(void) /* Note: ar variable must not be accessed after calling this! */ void ath6kl_cfg80211_destroy(struct ath6kl *ar) { + int i; + + for (i = 0; i < AP_MAX_NUM_STA; i++) + kfree(ar->sta_list[i].aggr_conn); + wiphy_free(ar->wiphy); } diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index d764afec395..0d92e7179f8 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -253,6 +253,13 @@ struct ath6kl *ath6kl_core_create(struct device *dev) spin_lock_init(&ar->sta_list[ctr].psq_lock); skb_queue_head_init(&ar->sta_list[ctr].psq); skb_queue_head_init(&ar->sta_list[ctr].apsdq); + ar->sta_list[ctr].aggr_conn = + kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL); + if (!ar->sta_list[ctr].aggr_conn) { + ath6kl_err("Failed to allocate memory for sta aggregation information\n"); + ath6kl_core_destroy(ar); + return NULL; + } } skb_queue_head_init(&ar->mcastpsq); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 1b9054f8f4e..ed9fcc11b5f 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -298,6 +298,7 @@ struct ath6kl_sta { spinlock_t psq_lock; u8 apsd_info; struct sk_buff_head apsdq; + struct aggr_info_conn *aggr_conn; }; struct ath6kl_version { @@ -713,6 +714,7 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); struct aggr_info *aggr_init(struct ath6kl_vif *vif); +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); @@ -720,7 +722,7 @@ struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target, enum htc_endpoint_id endpoint, int len); void aggr_module_destroy(struct aggr_info *aggr_info); -void aggr_reset_state(struct aggr_info *aggr_info); +void aggr_reset_state(struct aggr_info_conn *aggr_conn); struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 * node_addr); struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid); diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 167dc41af2d..4d8eb1cca6e 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1660,6 +1660,7 @@ void ath6kl_cleanup_vif(struct ath6kl_vif *vif, bool wmi_ready) void ath6kl_stop_txrx(struct ath6kl *ar) { struct ath6kl_vif *vif, *tmp_vif; + int i; set_bit(DESTROY_IN_PROGRESS, &ar->flag); @@ -1668,6 +1669,9 @@ void ath6kl_stop_txrx(struct ath6kl *ar) return; } + for (i = 0; i < AP_MAX_NUM_STA; i++) + aggr_reset_state(ar->sta_list[i].aggr_conn); + spin_lock_bh(&ar->list_lock); list_for_each_entry_safe(vif, tmp_vif, &ar->vif_list, list) { list_del(&vif->list); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index acb4acb7171..39da1f98da8 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -74,6 +74,7 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); + aggr_conn_init(vif, sta->aggr_conn); } static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) @@ -94,7 +95,7 @@ static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) sta->sta_flags = 0; ar->sta_list_index = ar->sta_list_index & ~(1 << i); - + aggr_reset_state(sta->aggr_conn); } static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason) @@ -602,7 +603,7 @@ void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid, netif_carrier_on(vif->ndev); spin_unlock_bh(&vif->if_lock); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); vif->reconnect_flag = 0; if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) { @@ -924,7 +925,7 @@ void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid, assoc_resp_len, assoc_info, prot_reason_status); - aggr_reset_state(vif->aggr_cntxt); + aggr_reset_state(vif->aggr_cntxt->aggr_conn); del_timer(&vif->disconnect_timer); diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 8cf7b2fa0f4..62c12102e14 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -22,12 +22,18 @@ * aid - tid_mux4..tid_mux7 */ #define ATH6KL_TID_MASK 0xf +#define ATH6KL_AID_SHIFT 4 static inline u8 ath6kl_get_tid(u8 tid_mux) { return tid_mux & ATH6KL_TID_MASK; } +static inline u8 ath6kl_get_aid(u8 tid_mux) +{ + return tid_mux >> ATH6KL_AID_SHIFT; +} + static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *map_no) { @@ -1003,7 +1009,7 @@ static void aggr_slice_amsdu(struct aggr_info *p_aggr, dev_kfree_skb(skb); } -static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, +static void aggr_deque_frms(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, u8 order) { struct sk_buff *skb; @@ -1011,12 +1017,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, struct skb_hold_q *node; u16 idx, idx_end, seq_end; struct rxtid_stats *stats; - struct aggr_info_conn *agg_conn; - if (!p_aggr || !p_aggr->aggr_conn) - return; - - agg_conn = p_aggr->aggr_conn; rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; @@ -1047,7 +1048,8 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, if (node->skb) { if (node->is_amsdu) - aggr_slice_amsdu(p_aggr, rxtid, node->skb); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, + node->skb); else skb_queue_tail(&rxtid->q, node->skb); node->skb = NULL; @@ -1066,7 +1068,7 @@ static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb); } -static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, +static bool aggr_process_recv_frm(struct aggr_info_conn *agg_conn, u8 tid, u16 seq_no, bool is_amsdu, struct sk_buff *frame) { @@ -1077,7 +1079,6 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, u16 idx, st, cur, end; bool is_queued = false; u16 extended_end; - struct aggr_info_conn *agg_conn = agg_info->aggr_conn; rxtid = &agg_conn->rx_tid[tid]; stats = &agg_conn->stat[tid]; @@ -1086,7 +1087,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, if (!rxtid->aggr) { if (is_amsdu) { - aggr_slice_amsdu(agg_info, rxtid, frame); + aggr_slice_amsdu(agg_conn->aggr_info, rxtid, frame); is_queued = true; stats->num_amsdu++; while ((skb = skb_dequeue(&rxtid->q))) @@ -1110,7 +1111,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, (cur < end || cur > extended_end)) || ((end > extended_end) && (cur > extended_end) && (cur < end))) { - aggr_deque_frms(agg_info, tid, 0, 0); + aggr_deque_frms(agg_conn, tid, 0, 0); if (cur >= rxtid->hold_q_sz - 1) rxtid->seq_next = cur - (rxtid->hold_q_sz - 1); else @@ -1127,7 +1128,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, st = ATH6KL_MAX_SEQ_NO - (rxtid->hold_q_sz - 2 - cur); - aggr_deque_frms(agg_info, tid, st, 0); + aggr_deque_frms(agg_conn, tid, st, 0); } stats->num_oow++; @@ -1166,7 +1167,7 @@ static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid, spin_unlock_bh(&rxtid->lock); - aggr_deque_frms(agg_info, tid, 0, 1); + aggr_deque_frms(agg_conn, tid, 0, 1); if (agg_conn->timer_scheduled) rxtid->progress = true; @@ -1278,6 +1279,7 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) struct sk_buff *skb1 = NULL; struct ethhdr *datap = NULL; struct ath6kl_vif *vif; + struct aggr_info_conn *aggr_conn; u16 seq_no, offset; u8 tid, if_idx; @@ -1529,11 +1531,21 @@ void ath6kl_rx(struct htc_target *target, struct htc_packet *packet) datap = (struct ethhdr *) skb->data; - if (is_unicast_ether_addr(datap->h_dest) && - aggr_process_recv_frm(vif->aggr_cntxt, tid, seq_no, - is_amsdu, skb)) - /* aggregation code will handle the skb */ - return; + if (is_unicast_ether_addr(datap->h_dest)) { + if (vif->nw_type == AP_NETWORK) { + conn = ath6kl_find_sta(vif, datap->h_source); + if (!conn) + return; + aggr_conn = conn->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; + + if (aggr_process_recv_frm(aggr_conn, tid, seq_no, + is_amsdu, skb)) { + /* aggregation code will handle the skb */ + return; + } + } ath6kl_deliver_frames_to_nw_stack(vif->ndev, skb); } @@ -1558,7 +1570,7 @@ static void aggr_timeout(unsigned long arg) rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO)); - aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0); + aggr_deque_frms(aggr_conn, i, 0, 0); } aggr_conn->timer_scheduled = false; @@ -1598,7 +1610,7 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) stats = &aggr_conn->stat[tid]; if (rxtid->aggr) - aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0); + aggr_deque_frms(aggr_conn, tid, 0, 0); rxtid->aggr = false; rxtid->progress = false; @@ -1616,17 +1628,23 @@ static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid) void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, u8 win_sz) { - struct aggr_info *p_aggr = vif->aggr_cntxt; - struct aggr_info_conn *aggr_conn; + struct ath6kl_sta *sta; + struct aggr_info_conn *aggr_conn = NULL; struct rxtid *rxtid; struct rxtid_stats *stats; u16 hold_q_size; - u8 tid; + u8 tid, aid; - if (!p_aggr || !p_aggr->aggr_conn) - return; + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; - aggr_conn = p_aggr->aggr_conn; + if (!aggr_conn) + return; tid = ath6kl_get_tid(tid_mux); if (tid >= NUM_OF_TIDS) @@ -1656,8 +1674,7 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, rxtid->aggr = true; } -static void aggr_conn_init(struct ath6kl_vif *vif, - struct aggr_info_conn *aggr_conn) +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) { struct rxtid *rxtid; u8 i; @@ -1709,39 +1726,46 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) void aggr_recv_delba_req_evt(struct ath6kl_vif *vif, u8 tid_mux) { - struct aggr_info *p_aggr = vif->aggr_cntxt; + struct ath6kl_sta *sta; struct rxtid *rxtid; - struct aggr_info_conn *aggr_conn; - u8 tid; + struct aggr_info_conn *aggr_conn = NULL; + u8 tid, aid; + + if (vif->nw_type == AP_NETWORK) { + aid = ath6kl_get_aid(tid_mux); + sta = ath6kl_find_sta_by_aid(vif->ar, aid); + if (sta) + aggr_conn = sta->aggr_conn; + } else + aggr_conn = vif->aggr_cntxt->aggr_conn; - if (!p_aggr || !p_aggr->aggr_conn) + if (!aggr_conn) return; tid = ath6kl_get_tid(tid_mux); if (tid >= NUM_OF_TIDS) return; - aggr_conn = p_aggr->aggr_conn; rxtid = &aggr_conn->rx_tid[tid]; if (rxtid->aggr) aggr_delete_tid_state(aggr_conn, tid); } -void aggr_reset_state(struct aggr_info *aggr_info) +void aggr_reset_state(struct aggr_info_conn *aggr_conn) { u8 tid; - if (!aggr_info || !aggr_info->aggr_conn) + if (!aggr_conn) return; - if (aggr_info->aggr_conn->timer_scheduled) { - del_timer(&aggr_info->aggr_conn->timer); - aggr_info->aggr_conn->timer_scheduled = false; + if (aggr_conn->timer_scheduled) { + del_timer(&aggr_conn->timer); + aggr_conn->timer_scheduled = false; } for (tid = 0; tid < NUM_OF_TIDS; tid++) - aggr_delete_tid_state(aggr_info->aggr_conn, tid); + aggr_delete_tid_state(aggr_conn, tid); } /* clean up our amsdu buffer list */ @@ -1768,10 +1792,10 @@ void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar) void aggr_module_destroy(struct aggr_info *aggr_info) { - if (!aggr_info || !aggr_info->aggr_conn) + if (!aggr_info) return; - aggr_reset_state(aggr_info); + aggr_reset_state(aggr_info->aggr_conn); skb_queue_purge(&aggr_info->rx_amsdu_freeq); kfree(aggr_info->aggr_conn); kfree(aggr_info); -- cgit v1.2.3-70-g09d2 From 8e636784b6f76653d358d521af9c2a8c246df38b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 22 Jan 2012 01:36:48 +0100 Subject: drm/i915: fixup assert_pipe to take the pipe A quirk into account This was completely spamming dmesg on my i855gm. This issue was just shortly introduced with: commit 931872fceabacf2d4f8b6fbd51611c167e83164c Author: Chris Wilson Date: Mon Jan 16 23:01:13 2012 +0000 drm/i915: Check that plane/pipe is disabled before removing the fb Reviewed-by: Jesse Barnes Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cfd3a87807f..ebb34524490 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -936,6 +936,10 @@ void assert_pipe(struct drm_i915_private *dev_priv, u32 val; bool cur_state; + /* if we need the pipe A quirk it must be always on */ + if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) + state = true; + reg = PIPECONF(pipe); val = I915_READ(reg); cur_state = !!(val & PIPECONF_ENABLE); -- cgit v1.2.3-70-g09d2 From b0f70292053a0f68f406564a721a7a3f2d66b44f Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:23 +0100 Subject: ssb: SPROM: extract each core power info MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already extract some basic info but it's incomplete, reads info about the first core only. Used data structure doesn't allow easy adding of more cores. This patch adds new struct and array for storing power info. The plan is to: switch all extractors (including the ones using NVRAM) to new struct, switch drivers, then deprecate and finally drop old SSB fields. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/ssb/pci.c | 40 +++++++++++++++++++++++++++++++++++++++- include/linux/ssb/ssb.h | 8 ++++++++ include/linux/ssb/ssb_regs.h | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c index 973223f5de8..befa89eac6f 100644 --- a/drivers/ssb/pci.c +++ b/drivers/ssb/pci.c @@ -523,7 +523,13 @@ static void sprom_extract_r45(struct ssb_sprom *out, const u16 *in) static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) { int i; - u16 v; + u16 v, o; + u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 + }; + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(out->core_pwr_info)); /* extract the MAC address */ for (i = 0; i < 3; i++) { @@ -607,6 +613,38 @@ static void sprom_extract_r8(struct ssb_sprom *out, const u16 *in) memcpy(&out->antenna_gain.ghz5, &out->antenna_gain.ghz24, sizeof(out->antenna_gain.ghz5)); + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + o = pwr_info_offset[i]; + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } + /* Extract FEM info */ SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index dcf35b0f303..bbc2612cb64 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -16,6 +16,12 @@ struct pcmcia_device; struct ssb_bus; struct ssb_driver; +struct ssb_sprom_core_pwr_info { + u8 itssi_2g, itssi_5g; + u8 maxpwr_2g, maxpwr_5gl, maxpwr_5g, maxpwr_5gh; + u16 pa_2g[3], pa_5gl[3], pa_5g[3], pa_5gh[3]; +}; + struct ssb_sprom { u8 revision; u8 il0mac[6]; /* MAC address for 802.11b/g */ @@ -82,6 +88,8 @@ struct ssb_sprom { u16 boardflags2_hi; /* Board flags (bits 48-63) */ /* TODO store board flags in a single u64 */ + struct ssb_sprom_core_pwr_info core_pwr_info[4]; + /* Antenna gain values for up to 4 antennas * on each band. Values in dBm/4 (Q5.2). Negative gain means the * loss in the connectors is bigger than the gain. */ diff --git a/include/linux/ssb/ssb_regs.h b/include/linux/ssb/ssb_regs.h index c814ae6eeb2..40b1ef8595e 100644 --- a/include/linux/ssb/ssb_regs.h +++ b/include/linux/ssb/ssb_regs.h @@ -449,6 +449,39 @@ #define SSB_SPROM8_TS_SLP_OPT_CORRX 0x00B6 #define SSB_SPROM8_FOC_HWIQ_IQSWP 0x00B8 #define SSB_SPROM8_PHYCAL_TEMPDELTA 0x00BA + +/* There are 4 blocks with power info sharing the same layout */ +#define SSB_SROM8_PWR_INFO_CORE0 0x00C0 +#define SSB_SROM8_PWR_INFO_CORE1 0x00E0 +#define SSB_SROM8_PWR_INFO_CORE2 0x0100 +#define SSB_SROM8_PWR_INFO_CORE3 0x0120 + +#define SSB_SROM8_2G_MAXP_ITSSI 0x00 +#define SSB_SPROM8_2G_MAXP 0x00FF +#define SSB_SPROM8_2G_ITSSI 0xFF00 +#define SSB_SPROM8_2G_ITSSI_SHIFT 8 +#define SSB_SROM8_2G_PA_0 0x02 /* 2GHz power amp settings */ +#define SSB_SROM8_2G_PA_1 0x04 +#define SSB_SROM8_2G_PA_2 0x06 +#define SSB_SROM8_5G_MAXP_ITSSI 0x08 /* 5GHz ITSSI and 5.3GHz Max Power */ +#define SSB_SPROM8_5G_MAXP 0x00FF +#define SSB_SPROM8_5G_ITSSI 0xFF00 +#define SSB_SPROM8_5G_ITSSI_SHIFT 8 +#define SSB_SPROM8_5GHL_MAXP 0x0A /* 5.2GHz and 5.8GHz Max Power */ +#define SSB_SPROM8_5GH_MAXP 0x00FF +#define SSB_SPROM8_5GL_MAXP 0xFF00 +#define SSB_SPROM8_5GL_MAXP_SHIFT 8 +#define SSB_SROM8_5G_PA_0 0x0C /* 5.3GHz power amp settings */ +#define SSB_SROM8_5G_PA_1 0x0E +#define SSB_SROM8_5G_PA_2 0x10 +#define SSB_SROM8_5GL_PA_0 0x12 /* 5.2GHz power amp settings */ +#define SSB_SROM8_5GL_PA_1 0x14 +#define SSB_SROM8_5GL_PA_2 0x16 +#define SSB_SROM8_5GH_PA_0 0x18 /* 5.8GHz power amp settings */ +#define SSB_SROM8_5GH_PA_1 0x1A +#define SSB_SROM8_5GH_PA_2 0x1C + +/* TODO: Make it deprecated */ #define SSB_SPROM8_MAXP_BG 0x00C0 /* Max Power 2GHz in path 1 */ #define SSB_SPROM8_MAXP_BG_MASK 0x00FF /* Mask for Max Power 2GHz */ #define SSB_SPROM8_ITSSI_BG 0xFF00 /* Mask for path 1 itssi_bg */ @@ -473,6 +506,7 @@ #define SSB_SPROM8_PA1HIB0 0x00D8 /* 5.8GHz power amp settings */ #define SSB_SPROM8_PA1HIB1 0x00DA #define SSB_SPROM8_PA1HIB2 0x00DC + #define SSB_SPROM8_CCK2GPO 0x0140 /* CCK power offset */ #define SSB_SPROM8_OFDM2GPO 0x0142 /* 2.4GHz OFDM power offset */ #define SSB_SPROM8_OFDM5GPO 0x0146 /* 5.3GHz OFDM power offset */ -- cgit v1.2.3-70-g09d2 From b35a9aca631ee0cf67cd23098ea9076ca33c3f7b Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:24 +0100 Subject: bcma: SPROM: add macro for easier extraction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 139 ++++++++++++++++++++++++++------------------------- 1 file changed, 71 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 6f230fb087c..27f62cc2c8a 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -14,8 +14,6 @@ #include #include -#define SPOFF(offset) ((offset) / sizeof(u16)) - /************************************************** * R/W ops. **************************************************/ @@ -124,6 +122,11 @@ static int bcma_sprom_valid(const u16 *sprom) * SPROM extraction. **************************************************/ +#define SPOFF(offset) ((offset) / sizeof(u16)) + +#define SPEX(_field, _offset, _mask, _shift) \ + bus->sprom._field = ((sprom[SPOFF(_offset)] & (_mask)) >> (_shift)) + static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { u16 v; @@ -137,72 +140,72 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) *(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v); } - bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)]; - - bus->sprom.txpid2g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & - SSB_SPROM4_TXPID2G0) >> SSB_SPROM4_TXPID2G0_SHIFT; - bus->sprom.txpid2g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID2G01)] & - SSB_SPROM4_TXPID2G1) >> SSB_SPROM4_TXPID2G1_SHIFT; - bus->sprom.txpid2g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & - SSB_SPROM4_TXPID2G2) >> SSB_SPROM4_TXPID2G2_SHIFT; - bus->sprom.txpid2g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID2G23)] & - SSB_SPROM4_TXPID2G3) >> SSB_SPROM4_TXPID2G3_SHIFT; - - bus->sprom.txpid5gl[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & - SSB_SPROM4_TXPID5GL0) >> SSB_SPROM4_TXPID5GL0_SHIFT; - bus->sprom.txpid5gl[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL01)] & - SSB_SPROM4_TXPID5GL1) >> SSB_SPROM4_TXPID5GL1_SHIFT; - bus->sprom.txpid5gl[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & - SSB_SPROM4_TXPID5GL2) >> SSB_SPROM4_TXPID5GL2_SHIFT; - bus->sprom.txpid5gl[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GL23)] & - SSB_SPROM4_TXPID5GL3) >> SSB_SPROM4_TXPID5GL3_SHIFT; - - bus->sprom.txpid5g[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & - SSB_SPROM4_TXPID5G0) >> SSB_SPROM4_TXPID5G0_SHIFT; - bus->sprom.txpid5g[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5G01)] & - SSB_SPROM4_TXPID5G1) >> SSB_SPROM4_TXPID5G1_SHIFT; - bus->sprom.txpid5g[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & - SSB_SPROM4_TXPID5G2) >> SSB_SPROM4_TXPID5G2_SHIFT; - bus->sprom.txpid5g[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5G23)] & - SSB_SPROM4_TXPID5G3) >> SSB_SPROM4_TXPID5G3_SHIFT; - - bus->sprom.txpid5gh[0] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & - SSB_SPROM4_TXPID5GH0) >> SSB_SPROM4_TXPID5GH0_SHIFT; - bus->sprom.txpid5gh[1] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH01)] & - SSB_SPROM4_TXPID5GH1) >> SSB_SPROM4_TXPID5GH1_SHIFT; - bus->sprom.txpid5gh[2] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & - SSB_SPROM4_TXPID5GH2) >> SSB_SPROM4_TXPID5GH2_SHIFT; - bus->sprom.txpid5gh[3] = (sprom[SPOFF(SSB_SPROM4_TXPID5GH23)] & - SSB_SPROM4_TXPID5GH3) >> SSB_SPROM4_TXPID5GH3_SHIFT; - - bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)]; - bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)]; - bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)]; - bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)]; - - bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)]; - - bus->sprom.fem.ghz2.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; - bus->sprom.fem.ghz2.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; - bus->sprom.fem.ghz2.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; - bus->sprom.fem.ghz2.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; - bus->sprom.fem.ghz2.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM2G)] & - SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; - - bus->sprom.fem.ghz5.tssipos = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_TSSIPOS) >> SSB_SROM8_FEM_TSSIPOS_SHIFT; - bus->sprom.fem.ghz5.extpa_gain = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_EXTPA_GAIN) >> SSB_SROM8_FEM_EXTPA_GAIN_SHIFT; - bus->sprom.fem.ghz5.pdet_range = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_PDET_RANGE) >> SSB_SROM8_FEM_PDET_RANGE_SHIFT; - bus->sprom.fem.ghz5.tr_iso = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_TR_ISO) >> SSB_SROM8_FEM_TR_ISO_SHIFT; - bus->sprom.fem.ghz5.antswlut = (sprom[SPOFF(SSB_SPROM8_FEM5G)] & - SSB_SROM8_FEM_ANTSWLUT) >> SSB_SROM8_FEM_ANTSWLUT_SHIFT; + SPEX(board_rev, SSB_SPROM8_BOARDREV, ~0, 0); + + SPEX(txpid2g[0], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G0, + SSB_SPROM4_TXPID2G0_SHIFT); + SPEX(txpid2g[1], SSB_SPROM4_TXPID2G01, SSB_SPROM4_TXPID2G1, + SSB_SPROM4_TXPID2G1_SHIFT); + SPEX(txpid2g[2], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G2, + SSB_SPROM4_TXPID2G2_SHIFT); + SPEX(txpid2g[3], SSB_SPROM4_TXPID2G23, SSB_SPROM4_TXPID2G3, + SSB_SPROM4_TXPID2G3_SHIFT); + + SPEX(txpid5gl[0], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL0, + SSB_SPROM4_TXPID5GL0_SHIFT); + SPEX(txpid5gl[1], SSB_SPROM4_TXPID5GL01, SSB_SPROM4_TXPID5GL1, + SSB_SPROM4_TXPID5GL1_SHIFT); + SPEX(txpid5gl[2], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL2, + SSB_SPROM4_TXPID5GL2_SHIFT); + SPEX(txpid5gl[3], SSB_SPROM4_TXPID5GL23, SSB_SPROM4_TXPID5GL3, + SSB_SPROM4_TXPID5GL3_SHIFT); + + SPEX(txpid5g[0], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G0, + SSB_SPROM4_TXPID5G0_SHIFT); + SPEX(txpid5g[1], SSB_SPROM4_TXPID5G01, SSB_SPROM4_TXPID5G1, + SSB_SPROM4_TXPID5G1_SHIFT); + SPEX(txpid5g[2], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G2, + SSB_SPROM4_TXPID5G2_SHIFT); + SPEX(txpid5g[3], SSB_SPROM4_TXPID5G23, SSB_SPROM4_TXPID5G3, + SSB_SPROM4_TXPID5G3_SHIFT); + + SPEX(txpid5gh[0], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH0, + SSB_SPROM4_TXPID5GH0_SHIFT); + SPEX(txpid5gh[1], SSB_SPROM4_TXPID5GH01, SSB_SPROM4_TXPID5GH1, + SSB_SPROM4_TXPID5GH1_SHIFT); + SPEX(txpid5gh[2], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH2, + SSB_SPROM4_TXPID5GH2_SHIFT); + SPEX(txpid5gh[3], SSB_SPROM4_TXPID5GH23, SSB_SPROM4_TXPID5GH3, + SSB_SPROM4_TXPID5GH3_SHIFT); + + SPEX(boardflags_lo, SSB_SPROM8_BFLLO, ~0, 0); + SPEX(boardflags_hi, SSB_SPROM8_BFLHI, ~0, 0); + SPEX(boardflags2_lo, SSB_SPROM8_BFL2LO, ~0, 0); + SPEX(boardflags2_hi, SSB_SPROM8_BFL2HI, ~0, 0); + + SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); + + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, + SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz2.pdet_range, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_PDET_RANGE, + SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz2.tr_iso, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TR_ISO, + SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz2.antswlut, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_ANTSWLUT, + SSB_SROM8_FEM_ANTSWLUT_SHIFT); + + SPEX(fem.ghz5.tssipos, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TSSIPOS, + SSB_SROM8_FEM_TSSIPOS_SHIFT); + SPEX(fem.ghz5.extpa_gain, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_EXTPA_GAIN, + SSB_SROM8_FEM_EXTPA_GAIN_SHIFT); + SPEX(fem.ghz5.pdet_range, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_PDET_RANGE, + SSB_SROM8_FEM_PDET_RANGE_SHIFT); + SPEX(fem.ghz5.tr_iso, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_TR_ISO, + SSB_SROM8_FEM_TR_ISO_SHIFT); + SPEX(fem.ghz5.antswlut, SSB_SPROM8_FEM5G, SSB_SROM8_FEM_ANTSWLUT, + SSB_SROM8_FEM_ANTSWLUT_SHIFT); } int bcma_sprom_get(struct bcma_bus *bus) -- cgit v1.2.3-70-g09d2 From 507f9a71846a3d25d0e5322754da6b65adceda80 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 08:41:25 +0100 Subject: bcma: SPROM: extract power info for cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index 27f62cc2c8a..cb835f026d9 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -129,8 +129,14 @@ static int bcma_sprom_valid(const u16 *sprom) static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) { - u16 v; + u16 v, o; int i; + u16 pwr_info_offset[] = { + SSB_SROM8_PWR_INFO_CORE0, SSB_SROM8_PWR_INFO_CORE1, + SSB_SROM8_PWR_INFO_CORE2, SSB_SROM8_PWR_INFO_CORE3 + }; + BUILD_BUG_ON(ARRAY_SIZE(pwr_info_offset) != + ARRAY_SIZE(bus->sprom.core_pwr_info)); bus->sprom.revision = sprom[SSB_SPROMSIZE_WORDS_R4 - 1] & SSB_SPROM_REVISION_REV; @@ -185,6 +191,38 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom) SPEX(country_code, SSB_SPROM8_CCODE, ~0, 0); + /* Extract cores power info info */ + for (i = 0; i < ARRAY_SIZE(pwr_info_offset); i++) { + o = pwr_info_offset[i]; + SPEX(core_pwr_info[i].itssi_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_ITSSI, SSB_SPROM8_2G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_2g, o + SSB_SROM8_2G_MAXP_ITSSI, + SSB_SPROM8_2G_MAXP, 0); + + SPEX(core_pwr_info[i].pa_2g[0], o + SSB_SROM8_2G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[1], o + SSB_SROM8_2G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_2g[2], o + SSB_SROM8_2G_PA_2, ~0, 0); + + SPEX(core_pwr_info[i].itssi_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_ITSSI, SSB_SPROM8_5G_ITSSI_SHIFT); + SPEX(core_pwr_info[i].maxpwr_5g, o + SSB_SROM8_5G_MAXP_ITSSI, + SSB_SPROM8_5G_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gh, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GH_MAXP, 0); + SPEX(core_pwr_info[i].maxpwr_5gl, o + SSB_SPROM8_5GHL_MAXP, + SSB_SPROM8_5GL_MAXP, SSB_SPROM8_5GL_MAXP_SHIFT); + + SPEX(core_pwr_info[i].pa_5gl[0], o + SSB_SROM8_5GL_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[1], o + SSB_SROM8_5GL_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gl[2], o + SSB_SROM8_5GL_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[0], o + SSB_SROM8_5G_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[1], o + SSB_SROM8_5G_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5g[2], o + SSB_SROM8_5G_PA_2, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[0], o + SSB_SROM8_5GH_PA_0, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[1], o + SSB_SROM8_5GH_PA_1, ~0, 0); + SPEX(core_pwr_info[i].pa_5gh[2], o + SSB_SROM8_5GH_PA_2, ~0, 0); + } + SPEX(fem.ghz2.tssipos, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_TSSIPOS, SSB_SROM8_FEM_TSSIPOS_SHIFT); SPEX(fem.ghz2.extpa_gain, SSB_SPROM8_FEM2G, SSB_SROM8_FEM_EXTPA_GAIN, -- cgit v1.2.3-70-g09d2 From 5056635c10151970d87ae256b7f52f056291799e Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 19:31:21 +0100 Subject: b43: add maskset helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/b43.h | 12 +++++++ drivers/net/wireless/b43/main.c | 67 ++++++++++++---------------------------- drivers/net/wireless/b43/phy_n.c | 14 +++------ 3 files changed, 36 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 16e8f805815..835462dc120 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h @@ -999,6 +999,12 @@ static inline void b43_write16(struct b43_wldev *dev, u16 offset, u16 value) dev->dev->write16(dev->dev, offset, value); } +static inline void b43_maskset16(struct b43_wldev *dev, u16 offset, u16 mask, + u16 set) +{ + b43_write16(dev, offset, (b43_read16(dev, offset) & mask) | set); +} + static inline u32 b43_read32(struct b43_wldev *dev, u16 offset) { return dev->dev->read32(dev->dev, offset); @@ -1009,6 +1015,12 @@ static inline void b43_write32(struct b43_wldev *dev, u16 offset, u32 value) dev->dev->write32(dev->dev, offset, value); } +static inline void b43_maskset32(struct b43_wldev *dev, u16 offset, u32 mask, + u32 set) +{ + b43_write32(dev, offset, (b43_read32(dev, offset) & mask) | set); +} + static inline void b43_block_read(struct b43_wldev *dev, void *buffer, size_t count, u16 offset, u8 reg_width) { diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index b91f28ef103..268f2db5237 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -578,22 +578,14 @@ void b43_tsf_read(struct b43_wldev *dev, u64 *tsf) static void b43_time_lock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl |= B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_TBTTHOLD); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } static void b43_time_unlock(struct b43_wldev *dev) { - u32 macctl; - - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_TBTTHOLD; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_TBTTHOLD, 0); /* Commit the write */ b43_read32(dev, B43_MMIO_MACCTL); } @@ -2485,10 +2477,8 @@ static int b43_upload_microcode(struct b43_wldev *dev) b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL); /* Start the microcode PSM */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_JMP0; - macctl |= B43_MACCTL_PSM_RUN; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_JMP0, + B43_MACCTL_PSM_RUN); /* Wait for the microcode to load and respond */ i = 0; @@ -2588,10 +2578,9 @@ static int b43_upload_microcode(struct b43_wldev *dev) return 0; error: - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + /* Stop the microcode PSM. */ + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); return err; } @@ -2706,11 +2695,8 @@ static int b43_gpio_init(struct b43_wldev *dev) struct ssb_device *gpiodev; u32 mask, set; - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_GPOUTSMSK); - - b43_write16(dev, B43_MMIO_GPIO_MASK, b43_read16(dev, B43_MMIO_GPIO_MASK) - | 0x000F); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF); mask = 0x0000001F; set = 0x0000000F; @@ -2798,9 +2784,7 @@ void b43_mac_enable(struct b43_wldev *dev) dev->mac_suspended--; B43_WARN_ON(dev->mac_suspended < 0); if (dev->mac_suspended == 0) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_ENABLED); b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_MAC_SUSPENDED); /* Commit writes */ @@ -2821,9 +2805,7 @@ void b43_mac_suspend(struct b43_wldev *dev) if (dev->mac_suspended == 0) { b43_power_saving_ctl_bits(dev, B43_PS_AWAKE); - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_ENABLED); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_ENABLED, 0); /* force pci to flush the write */ b43_read32(dev, B43_MMIO_MACCTL); for (i = 35; i; i--) { @@ -2929,15 +2911,10 @@ static void b43_adjust_opmode(struct b43_wldev *dev) * so always disable it. If we want to implement PMQ, * we need to enable it here (clear DISCPMQ) in AP mode. */ - if (0 /* ctl & B43_MACCTL_AP */) { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_DISCPMQ); - } else { - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_DISCPMQ); - } + if (0 /* ctl & B43_MACCTL_AP */) + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_DISCPMQ, 0); + else + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_DISCPMQ); } static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm) @@ -3081,10 +3058,8 @@ static int b43_chip_init(struct b43_wldev *dev) if (dev->dev->core_rev < 5) b43_write32(dev, 0x010C, 0x01000000); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - & ~B43_MACCTL_INFRA); - b43_write32(dev, B43_MMIO_MACCTL, b43_read32(dev, B43_MMIO_MACCTL) - | B43_MACCTL_INFRA); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_INFRA, 0); + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, B43_MACCTL_INFRA); /* Probe Response Timeout value */ /* FIXME: Default to 0, has to be set by ioctl probably... :-/ */ @@ -4562,8 +4537,6 @@ static void b43_set_pretbtt(struct b43_wldev *dev) /* Locking: wl->mutex */ static void b43_wireless_core_exit(struct b43_wldev *dev) { - u32 macctl; - B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED); if (!dev || b43_status(dev) != B43_STAT_INITIALIZED) return; @@ -4574,10 +4547,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev) b43_set_status(dev, B43_STAT_UNINIT); /* Stop the microcode PSM. */ - macctl = b43_read32(dev, B43_MMIO_MACCTL); - macctl &= ~B43_MACCTL_PSM_RUN; - macctl |= B43_MACCTL_PSM_JMP0; - b43_write32(dev, B43_MMIO_MACCTL, macctl); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_PSM_RUN, + B43_MACCTL_PSM_JMP0); b43_dma_free(dev); b43_pio_free(dev); diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index bf5a4385535..9530f12c028 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -3968,13 +3968,10 @@ static void b43_nphy_superswitch_init(struct b43_wldev *dev, bool init) #endif } - b43_write32(dev, B43_MMIO_MACCTL, - b43_read32(dev, B43_MMIO_MACCTL) & - ~B43_MACCTL_GPOUTSMSK); - b43_write16(dev, B43_MMIO_GPIO_MASK, - b43_read16(dev, B43_MMIO_GPIO_MASK) | 0xFC00); - b43_write16(dev, B43_MMIO_GPIO_CONTROL, - b43_read16(dev, B43_MMIO_GPIO_CONTROL) & ~0xFC00); + b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); + b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xFC00); + b43_maskset16(dev, B43_MMIO_GPIO_CONTROL, (~0xFC00 & 0xFFFF), + 0); if (init) { b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_LO1, 0x2D8); @@ -4530,8 +4527,7 @@ static void b43_nphy_op_maskset(struct b43_wldev *dev, u16 reg, u16 mask, { check_phyreg(dev, reg); b43_write16(dev, B43_MMIO_PHY_CONTROL, reg); - b43_write16(dev, B43_MMIO_PHY_DATA, - (b43_read16(dev, B43_MMIO_PHY_DATA) & mask) | set); + b43_maskset16(dev, B43_MMIO_PHY_DATA, mask, set); } static u16 b43_nphy_op_radio_read(struct b43_wldev *dev, u16 reg) -- cgit v1.2.3-70-g09d2 From d3fd8bf77affcbf80bb8297d177e17ad0b61abc8 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Mon, 2 Jan 2012 19:31:22 +0100 Subject: b43: N-PHY: implement TX power control setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 217 ++++++++++++++++++++++++++++++++++++++- drivers/net/wireless/b43/phy_n.h | 1 + 2 files changed, 217 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 9530f12c028..fbbdbdad101 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2420,6 +2420,221 @@ static void b43_nphy_tx_power_ctl_idle_tssi(struct b43_wldev *dev) nphy->pwr_ctl_info[1].idle_tssi_2g = (tmp >> 8) & 0xFF; } +/* http://bcm-v4.sipsolutions.net/PHY/N/TxPwrLimitToTbl */ +static void b43_nphy_tx_prepare_adjusted_power_table(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + u8 idx, delta; + u8 i, stf_mode; + + for (i = 0; i < 4; i++) + nphy->adj_pwr_tbl[i] = nphy->tx_power_offset[i]; + + for (stf_mode = 0; stf_mode < 4; stf_mode++) { + delta = 0; + switch (stf_mode) { + case 0: + if (dev->phy.is_40mhz && dev->phy.rev >= 5) { + idx = 68; + } else { + delta = 1; + idx = dev->phy.is_40mhz ? 52 : 4; + } + break; + case 1: + idx = dev->phy.is_40mhz ? 76 : 28; + break; + case 2: + idx = dev->phy.is_40mhz ? 84 : 36; + break; + case 3: + idx = dev->phy.is_40mhz ? 92 : 44; + break; + } + + for (i = 0; i < 20; i++) { + nphy->adj_pwr_tbl[4 + 4 * i + stf_mode] = + nphy->tx_power_offset[idx]; + if (i == 0) + idx += delta; + if (i == 14) + idx += 1 - delta; + if (i == 3 || i == 4 || i == 7 || i == 8 || i == 11 || + i == 13) + idx += 1; + } + } +} + +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlSetup */ +static void b43_nphy_tx_power_ctl_setup(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + s16 a1[2], b0[2], b1[2]; + u8 idle[2]; + s8 target[2]; + s32 num, den, pwr; + u32 regval[64]; + + u16 freq = dev->phy.channel_freq; + u16 tmp; + u16 r; /* routing */ + u8 i, c; + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, true); + + b43_phy_set(dev, B43_NPHY_TSSIMODE, B43_NPHY_TSSIMODE_EN); + if (dev->phy.rev >= 3) + b43_phy_mask(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_PCTLEN & 0xFFFF); + else + b43_phy_set(dev, B43_NPHY_TXPCTL_CMD, + B43_NPHY_TXPCTL_CMD_PCTLEN); + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + if (sprom->revision < 4) { + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_2g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_2g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } else { + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_2g; + target[c] = sprom->core_pwr_info[c].maxpwr_2g; + a1[c] = sprom->core_pwr_info[c].pa_2g[0]; + b0[c] = sprom->core_pwr_info[c].pa_2g[1]; + b1[c] = sprom->core_pwr_info[c].pa_2g[2]; + } + } else if (freq >= 4900 && freq < 5100) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gl; + a1[c] = sprom->core_pwr_info[c].pa_5gl[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gl[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gl[2]; + } + } else if (freq >= 5100 && freq < 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5g; + a1[c] = sprom->core_pwr_info[c].pa_5g[0]; + b0[c] = sprom->core_pwr_info[c].pa_5g[1]; + b1[c] = sprom->core_pwr_info[c].pa_5g[2]; + } + } else if (freq >= 5500) { + for (c = 0; c < 2; c++) { + idle[c] = nphy->pwr_ctl_info[c].idle_tssi_5g; + target[c] = sprom->core_pwr_info[c].maxpwr_5gh; + a1[c] = sprom->core_pwr_info[c].pa_5gh[0]; + b0[c] = sprom->core_pwr_info[c].pa_5gh[1]; + b1[c] = sprom->core_pwr_info[c].pa_5gh[2]; + } + } else { + idle[0] = nphy->pwr_ctl_info[0].idle_tssi_5g; + idle[1] = nphy->pwr_ctl_info[1].idle_tssi_5g; + target[0] = target[1] = 52; + a1[0] = a1[1] = -424; + b0[0] = b0[1] = 5612; + b1[0] = b1[1] = -1393; + } + } + /* target[0] = target[1] = nphy->tx_power_max; */ + + if (dev->phy.rev >= 3) { + if (sprom->fem.ghz2.tssipos) + b43_phy_set(dev, B43_NPHY_TXPCTL_ITSSI, 0x4000); + if (dev->phy.rev >= 7) { + for (c = 0; c < 2; c++) { + r = c ? 0x190 : 0x170; + if (b43_nphy_ipa(dev)) + b43_radio_write(dev, r + 0x9, (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) ? 0xE : 0xC); + } + } else { + if (b43_nphy_ipa(dev)) { + tmp = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ? 0xC : 0xE; + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, tmp); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, tmp); + } else { + b43_radio_write(dev, + B2056_TX0 | B2056_TX_TX_SSI_MUX, 0x11); + b43_radio_write(dev, + B2056_TX1 | B2056_TX_TX_SSI_MUX, 0x11); + } + } + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) { + b43_maskset32(dev, B43_MMIO_MACCTL, ~0, 0x200000); + b43_read32(dev, B43_MMIO_MACCTL); + udelay(1); + } + + if (dev->phy.rev >= 7) { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x19); + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x19); + } else { + b43_phy_maskset(dev, B43_NPHY_TXPCTL_CMD, + ~B43_NPHY_TXPCTL_CMD_INIT, 0x40); + if (dev->phy.rev > 1) + b43_phy_maskset(dev, B43_NPHY_TXPCTL_INIT, + ~B43_NPHY_TXPCTL_INIT_PIDXI1, 0x40); + } + + if (dev->dev->core_rev == 11 || dev->dev->core_rev == 12) + b43_maskset32(dev, B43_MMIO_MACCTL, ~0x200000, 0); + + b43_phy_write(dev, B43_NPHY_TXPCTL_N, + 0xF0 << B43_NPHY_TXPCTL_N_TSSID_SHIFT | + 3 << B43_NPHY_TXPCTL_N_NPTIL2_SHIFT); + b43_phy_write(dev, B43_NPHY_TXPCTL_ITSSI, + idle[0] << B43_NPHY_TXPCTL_ITSSI_0_SHIFT | + idle[1] << B43_NPHY_TXPCTL_ITSSI_1_SHIFT | + B43_NPHY_TXPCTL_ITSSI_BINF); + b43_phy_write(dev, B43_NPHY_TXPCTL_TPWR, + target[0] << B43_NPHY_TXPCTL_TPWR_0_SHIFT | + target[1] << B43_NPHY_TXPCTL_TPWR_1_SHIFT); + + for (c = 0; c < 2; c++) { + for (i = 0; i < 64; i++) { + num = 8 * (16 * b0[c] + b1[c] * i); + den = 32768 + a1[c] * i; + pwr = max((4 * num + den / 2) / den, -8); + if (dev->phy.rev < 3 && (i <= (31 - idle[c] + 1))) + pwr = max(pwr, target[c] + 1); + regval[i] = pwr; + } + b43_ntab_write_bulk(dev, B43_NTAB32(26 + c, 0), 64, regval); + } + + b43_nphy_tx_prepare_adjusted_power_table(dev); + /* + b43_ntab_write_bulk(dev, B43_NTAB16(26, 64), 84, nphy->adj_pwr_tbl); + b43_ntab_write_bulk(dev, B43_NTAB16(27, 64), 84, nphy->adj_pwr_tbl); + */ + + if (nphy->hang_avoid) + b43_nphy_stay_in_carrier_search(dev, false); +} + static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) { struct b43_phy *phy = &dev->phy; @@ -4107,7 +4322,7 @@ int b43_phy_initn(struct b43_wldev *dev) b43_nphy_tx_power_ctrl(dev, false); b43_nphy_tx_power_fix(dev); b43_nphy_tx_power_ctl_idle_tssi(dev); - /* TODO N PHY TX Power Control Setup */ + b43_nphy_tx_power_ctl_setup(dev); b43_nphy_tx_gain_table_upload(dev); if (nphy->phyrxchain != 3) diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h index 5de8f74cc02..fd12b386fea 100644 --- a/drivers/net/wireless/b43/phy_n.h +++ b/drivers/net/wireless/b43/phy_n.h @@ -798,6 +798,7 @@ struct b43_phy_n { bool txpwrctrl; bool pwg_gain_5ghz; u8 tx_pwr_idx[2]; + s8 tx_power_offset[101]; u16 adj_pwr_tbl[84]; u16 txcal_bbmult; u16 txiqlocal_bestc[11]; -- cgit v1.2.3-70-g09d2 From aeab57517cb7995626a60e8d1817fe95e5c07f42 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:17 +0100 Subject: b43: N-PHY: add helper for getting gain table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also move the code to tables file. Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 81 +++------------------------------- drivers/net/wireless/b43/tables_nphy.c | 65 +++++++++++++++++++++++---- drivers/net/wireless/b43/tables_nphy.h | 12 +---- 3 files changed, 64 insertions(+), 94 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index fbbdbdad101..d5d02aed9db 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -85,24 +85,6 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ -static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) -{ - if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { - if (dev->phy.rev >= 6) { - if (dev->dev->chip_id == 47162) - return txpwrctrl_tx_gain_ipa_rev5; - return txpwrctrl_tx_gain_ipa_rev6; - } else if (dev->phy.rev >= 5) { - return txpwrctrl_tx_gain_ipa_rev5; - } else { - return txpwrctrl_tx_gain_ipa; - } - } else { - return txpwrctrl_tx_gain_ipa_5g; - } -} - /************************************************** * RF (just without b43_nphy_rf_control_intc_override) **************************************************/ @@ -2229,27 +2211,12 @@ static void b43_nphy_tx_power_fix(struct b43_wldev *dev) */ for (i = 0; i < 2; i++) { - if (dev->phy.rev >= 3) { - if (b43_nphy_ipa(dev)) { - txgain = *(b43_nphy_get_ipa_gain_table(dev) + - txpi[i]); - } else if (b43_current_band(dev->wl) == - IEEE80211_BAND_5GHZ) { - /* FIXME: use 5GHz tables */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } else { - if (dev->phy.rev >= 5 && - sprom->fem.ghz5.extpa_gain == 3) - ; /* FIXME: 5GHz_txgain_HiPwrEPA */ - txgain = - b43_ntab_tx_gain_rev3plus_2ghz[txpi[i]]; - } + txgain = *(b43_nphy_get_tx_gain_table(dev) + txpi[i]); + + if (dev->phy.rev >= 3) radio_gain = (txgain >> 16) & 0x1FFFF; - } else { - txgain = b43_ntab_tx_gain_rev0_1_2[txpi[i]]; + else radio_gain = (txgain >> 16) & 0x1FFF; - } if (dev->phy.rev >= 7) dac_gain = (txgain >> 8) & 0x7; @@ -2647,24 +2614,7 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) int i; #endif - if (phy->rev >= 3) { - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); - } else { - if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { - if (phy->rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - if (phy->rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; - } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; - } - } - } else { - table = b43_ntab_tx_gain_rev0_1_2; - } + table = b43_nphy_get_tx_gain_table(dev); b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); b43_ntab_write_bulk(dev, B43_NTAB32(27, 192), 128, table); @@ -3354,32 +3304,13 @@ static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev) B43_NPHY_TXPCTL_STAT_BIDX_SHIFT; for (i = 0; i < 2; ++i) { + table = b43_nphy_get_tx_gain_table(dev); if (dev->phy.rev >= 3) { - enum ieee80211_band band = - b43_current_band(dev->wl); - - if (b43_nphy_ipa(dev)) { - table = b43_nphy_get_ipa_gain_table(dev); - } else { - if (band == IEEE80211_BAND_5GHZ) { - if (dev->phy.rev == 3) - table = b43_ntab_tx_gain_rev3_5ghz; - else if (dev->phy.rev == 4) - table = b43_ntab_tx_gain_rev4_5ghz; - else - table = b43_ntab_tx_gain_rev5plus_5ghz; - } else { - table = b43_ntab_tx_gain_rev3plus_2ghz; - } - } - target.ipa[i] = (table[index[i]] >> 16) & 0xF; target.pad[i] = (table[index[i]] >> 20) & 0xF; target.pga[i] = (table[index[i]] >> 24) & 0xF; target.txgm[i] = (table[index[i]] >> 28) & 0xF; } else { - table = b43_ntab_tx_gain_rev0_1_2; - target.ipa[i] = (table[index[i]] >> 16) & 0x3; target.pad[i] = (table[index[i]] >> 18) & 0x3; target.pga[i] = (table[index[i]] >> 20) & 0x7; diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index f7def13524d..afcdca638cc 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2214,7 +2214,7 @@ static const u16 b43_ntab_antswctl2g_r3[4][32] = { }; /* TX gain tables */ -const u32 b43_ntab_tx_gain_rev0_1_2[] = { +static const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42, 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44, 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844, @@ -2249,7 +2249,7 @@ const u32 b43_ntab_tx_gain_rev0_1_2[] = { 0x03801442, 0x03801344, 0x03801342, 0x00002b00, }; -const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { +static const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e, 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037, 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e, @@ -2284,7 +2284,7 @@ const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = { 0x1041003c, 0x1041003b, 0x10410039, 0x10410037, }; -const u32 b43_ntab_tx_gain_rev3_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e, 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037, 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e, @@ -2319,7 +2319,7 @@ const u32 b43_ntab_tx_gain_rev3_5ghz[] = { 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037, }; -const u32 b43_ntab_tx_gain_rev4_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e, 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037, 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e, @@ -2354,7 +2354,7 @@ const u32 b43_ntab_tx_gain_rev4_5ghz[] = { 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034, }; -const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { +static const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044, 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c, 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e, @@ -2389,7 +2389,7 @@ const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = { 0x0062003b, 0x00620039, 0x00620037, 0x00620035, }; -const u32 txpwrctrl_tx_gain_ipa[] = { +static const u32 txpwrctrl_tx_gain_ipa[] = { 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029, 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025, 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029, @@ -2424,7 +2424,7 @@ const u32 txpwrctrl_tx_gain_ipa[] = { 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev5[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029, 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025, 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029, @@ -2459,7 +2459,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev5[] = { 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025, }; -const u32 txpwrctrl_tx_gain_ipa_rev6[] = { +static const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029, 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025, 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029, @@ -2494,7 +2494,7 @@ const u32 txpwrctrl_tx_gain_ipa_rev6[] = { 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025, }; -const u32 txpwrctrl_tx_gain_ipa_5g[] = { +static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031, 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b, 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027, @@ -3126,6 +3126,53 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev) B43_WARN_ON(1); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */ +static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev) +{ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + if (dev->phy.rev >= 6) { + if (dev->dev->chip_id == 47162) + return txpwrctrl_tx_gain_ipa_rev5; + return txpwrctrl_tx_gain_ipa_rev6; + } else if (dev->phy.rev >= 5) { + return txpwrctrl_tx_gain_ipa_rev5; + } else { + return txpwrctrl_tx_gain_ipa; + } + } else { + return txpwrctrl_tx_gain_ipa_5g; + } +} + +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev) +{ + enum ieee80211_band band = b43_current_band(dev->wl); + struct ssb_sprom *sprom = dev->dev->bus_sprom; + + if (dev->phy.rev < 3) + return b43_ntab_tx_gain_rev0_1_2; + + /* rev 3+ */ + if ((dev->phy.n->ipa2g_on && band == IEEE80211_BAND_2GHZ) || + (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)) { + return b43_nphy_get_ipa_gain_table(dev); + } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + if (dev->phy.rev == 3) + return b43_ntab_tx_gain_rev3_5ghz; + if (dev->phy.rev == 4) + return sprom->fem.ghz5.extpa_gain == 3 ? + b43_ntab_tx_gain_rev4_5ghz : + b43_ntab_tx_gain_rev4_5ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev5plus_5ghz; + } else { + if (dev->phy.rev >= 5 && sprom->fem.ghz5.extpa_gain == 3) + return b43_ntab_tx_gain_rev3plus_2ghz; /* FIXME */ + else + return b43_ntab_tx_gain_rev3plus_2ghz; + } +} + struct nphy_gain_ctl_workaround_entry *b43_nphy_get_gain_ctl_workaround_ent( struct b43_wldev *dev, bool ghz5, bool ext_lna) { diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 97038c48193..2a9d5f14af9 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -177,16 +177,8 @@ void b43_ntab_write_bulk(struct b43_wldev *dev, u32 offset, void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev); void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); -extern const u32 b43_ntab_tx_gain_rev0_1_2[]; -extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[]; -extern const u32 b43_ntab_tx_gain_rev3_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev4_5ghz[]; -extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[]; - -extern const u32 txpwrctrl_tx_gain_ipa[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev5[]; -extern const u32 txpwrctrl_tx_gain_ipa_rev6[]; -extern const u32 txpwrctrl_tx_gain_ipa_5g[]; +const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); + extern const u16 tbl_iqcal_gainparams[2][9][8]; extern const struct nphy_txiqcal_ladder ladder_lo[]; extern const struct nphy_txiqcal_ladder ladder_iq[]; -- cgit v1.2.3-70-g09d2 From 603431e9e2cb158817c8403e100bb495755a2395 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:18 +0100 Subject: b43: N-PHY: fix typos in RF control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 6 +++--- drivers/net/wireless/b43/tables_nphy.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index d5d02aed9db..f1a856874a9 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -211,7 +211,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, reg = (i == 0) ? B43_NPHY_RFCTL_INTC1 : B43_NPHY_RFCTL_INTC2; - b43_phy_mask(dev, reg, 0xFBFF); + b43_phy_set(dev, reg, 0x400); switch (field) { case 0: @@ -227,7 +227,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_START)) { j = 0; break; } @@ -246,7 +246,7 @@ static void b43_nphy_rf_control_intc_override(struct b43_wldev *dev, u8 field, b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); for (j = 0; j < 100; j++) { - if (b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX) { + if (!(b43_phy_read(dev, B43_NPHY_RFCTL_CMD) & B43_NPHY_RFCTL_CMD_RXTX)) { j = 0; break; } diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index afcdca638cc..8d96454081a 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2739,11 +2739,11 @@ const struct nphy_rf_control_override_rev3 tbl_rf_control_override_rev3[] = { { 0x0001, 0, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0002 (fls 2) */ { 0x0002, 1, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0004 (fls 3) */ { 0x0004, 2, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0008 (fls 4) */ - { 0x0016, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ + { 0x0010, 4, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0010 (fls 5) */ { 0x0020, 5, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0020 (fls 6) */ { 0x0040, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0040 (fls 7) */ - { 0x0080, 6, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ - { 0x0100, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ + { 0x0080, 7, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0080 (fls 8) */ + { 0x0100, 8, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0100 (fls 9) */ { 0x0007, 0, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0200 (fls 10) */ { 0x0070, 4, 0xE7, 0xF8, 0xEC, 0xFA }, /* field == 0x0400 (fls 11) */ { 0xE000, 13, 0xE7, 0x7A, 0xEC, 0x7D }, /* field == 0x0800 (fls 12) */ -- cgit v1.2.3-70-g09d2 From 34c5cf205ec27e170b7061f43cf6390486be9a78 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:19 +0100 Subject: b43: N-PHY: upload PAPD PGA gain delta table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 11 +++++------ drivers/net/wireless/b43/tables_nphy.c | 5 +++++ drivers/net/wireless/b43/tables_nphy.h | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f1a856874a9..f6ac18139b1 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -2607,12 +2607,9 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) struct b43_phy *phy = &dev->phy; const u32 *table = NULL; -#if 0 - TODO: b43_ntab_papd_pga_gain_delta_ipa_2* u32 rfpwr_offset; u8 pga_gain; int i; -#endif table = b43_nphy_get_tx_gain_table(dev); b43_ntab_write_bulk(dev, B43_NTAB32(26, 192), 128, table); @@ -2621,19 +2618,21 @@ static void b43_nphy_tx_gain_table_upload(struct b43_wldev *dev) if (phy->rev >= 3) { #if 0 nphy->gmval = (table[0] >> 16) & 0x7000; +#endif for (i = 0; i < 128; i++) { pga_gain = (table[i] >> 24) & 0xF; if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; + rfpwr_offset = + b43_ntab_papd_pga_gain_delta_ipa_2g[pga_gain]; else - rfpwr_offset = b43_ntab_papd_pga_gain_delta_ipa_5g[pga_gain]; + rfpwr_offset = + 0; /* FIXME */ b43_ntab_write(dev, B43_NTAB32(26, 576 + i), rfpwr_offset); b43_ntab_write(dev, B43_NTAB32(27, 576 + i), rfpwr_offset); } -#endif } } diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c index 8d96454081a..f0d8377429c 100644 --- a/drivers/net/wireless/b43/tables_nphy.c +++ b/drivers/net/wireless/b43/tables_nphy.c @@ -2529,6 +2529,11 @@ static const u32 txpwrctrl_tx_gain_ipa_5g[] = { 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f, }; +const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[] = { + -114, -108, -98, -91, -84, -78, -70, -62, + -54, -46, -39, -31, -23, -15, -8, 0 +}; + const u16 tbl_iqcal_gainparams[2][9][8] = { { { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 }, diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h index 2a9d5f14af9..f348953c023 100644 --- a/drivers/net/wireless/b43/tables_nphy.h +++ b/drivers/net/wireless/b43/tables_nphy.h @@ -179,6 +179,8 @@ void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev); const u32 *b43_nphy_get_tx_gain_table(struct b43_wldev *dev); +extern const s8 b43_ntab_papd_pga_gain_delta_ipa_2g[]; + extern const u16 tbl_iqcal_gainparams[2][9][8]; extern const struct nphy_txiqcal_ladder ladder_lo[]; extern const struct nphy_txiqcal_ladder ladder_iq[]; -- cgit v1.2.3-70-g09d2 From 3eb1fa7e0021bc03be1bf7f68b1913d959e29512 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 4 Jan 2012 14:52:51 -0800 Subject: brcm80211: make ethtool_ops const All usage of ethtool_ops should be const; also add comma at end of initializer list. Signed-off-by: Stephen Hemminger Acked-by: Arend van Spriel Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index eb9eb766ac2..c3980c50a99 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -590,8 +590,8 @@ static void brcmf_ethtool_get_drvinfo(struct net_device *ndev, sprintf(info->bus_info, "%s", dev_name(drvr->dev)); } -static struct ethtool_ops brcmf_ethtool_ops = { - .get_drvinfo = brcmf_ethtool_get_drvinfo +static const struct ethtool_ops brcmf_ethtool_ops = { + .get_drvinfo = brcmf_ethtool_get_drvinfo, }; static int brcmf_ethtool(struct brcmf_pub *drvr, void __user *uaddr) -- cgit v1.2.3-70-g09d2 From e0c9a0219a8f542e3946fe972a68aacf8c3f906c Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Thu, 5 Jan 2012 01:05:30 +0100 Subject: b43: N-PHY: implement RSSI calibration for rev3+ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 193 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 187 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index f6ac18139b1..945aa5267d0 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -85,6 +85,13 @@ static inline bool b43_nphy_ipa(struct b43_wldev *dev) (dev->phy.n->ipa5g_on && band == IEEE80211_BAND_5GHZ)); } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxCoreGetState */ +static u8 b43_nphy_get_rx_core_state(struct b43_wldev *dev) +{ + return (b43_phy_read(dev, B43_NPHY_RFSEQCA) & B43_NPHY_RFSEQCA_RXEN) >> + B43_NPHY_RFSEQCA_RXEN_SHIFT; +} + /************************************************** * RF (just without b43_nphy_rf_control_intc_override) **************************************************/ @@ -1290,6 +1297,186 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, return out; } +/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ +static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) +{ + struct b43_phy_n *nphy = dev->phy.n; + + u16 saved_regs_phy_rfctl[2]; + u16 saved_regs_phy[13]; + u16 regs_to_store[] = { + B43_NPHY_AFECTL_OVER1, B43_NPHY_AFECTL_OVER, + B43_NPHY_AFECTL_C1, B43_NPHY_AFECTL_C2, + B43_NPHY_TXF_40CO_B1S1, B43_NPHY_RFCTL_OVER, + B43_NPHY_TXF_40CO_B1S0, B43_NPHY_TXF_40CO_B32S1, + B43_NPHY_RFCTL_CMD, + B43_NPHY_RFCTL_LUT_TRSW_UP1, B43_NPHY_RFCTL_LUT_TRSW_UP2, + B43_NPHY_RFCTL_RSSIO1, B43_NPHY_RFCTL_RSSIO2 + }; + + u16 class; + + u16 clip_state[2]; + u16 clip_off[2] = { 0xFFFF, 0xFFFF }; + + u8 vcm_final = 0; + s8 offset[4]; + s32 results[8][4] = { }; + s32 results_min[4] = { }; + s32 poll_results[4] = { }; + + u16 *rssical_radio_regs = NULL; + u16 *rssical_phy_regs = NULL; + + u16 r; /* routing */ + u8 rx_core_state; + u8 core, i, j; + + class = b43_nphy_classifier(dev, 0, 0); + b43_nphy_classifier(dev, 7, 4); + b43_nphy_read_clip_detection(dev, clip_state); + b43_nphy_write_clip_detection(dev, clip_off); + + saved_regs_phy_rfctl[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1); + saved_regs_phy_rfctl[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2); + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + saved_regs_phy[i] = b43_phy_read(dev, regs_to_store[i]); + + b43_nphy_rf_control_intc_override(dev, 0, 0, 7); + b43_nphy_rf_control_intc_override(dev, 1, 1, 7); + b43_nphy_rf_control_override(dev, 0x1, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x2, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x80, 1, 0, false); + b43_nphy_rf_control_override(dev, 0x40, 1, 0, false); + + if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { + b43_nphy_rf_control_override(dev, 0x20, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x10, 1, 0, false); + } else { + b43_nphy_rf_control_override(dev, 0x10, 0, 0, false); + b43_nphy_rf_control_override(dev, 0x20, 1, 0, false); + } + + rx_core_state = b43_nphy_get_rx_core_state(dev); + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + r = core ? B2056_RX1 : B2056_RX0; + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, 2); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, 2); + for (i = 0; i < 8; i++) { + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + i << 2); + b43_nphy_poll_rssi(dev, 2, results[i], 8); + } + for (i = 0; i < 4; i++) { + s32 curr; + s32 mind = 40; + s32 minpoll = 249; + u8 minvcm = 0; + if (2 * core != i) + continue; + for (j = 0; j < 8; j++) { + curr = results[j][i] * results[j][i] + + results[j][i + 1] * results[j][i]; + if (curr < mind) { + mind = curr; + minvcm = j; + } + if (results[j][i] < minpoll) + minpoll = results[j][i]; + } + vcm_final = minvcm; + results_min[i] = minpoll; + } + b43_radio_maskset(dev, r | B2056_RX_RSSI_MISC, 0xE3, + vcm_final << 2); + for (i = 0; i < 4; i++) { + if (core != i / 2) + continue; + offset[i] = -results[vcm_final][i]; + if (offset[i] < 0) + offset[i] = -((abs(offset[i]) + 4) / 8); + else + offset[i] = (offset[i] + 4) / 8; + if (results_min[i] == 248) + offset[i] = -32; + b43_nphy_scale_offset_rssi(dev, 0, offset[i], + (i / 2 == 0) ? 1 : 2, + (i % 2 == 0) ? 0 : 1, + 2); + } + } + for (core = 0; core < 2; core++) { + if (!(rx_core_state & (1 << core))) + continue; + for (i = 0; i < 2; i++) { + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 0, i); + b43_nphy_scale_offset_rssi(dev, 0, 0, core + 1, 1, i); + b43_nphy_poll_rssi(dev, i, poll_results, 8); + for (j = 0; j < 4; j++) { + if (j / 2 == core) + offset[j] = 232 - poll_results[j]; + if (offset[j] < 0) + offset[j] = -(abs(offset[j] + 4) / 8); + else + offset[j] = (offset[j] + 4) / 8; + b43_nphy_scale_offset_rssi(dev, 0, + offset[2 * core], core + 1, j % 2, i); + } + } + } + + b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, saved_regs_phy_rfctl[0]); + b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, saved_regs_phy_rfctl[1]); + + b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); + + b43_phy_set(dev, B43_NPHY_TXF_40CO_B1S1, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_START); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + b43_phy_set(dev, B43_NPHY_RFCTL_OVER, 0x1); + b43_phy_set(dev, B43_NPHY_RFCTL_CMD, B43_NPHY_RFCTL_CMD_RXTX); + b43_phy_mask(dev, B43_NPHY_TXF_40CO_B1S1, ~0x1); + + for (i = 0; i < ARRAY_SIZE(regs_to_store); i++) + b43_phy_write(dev, regs_to_store[i], saved_regs_phy[i]); + + /* Store for future configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G; + } else { + rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G; + rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G; + } + rssical_radio_regs[0] = b43_radio_read(dev, 0x602B); + rssical_radio_regs[0] = b43_radio_read(dev, 0x702B); + rssical_phy_regs[0] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Z); + rssical_phy_regs[1] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z); + rssical_phy_regs[2] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Z); + rssical_phy_regs[3] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z); + rssical_phy_regs[4] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_X); + rssical_phy_regs[5] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_X); + rssical_phy_regs[6] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_X); + rssical_phy_regs[7] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_X); + rssical_phy_regs[8] = b43_phy_read(dev, B43_NPHY_RSSIMC_0I_RSSI_Y); + rssical_phy_regs[9] = b43_phy_read(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y); + rssical_phy_regs[10] = b43_phy_read(dev, B43_NPHY_RSSIMC_1I_RSSI_Y); + rssical_phy_regs[11] = b43_phy_read(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y); + + /* Remember for which channel we store configuration */ + if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) + nphy->rssical_chanspec_2G.center_freq = dev->phy.channel_freq; + else + nphy->rssical_chanspec_5G.center_freq = dev->phy.channel_freq; + + /* End of calibration, restore configuration */ + b43_nphy_classifier(dev, 7, class); + b43_nphy_write_clip_detection(dev, clip_state); +} + /* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) { @@ -1454,12 +1641,6 @@ static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type) b43_nphy_reset_cca(dev); } -/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */ -static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev) -{ - /* TODO */ -} - /* * RSSI Calibration * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal -- cgit v1.2.3-70-g09d2 From 3084f3b65c178228bece6f7b166a19f3e38a75d4 Mon Sep 17 00:00:00 2001 From: Rafał Miłecki Date: Tue, 3 Jan 2012 22:49:21 +0100 Subject: b43: N-PHY: trivial: change save&rest order in RSSI polling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki Signed-off-by: John W. Linville --- drivers/net/wireless/b43/phy_n.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c index 945aa5267d0..108118820b3 100644 --- a/drivers/net/wireless/b43/phy_n.c +++ b/drivers/net/wireless/b43/phy_n.c @@ -1220,12 +1220,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, u16 s[2]; if (dev->phy.rev >= 3) { - save_regs_phy[0] = b43_phy_read(dev, + save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); + save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); + save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1); - save_regs_phy[1] = b43_phy_read(dev, + save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2); - save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1); - save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2); save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1); save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER); save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0); @@ -1274,12 +1274,12 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf, b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]); if (dev->phy.rev >= 3) { + b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[0]); + b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[1]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1, - save_regs_phy[0]); + save_regs_phy[2]); b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2, - save_regs_phy[1]); - b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]); - b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]); + save_regs_phy[3]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]); b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]); b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]); -- cgit v1.2.3-70-g09d2 From 884dd24499df823f5c167223c7ae93bd764e2e4f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:39 -0800 Subject: rtlwifi: Neaten RT_ASSERT, RT_TRACE, RTPRINT, RT_PRINT_DATA macros Make the macros a bit more readable. Use do {...} while (0) without terminating semicolons. Add missing terminating semicolon to a few uses. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 88 +++++++++++++--------------- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/usb.c | 6 +- 5 files changed, 47 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 160dd068521..802c491b3d8 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,53 +156,47 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; -#define RT_ASSERT(_exp, fmt) \ - do { \ - if (!(_exp)) { \ - printk(KERN_DEBUG "%s:%s(): ", KBUILD_MODNAME, \ - __func__); \ - printk fmt; \ - } \ - } while (0); - -#define RT_TRACE(rtlpriv, comp, level, fmt)\ - do { \ - if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ - ((level) <= rtlpriv->dbg.global_debuglevel))) {\ - printk(KERN_DEBUG "%s:%s():<%lx-%x> ", KBUILD_MODNAME, \ - __func__, in_interrupt(), in_atomic()); \ - printk fmt; \ - } \ - } while (0); - -#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ - do { \ - if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk printstr; \ - } \ - } while (0); - -#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ - _hexdatalen) \ - do {\ - if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) &&\ - (_level <= rtlpriv->dbg.global_debuglevel))) { \ - int __i; \ - u8* ptr = (u8 *)_hexdata; \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk("In process \"%s\" (pid %i):", current->comm,\ - current->pid); \ - printk(_titlestring); \ - for (__i = 0; __i < (int)_hexdatalen; __i++) { \ - printk("%02X%s", ptr[__i], (((__i + 1) % 4)\ - == 0) ? " " : " ");\ - if (((__i + 1) % 16) == 0) \ - printk("\n"); \ - } \ - printk(KERN_DEBUG "\n"); \ - } \ - } while (0); +#define RT_ASSERT(_exp, fmt) \ +do { \ + if (!(_exp)) { \ + printk(KERN_DEBUG "%s:%s(): ", \ + KBUILD_MODNAME, __func__); \ + printk fmt; \ + } \ +} while (0) + +#define RT_TRACE(rtlpriv, comp, level, fmt) \ +do { \ + if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ + ((level) <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG "%s:%s():<%lx-%x> ", \ + KBUILD_MODNAME, __func__, \ + in_interrupt(), in_atomic()); \ + printk fmt; \ + } \ +} while (0) + +#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ +do { \ + if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + printk printstr; \ + } \ +} while (0) + +#define RT_PRINT_DATA(rtlpriv, _comp, _level, _titlestring, _hexdata, \ + _hexdatalen) \ +do { \ + if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ + (_level <= rtlpriv->dbg.global_debuglevel))) { \ + printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ + pr_cont("In process \"%s\" (pid %i):", \ + current->comm, current->pid); \ + printk(_titlestring); \ + print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ + _hexdata, _hexdatalen); \ + } \ +} while (0) void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 3b585aadabf..ce9eea94bb5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -374,7 +374,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + "20MHz" : "40MHz")); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index e49cf2244c7..df491d38ecc 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -360,7 +360,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")) + "20MHz" : "40MHz")); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; return; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 9d89d7ccdaf..c8c4cf9240d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1617,7 +1617,7 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Is D cut,Internal PA0 %d Internal PA1 %d\n", rtlefuse->internal_pa_5g[0], - rtlefuse->internal_pa_5g[1])) + rtlefuse->internal_pa_5g[1])); } rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e956fa71d04..1b8e68e70f8 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -414,7 +414,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")) + ("Failed to __dev_alloc_skb!!\n")); return ERR_PTR(-ENOMEM); } @@ -632,14 +632,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")) + ("Failed to alloc URB!!\n")); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")) + ("Failed to prep_rx_urb!!\n")); err = PTR_ERR(skb); goto err_out; } -- cgit v1.2.3-70-g09d2 From af08687b4e6d44dcdb04b519e718eb58ecb99050 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:40 -0800 Subject: rtlwifi: Standardize RT_PRINT_DATA macro and uses Use a single printk(KERN_DEBUG to emit the header line to avoid any possible output interleaving. Remove unnecessary parentheses from the calling uses. Standardize header arg without trailing \n or colon. Fix a few pairwiase/pairwise typos. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 7 +++---- drivers/net/wireless/rtlwifi/efuse.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 9 ++++----- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 3 +-- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 8 ++++---- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 4 ++-- 12 files changed, 23 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 802c491b3d8..588986a1e21 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -189,10 +189,9 @@ do { \ do { \ if (unlikely(((_comp) & rtlpriv->dbg.global_debugcomponents) && \ (_level <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - pr_cont("In process \"%s\" (pid %i):", \ - current->comm, current->pid); \ - printk(_titlestring); \ + printk(KERN_DEBUG "%s: In process \"%s\" (pid %i): %s\n", \ + KBUILD_MODNAME, current->comm, current->pid, \ + _titlestring); \ print_hex_dump_bytes("", DUMP_PREFIX_NONE, \ _hexdata, _hexdatalen); \ } \ diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index ed1058b7158..91fd3639d73 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -478,7 +478,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_MODIFY_MAP][base], 8); RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, - ("U-efuse\n"), tmpdata, 8); + "U-efuse", tmpdata, 8); if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 931d97979b0..5401b32733d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -570,7 +570,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92c_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92c_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); @@ -780,10 +780,10 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92c_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); @@ -800,8 +800,7 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("Set RSVD page location to Fw.\n")); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", - u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index a3deaefa788..2156378de1e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1570,7 +1570,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2134,7 +2134,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 4fb5ae24dee..378bc567346 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -821,8 +821,7 @@ void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", - pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); } void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 124cf633861..778c0e6e836 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -496,7 +496,7 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0])); if (eeprom_id != RTL8190_EEPROM_ID) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 9e0c8fcdf90..487ee908d7c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -331,7 +331,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index b3cc7b94999..128cfcd09fa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -677,7 +677,7 @@ void rtl92cu_tx_fill_cmddesc(struct ieee80211_hw *hw, SET_TX_DESC_HWSEQ_EN(pdesc, 1); SET_TX_DESC_PKT_ID(pdesc, 8); } - RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content\n", + RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, "H2C Tx Cmd Content", pdesc, RTL_TX_DESC_SIZE); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index 82f060bdbc0..db6972ffe50 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -565,7 +565,7 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, ppsc->reg_max_lps_awakeintvl); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode\n", + "rtl92d_set_fw_rsvdpagepkt(): u1_h2c_set_pwrmode", u1_h2c_set_pwrmode, 3); rtl92d_fill_h2c_cmd(hw, H2C_SETPWRMODE, 3, u1_h2c_set_pwrmode); } @@ -757,10 +757,10 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1RsvdPageLoc, PROBERSP_PG); totalpacketlen = TOTAL_RESERVED_PKT_LEN; RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", &reserved_page_packet[0], totalpacketlen); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL\n", + "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, @@ -773,7 +773,7 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("Set RSVD page location to Fw.\n")); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, - "H2C_RSVDPAGE:\n", u1RsvdPageLoc, 3); + "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index c8c4cf9240d..5c8a639582a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1777,7 +1777,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("RTL819X Not boot from eeprom, check it !!")); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2279,7 +2279,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv-> sec.key_len[PAIRWISE_KEYIDX]); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index 3637c0c3352..e84b8d5e4b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -776,7 +776,7 @@ void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, } RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_LOUD, - "H2C Tx Cmd Content\n", pdesc, TX_DESC_SIZE); + "H2C Tx Cmd Content", pdesc, TX_DESC_SIZE); wmb(); SET_TX_DESC_OWN(pdesc, 1); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index c474486e391..f9ba077bc18 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1636,7 +1636,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE_92S); } - RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("MAP\n"), + RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE_92S); eeprom_id = *((u16 *)&hwinfo[0]); @@ -2453,7 +2453,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, ("add one entry\n")); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwiase Key content :", + "Pairwise Key content", rtlpriv->sec.pairwise_key, rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); -- cgit v1.2.3-70-g09d2 From f30d7507a8116e2099a9135c873411db8c0a3dc6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:41 -0800 Subject: rtlwifi: Convert RT_TRACE macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RT_TRACE parentheses. Miscellaneous typo and grammar fixes. Add missing newlines to formats. Remove duplicate KERN_DEBUG prefixes. Coalesce formats. Align arguments. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 594841 55333 129680 779854 be64e drivers/net/wireless/rtlwifi/built-in.o.new 607022 55333 138720 801075 c3933 drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 56 ++- drivers/net/wireless/rtlwifi/cam.c | 81 ++-- drivers/net/wireless/rtlwifi/core.c | 120 +++--- drivers/net/wireless/rtlwifi/debug.h | 7 +- drivers/net/wireless/rtlwifi/efuse.c | 31 +- drivers/net/wireless/rtlwifi/pci.c | 196 +++++----- drivers/net/wireless/rtlwifi/ps.c | 31 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- drivers/net/wireless/rtlwifi/regd.c | 12 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 189 +++++----- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 69 ++-- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 201 +++++----- drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 24 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 182 +++++---- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 16 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 108 +++--- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 4 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 24 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 179 +++++---- drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 101 +++-- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 121 +++--- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 36 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 239 ++++++------ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 103 +++-- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 182 +++++---- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 14 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 419 ++++++++++----------- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 26 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 8 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 30 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 66 ++-- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 155 ++++---- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 15 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 200 +++++----- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 60 ++- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 6 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/rtlwifi/usb.c | 37 +- 44 files changed, 1613 insertions(+), 1784 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 8d6eb0f56c0..fa16b1d708f 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -211,7 +211,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, */ if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_2T2R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T2R or 2T2R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0xFF; @@ -220,7 +220,7 @@ static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw, ht_cap->mcs.rx_highest = cpu_to_le16(MAX_BIT_RATE_40MHZ_MCS15); } else if (get_rf_type(rtlphy) == RF_1T1R) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("1T1R\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "1T1R\n"); ht_cap->mcs.rx_mask[0] = 0xFF; ht_cap->mcs.rx_mask[1] = 0x00; @@ -302,9 +302,8 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* <4> set mac->sband to wiphy->sband */ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Err BAND %d\n", - rtlhal->current_bandtype)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Err BAND %d\n", + rtlhal->current_bandtype); } } /* <5> set hw caps */ @@ -436,13 +435,13 @@ int rtl_init_core(struct ieee80211_hw *hw) * mac80211 hw in _rtl_init_mac80211. */ if (rtl_regd_init(hw, rtl_reg_notifier)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n"); return 1; } else { /* CRDA regd hint must after init CRDA */ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("regulatory_hint fail\n")); + "regulatory_hint fail\n"); } } @@ -922,17 +921,17 @@ bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return false; RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBAREQ From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBAREQ From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_ADDBARSP: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("%s ACT_ADDBARSP From :%pM\n", - is_tx ? "Tx" : "Rx", hdr->addr2)); + "%s ACT_ADDBARSP From :%pM\n", + is_tx ? "Tx" : "Rx", hdr->addr2); break; case ACT_DELBA: RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("ACT_ADDBADEL From :%pM\n", hdr->addr2)); + "ACT_ADDBADEL From :%pM\n", hdr->addr2); break; } break; @@ -975,8 +974,8 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) * 67 : UDP BOOTP server */ RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), - DBG_DMESG, ("dhcp %s !!\n", - (is_tx) ? "Tx" : "Rx")); + DBG_DMESG, "dhcp %s !!\n", + is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -996,7 +995,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx) return true; } else if (ETH_P_PAE == ether_type) { RT_TRACE(rtlpriv, (COMP_SEND | COMP_RECV), DBG_DMESG, - ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx")); + "802.1X %s EAPOL pkt!!\n", is_tx ? "Tx" : "Rx"); if (is_tx) { rtl_lps_leave(hw); @@ -1036,9 +1035,8 @@ int rtl_tx_agg_start(struct ieee80211_hw *hw, return -ENXIO; tid_data = &sta_entry->tids[tid]; - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid, - tid_data->seq_number)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d seq:%d\n", + sta->addr, tid, tid_data->seq_number); *ssn = tid_data->seq_number; tid_data->agg.agg_state = RTL_AGG_START; @@ -1059,12 +1057,12 @@ int rtl_tx_agg_stop(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1087,12 +1085,12 @@ int rtl_tx_agg_oper(struct ieee80211_hw *hw, return -EINVAL; if (!sta->addr) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("ra = NULL\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "ra = NULL\n"); return -EINVAL; } - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, - ("on ra = %pM tid = %d\n", sta->addr, tid)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "on ra = %pM tid = %d\n", + sta->addr, tid); if (unlikely(tid >= MAX_TID_COUNT)) return -EINVAL; @@ -1474,29 +1472,29 @@ void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len) (memcmp(mac->bssid, ap5_6, 3) == 0) || vendor == PEER_ATH) { vendor = PEER_ATH; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ath find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ath find\n"); } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) || (memcmp(mac->bssid, ap4_5, 3) == 0) || (memcmp(mac->bssid, ap4_1, 3) == 0) || (memcmp(mac->bssid, ap4_2, 3) == 0) || (memcmp(mac->bssid, ap4_3, 3) == 0) || vendor == PEER_RAL) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>ral findn\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>ral find\n"); vendor = PEER_RAL; } else if (memcmp(mac->bssid, ap6_1, 3) == 0 || vendor == PEER_CISCO) { vendor = PEER_CISCO; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>cisco find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>cisco find\n"); } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) || (memcmp(mac->bssid, ap3_2, 3) == 0) || (memcmp(mac->bssid, ap3_3, 3) == 0) || vendor == PEER_BROAD) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>broad find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>broad find\n"); vendor = PEER_BROAD; } else if (memcmp(mac->bssid, ap7_1, 3) == 0 || vendor == PEER_MARV) { vendor = PEER_MARV; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("=>marv find\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "=>marv find\n"); } mac->vendor = vendor; diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index dc36d7461ca..cbf5e3cdb44 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -55,10 +55,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, u8 entry_i; RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("key_cont_128:\n %x:%x:%x:%x:%x:%x\n", - key_cont_128[0], key_cont_128[1], - key_cont_128[2], key_cont_128[3], - key_cont_128[4], key_cont_128[5])); + "key_cont_128:\n %x:%x:%x:%x:%x:%x\n", + key_cont_128[0], key_cont_128[1], + key_cont_128[2], key_cont_128[3], + key_cont_128[4], key_cont_128[5]); for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { target_command = entry_i + CAM_CONTENT_COUNT * entry_no; @@ -73,14 +73,12 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[WCAMI], target_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[WCAMI], target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The Key ID is %d\n", entry_no)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE %x: %x\n", - rtlpriv->cfg->maps[RWCAM], target_command)); + "The Key ID is %d\n", entry_no); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE %x: %x\n", + rtlpriv->cfg->maps[RWCAM], target_command); } else if (entry_i == 1) { @@ -94,10 +92,10 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], target_command); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } else { @@ -114,15 +112,15 @@ static void rtl_cam_program_entry(struct ieee80211_hw *hw, u32 entry_no, target_command); udelay(100); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A4: %x\n", target_content)); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("WRITE A0: %x\n", target_command)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A4: %x\n", + target_content); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "WRITE A0: %x\n", + target_command); } } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("after set key, usconfig:%x\n", us_config)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "after set key, usconfig:%x\n", + us_config); } u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, @@ -133,14 +131,13 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, " - "ulUseDK=%x MacAddr %pM\n", - ul_entry_idx, ul_key_id, ul_enc_alg, - ul_default_key, mac_addr)); + "EntryNo:%x, ulKeyId=%x, ulEncAlg=%x, ulUseDK=%x MacAddr %pM\n", + ul_entry_idx, ul_key_id, ul_enc_alg, + ul_default_key, mac_addr); if (ul_key_id == TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("<=== ulKeyId exceed!\n")); + "<=== ulKeyId exceed!\n"); return 0; } @@ -153,7 +150,7 @@ u8 rtl_cam_add_one_entry(struct ieee80211_hw *hw, u8 *mac_addr, rtl_cam_program_entry(hw, ul_entry_idx, mac_addr, (u8 *) key_content, us_config); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("<===\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "<===\n"); return 1; @@ -166,7 +163,7 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, u32 ul_command; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("key_idx:%d\n", ul_key_id)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "key_idx:%d\n", ul_key_id); ul_command = ul_key_id * CAM_CONTENT_COUNT; ul_command = ul_command | BIT(31) | BIT(16); @@ -175,9 +172,9 @@ int rtl_cam_delete_one_entry(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0)); + "rtl_cam_delete_one_entry(): WRITE A4: %x\n", 0); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command)); + "rtl_cam_delete_one_entry(): WRITE A0: %x\n", ul_command); return 0; @@ -229,9 +226,9 @@ void rtl_cam_mark_invalid(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content)); + "rtl_cam_mark_invalid(): WRITE A4: %x\n", ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command)); + "rtl_cam_mark_invalid(): WRITE A0: %x\n", ul_command); } EXPORT_SYMBOL(rtl_cam_mark_invalid); @@ -279,11 +276,11 @@ void rtl_cam_empty_entry(struct ieee80211_hw *hw, u8 uc_index) rtl_write_dword(rtlpriv, rtlpriv->cfg->maps[RWCAM], ul_command); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A4: %x\n", - ul_content)); + "rtl_cam_empty_entry(): WRITE A4: %x\n", + ul_content); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("rtl_cam_empty_entry(): WRITE A0: %x\n", - ul_command)); + "rtl_cam_empty_entry(): WRITE A0: %x\n", + ul_command); } } @@ -297,8 +294,7 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); return TOTAL_CAM_ENTRY; } /* Does STA already exist? */ @@ -311,8 +307,8 @@ u8 rtl_cam_get_free_entry(struct ieee80211_hw *hw, u8 *sta_addr) for (entry_idx = 4; entry_idx < TOTAL_CAM_ENTRY; entry_idx++) { if ((bitmap & BIT(0)) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", - rtlpriv->sec.hwsec_cam_bitmap, entry_idx)); + "-----hwsec_cam_bitmap: 0x%x entry_idx=%d\n", + rtlpriv->sec.hwsec_cam_bitmap, entry_idx); rtlpriv->sec.hwsec_cam_bitmap |= BIT(0) << entry_idx; memcpy(rtlpriv->sec.hwsec_cam_sta_addr[entry_idx], sta_addr, ETH_ALEN); @@ -331,14 +327,13 @@ void rtl_cam_del_entry(struct ieee80211_hw *hw, u8 *sta_addr) u8 i, *addr; if (NULL == sta_addr) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is NULL.\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, "sta_addr is NULL\n"); } if ((sta_addr[0]|sta_addr[1]|sta_addr[2]|sta_addr[3]|\ sta_addr[4]|sta_addr[5]) == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_EMERG, - ("sta_addr is 00:00:00:00:00:00.\n")); + "sta_addr is 00:00:00:00:00:00\n"); return; } /* Does STA already exist? */ diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 3f0f056fae9..186c944c143 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -114,7 +114,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, if (mac->vif) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("vif has been set!! mac->vif = 0x%p\n", mac->vif)); + "vif has been set!! mac->vif = 0x%p\n", mac->vif); return -EOPNOTSUPP; } @@ -125,7 +125,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, case NL80211_IFTYPE_STATION: if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_STATION\n")); + "NL80211_IFTYPE_STATION\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, rtlpriv->cfg->maps @@ -134,7 +134,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_ADHOC: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_ADHOC\n")); + "NL80211_IFTYPE_ADHOC\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -148,7 +148,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; case NL80211_IFTYPE_AP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("NL80211_IFTYPE_AP\n")); + "NL80211_IFTYPE_AP\n"); mac->link_state = MAC80211_LINKED; rtlpriv->cfg->ops->set_bcn_reg(hw); @@ -161,7 +161,7 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("operation mode %d is not support!\n", vif->type)); + "operation mode %d is not supported!\n", vif->type); err = -EOPNOTSUPP; goto out; } @@ -221,7 +221,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) mutex_lock(&rtlpriv->locks.conf_mutex); if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { /*BIT(2)*/ RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n")); + "IEEE80211_CONF_CHANGE_LISTEN_INTERVAL\n"); } /*For IPS */ @@ -264,8 +264,8 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", - hw->conf.long_frame_max_tx_count)); + "IEEE80211_CONF_CHANGE_RETRY_LIMITS %x\n", + hw->conf.long_frame_max_tx_count); mac->retry_long = hw->conf.long_frame_max_tx_count; mac->retry_short = hw->conf.long_frame_max_tx_count; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, @@ -320,7 +320,7 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) default: mac->bw_40 = false; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not processed\n")); + "switch case not processed\n"); break; } @@ -369,12 +369,12 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive multicast frame.\n")); + "Enable receive multicast frame\n"); } else { mac->rx_conf &= ~(rtlpriv->cfg->maps[MAC_RCR_AM] | rtlpriv->cfg->maps[MAC_RCR_AB]); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive multicast frame.\n")); + "Disable receive multicast frame\n"); } } @@ -382,11 +382,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_FCSFAIL) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive FCS error frame.\n")); + "Enable receive FCS error frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACRC32]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive FCS error frame.\n")); + "Disable receive FCS error frame\n"); } } @@ -409,11 +409,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive control frame.\n")); + "Enable receive control frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_ACF]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive control frame.\n")); + "Disable receive control frame\n"); } } @@ -421,11 +421,11 @@ static void rtl_op_configure_filter(struct ieee80211_hw *hw, if (*new_flags & FIF_OTHER_BSS) { mac->rx_conf |= rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Enable receive other BSS's frame.\n")); + "Enable receive other BSS's frame\n"); } else { mac->rx_conf &= ~rtlpriv->cfg->maps[MAC_RCR_AAP]; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("Disable receive other BSS's frame.\n")); + "Disable receive other BSS's frame\n"); } } } @@ -456,7 +456,7 @@ static int rtl_op_sta_add(struct ieee80211_hw *hw, sta_entry->wireless_mode = WIRELESS_MODE_G; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Add sta addr is %pM\n", sta->addr)); + "Add sta addr is %pM\n", sta->addr); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); } return 0; @@ -469,7 +469,7 @@ static int rtl_op_sta_remove(struct ieee80211_hw *hw, struct rtl_sta_info *sta_entry; if (sta) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("Remove sta addr is %pM\n", sta->addr)); + "Remove sta addr is %pM\n", sta->addr); sta_entry = (struct rtl_sta_info *) sta->drv_priv; sta_entry->wireless_mode = 0; sta_entry->ratr_index = 0; @@ -514,7 +514,7 @@ static int rtl_op_conf_tx(struct ieee80211_hw *hw, if (queue >= AC_MAX) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("queue number %d is incorrect!\n", queue)); + "queue number %d is incorrect!\n", queue); return -EINVAL; } @@ -547,7 +547,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, bss_conf->enable_beacon)) { if (mac->beacon_enabled == 0) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_BEACON_ENABLED\n")); + "BSS_CHANGED_BEACON_ENABLED\n"); /*start hw beacon interrupt. */ /*rtlpriv->cfg->ops->set_bcn_reg(hw); */ @@ -565,7 +565,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, !bss_conf->enable_beacon)) { if (mac->beacon_enabled == 1) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("ADHOC DISABLE BEACON\n")); + "ADHOC DISABLE BEACON\n"); mac->beacon_enabled = 0; rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, @@ -575,7 +575,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_BEACON_INT) { RT_TRACE(rtlpriv, COMP_BEACON, DBG_TRACE, - ("BSS_CHANGED_BEACON_INT\n")); + "BSS_CHANGED_BEACON_INT\n"); mac->beacon_interval = bss_conf->beacon_int; rtlpriv->cfg->ops->set_bcn_intv(hw); } @@ -604,7 +604,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (mac->opmode == NL80211_IFTYPE_STATION && sta) rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_ASSOC\n")); + "BSS_CHANGED_ASSOC\n"); } else { if (mac->link_state == MAC80211_LINKED) rtl_lps_leave(hw); @@ -619,20 +619,20 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, mac->vendor = PEER_UNKNOWN; RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("BSS_CHANGED_UN_ASSOC\n")); + "BSS_CHANGED_UN_ASSOC\n"); } } if (changed & BSS_CHANGED_ERP_CTS_PROT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_CTS_PROT\n")); + "BSS_CHANGED_ERP_CTS_PROT\n"); mac->use_cts_protect = bss_conf->use_cts_prot; } if (changed & BSS_CHANGED_ERP_PREAMBLE) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, - ("BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", - bss_conf->use_short_preamble)); + "BSS_CHANGED_ERP_PREAMBLE use short preamble:%x\n", + bss_conf->use_short_preamble); mac->short_preamble = bss_conf->use_short_preamble; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACK_PREAMBLE, @@ -641,7 +641,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ERP_SLOT) { RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_ERP_SLOT\n")); + "BSS_CHANGED_ERP_SLOT\n"); if (bss_conf->use_short_slot) mac->slot_time = RTL_SLOT_TIME_9; @@ -653,8 +653,7 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("BSS_CHANGED_HT\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, "BSS_CHANGED_HT\n"); rcu_read_lock(); sta = get_sta(hw, vif, bss_conf->bssid); if (sta) { @@ -683,8 +682,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw, rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_BSSID, (u8 *) bss_conf->bssid); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, - ("%pM\n", bss_conf->bssid)); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_DMESG, "%pM\n", + bss_conf->bssid); mac->vendor = PEER_UNKNOWN; memcpy(mac->bssid, bss_conf->bssid, 6); @@ -831,30 +830,30 @@ static int rtl_op_ampdu_action(struct ieee80211_hw *hw, switch (action) { case IEEE80211_AMPDU_TX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_START: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_START: TID:%d\n", tid); return rtl_tx_agg_start(hw, sta, tid, ssn); break; case IEEE80211_AMPDU_TX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_STOP: TID:%d\n", tid); return rtl_tx_agg_stop(hw, sta, tid); break; case IEEE80211_AMPDU_TX_OPERATIONAL: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid)); + "IEEE80211_AMPDU_TX_OPERATIONAL:TID:%d\n", tid); rtl_tx_agg_oper(hw, sta, tid); break; case IEEE80211_AMPDU_RX_START: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_START:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_START:TID:%d\n", tid); break; case IEEE80211_AMPDU_RX_STOP: RT_TRACE(rtlpriv, COMP_MAC80211, DBG_TRACE, - ("IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid)); + "IEEE80211_AMPDU_RX_STOP:TID:%d\n", tid); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("IEEE80211_AMPDU_ERR!!!!:\n")); + "IEEE80211_AMPDU_ERR!!!!:\n"); return -EOPNOTSUPP; } return 0; @@ -867,7 +866,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw) mac->act_scanning = true; - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); if (mac->link_state == MAC80211_LINKED) { rtl_lps_leave(hw); @@ -888,7 +887,7 @@ static void rtl_op_sw_scan_complete(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_MAC80211, DBG_LOUD, "\n"); mac->act_scanning = false; /* Dual mac */ rtlpriv->rtlhal.load_imrandiqk_setting_for2g = false; @@ -921,13 +920,13 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not open hw encryption\n")); + "not open hw encryption\n"); return -ENOSPC; /*User disabled HW-crypto */ } RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("%s hardware based encryption for keyidx: %d, mac: %pM\n", - cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, - sta ? sta->addr : bcast_addr)); + "%s hardware based encryption for keyidx: %d, mac: %pM\n", + cmd == SET_KEY ? "Using" : "Disabling", key->keyidx, + sta ? sta->addr : bcast_addr); rtlpriv->sec.being_setkey = true; rtl_ips_nic_on(hw); mutex_lock(&rtlpriv->locks.conf_mutex); @@ -936,24 +935,23 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: key_type = WEP40_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:WEP40\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("alg:WEP104\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:WEP104\n"); key_type = WEP104_ENCRYPTION; break; case WLAN_CIPHER_SUITE_TKIP: key_type = TKIP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:TKIP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:TKIP\n"); break; case WLAN_CIPHER_SUITE_CCMP: key_type = AESCCMP_ENCRYPTION; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("alg:CCMP\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "alg:CCMP\n"); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("alg_err:%x!!!!:\n", key->cipher)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "alg_err:%x!!!!\n", + key->cipher); goto out_unlock; } if (key_type == WEP40_ENCRYPTION || @@ -995,8 +993,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, wep_only = true; rtlpriv->sec.pairwise_enc_algorithm = key_type; RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1" - " TKIP:2 AES:4 WEP104:5)\n", key_type)); + "set enable_hw_sec, key_type:%x(OPEN:0 WEP40:1 TKIP:2 AES:4 WEP104:5)\n", + key_type); rtlpriv->cfg->ops->enable_hw_sec(hw); } } @@ -1005,7 +1003,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, case SET_KEY: if (wep_only) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set WEP(group/pairwise) key\n")); + "set WEP(group/pairwise) key\n"); /* Pairwise key with an assigned MAC address. */ rtlpriv->sec.pairwise_enc_algorithm = key_type; rtlpriv->sec.group_enc_algorithm = key_type; @@ -1016,7 +1014,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, zero_addr, ETH_ALEN); } else if (group_key) { /* group key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); /* group key */ rtlpriv->sec.group_enc_algorithm = key_type; /*set local buf about group key. */ @@ -1026,7 +1024,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, memcpy(mac_addr, bcast_addr, ETH_ALEN); } else { /* pairwise key */ RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set pairwise key\n")); + "set pairwise key\n"); if (!sta) { RT_ASSERT(false, ("pairwise key withnot" "mac_addr\n")); @@ -1056,7 +1054,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; case DISABLE_KEY: RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("disable key delete one entry\n")); + "disable key delete one entry\n"); /*set local buf about wep key. */ if (mac->opmode == NL80211_IFTYPE_AP) { if (sta) @@ -1077,7 +1075,7 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("cmd_err:%x!!!!:\n", cmd)); + "cmd_err:%x!!!!\n", cmd); } out_unlock: mutex_unlock(&rtlpriv->locks.conf_mutex); @@ -1106,8 +1104,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw) rtlpriv->rfkill.rfkill_state = radio_state; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - (KERN_INFO "wireless radio switch turned %s\n", - radio_state ? "on" : "off")); + "wireless radio switch turned %s\n", + radio_state ? "on" : "off"); blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1; wiphy_rfkill_set_hw_state(hw->wiphy, blocked); diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 588986a1e21..8c139693354 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -165,14 +165,13 @@ do { \ } \ } while (0) -#define RT_TRACE(rtlpriv, comp, level, fmt) \ +#define RT_TRACE(rtlpriv, comp, level, fmt, ...) \ do { \ if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ ((level) <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s:%s():<%lx-%x> ", \ + printk(KERN_DEBUG "%s:%s():<%lx-%x> " fmt, \ KBUILD_MODNAME, __func__, \ - in_interrupt(), in_atomic()); \ - printk fmt; \ + in_interrupt(), in_atomic(), ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 91fd3639d73..2885131cf1a 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -162,8 +162,8 @@ void efuse_write_1byte(struct ieee80211_hw *hw, u16 address, u8 value) const u32 efuse_len = rtlpriv->cfg->maps[EFUSE_REAL_CONTENT_SIZE]; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr=%x Data =%x\n", address, value)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr=%x Data =%x\n", + address, value); if (address < efuse_len) { rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL], value); @@ -252,8 +252,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if ((_offset + _size_byte) > rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("read_efuse(): Invalid offset(%#x) with read " - "bytes(%#x)!!\n", _offset, _size_byte)); + "read_efuse(): Invalid offset(%#x) with read bytes(%#x)!!\n", + _offset, _size_byte); return; } @@ -395,9 +395,8 @@ bool efuse_shadow_update_chk(struct ieee80211_hw *hw) result = false; RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_shadow_update_chk(): totalbytes(%#x), " - "hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", - totalbytes, hdr_num, words_need, efuse_used)); + "efuse_shadow_update_chk(): totalbytes(%#x), hdr_num(%#x), words_need(%#x), efuse_used(%d)\n", + totalbytes, hdr_num, words_need, efuse_used); return result; } @@ -434,7 +433,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) u8 word_en = 0x0F; u8 first_pg = false; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("--->\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "--->\n"); if (!efuse_shadow_update_chk(hw)) { efuse_read_all_map(hw, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0]); @@ -443,7 +442,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("<---efuse out of capacity!!\n")); + "<---efuse out of capacity!!\n"); return false; } efuse_power_switch(hw, true, true); @@ -483,7 +482,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) if (!efuse_pg_packet_write(hw, (u8) offset, word_en, tmpdata)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("PG section(%#x) fail!!\n", offset)); + "PG section(%#x) fail!!\n", offset); break; } } @@ -497,7 +496,7 @@ bool efuse_shadow_update(struct ieee80211_hw *hw) &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], rtlpriv->cfg->maps[EFUSE_HWSET_MAX_SIZE]); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, ("<---\n")); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "<---\n"); return true; } @@ -634,8 +633,8 @@ static int efuse_one_byte_write(struct ieee80211_hw *hw, u16 addr, u8 data) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpidx = 0; - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("Addr = %x Data=%x\n", addr, data)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "Addr = %x Data=%x\n", + addr, data); rtl_write_byte(rtlpriv, rtlpriv->cfg->maps[EFUSE_CTRL] + 1, (u8) (addr & 0xff)); @@ -1006,7 +1005,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_addr >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("efuse_addr(%#x) Out of size!!\n", efuse_addr)); + "efuse_addr(%#x) Out of size!!\n", efuse_addr); } return true; @@ -1046,8 +1045,8 @@ static u8 efuse_word_enable_data_write(struct ieee80211_hw *hw, u8 tmpdata[8]; memset(tmpdata, 0xff, PGPKT_DATA_SIZE); - RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, - ("word_en = %x efuse_addr=%x\n", word_en, efuse_addr)); + RT_TRACE(rtlpriv, COMP_EFUSE, DBG_LOUD, "word_en = %x efuse_addr=%x\n", + word_en, efuse_addr); if (!(word_en & BIT(0))) { tmpaddr = start_addr; diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 39e0907a3c4..b52fef23575 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -170,7 +170,7 @@ static void _rtl_pci_update_default_setting(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -232,7 +232,7 @@ static void rtl_pci_disable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -286,7 +286,7 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) if (pcibridge_vendor == PCI_BRIDGE_VENDOR_UNKNOWN) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("PCI(Bridge) UNKNOWN.\n")); + "PCI(Bridge) UNKNOWN\n"); return; } @@ -303,11 +303,10 @@ static void rtl_pci_enable_aspm(struct ieee80211_hw *hw) u_pcibridge_aspmsetting); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PlatformEnableASPM():PciBridge busnumber[%x], " - "DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", - pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, - (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), - u_pcibridge_aspmsetting)); + "PlatformEnableASPM():PciBridge busnumber[%x], DevNumbe[%x], funcnumber[%x], Write reg[%x] = %x\n", + pcibridge_busnum, pcibridge_devnum, pcibridge_funcnum, + (pcipriv->ndis_adapter.pcibridge_pciehdr_offset + 0x10), + u_pcibridge_aspmsetting); udelay(50); @@ -382,9 +381,8 @@ static void rtl_pci_parse_configuration(struct pci_dev *pdev, pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &linkctrl_reg); pcipriv->ndis_adapter.linkctrl_reg = linkctrl_reg; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Link Control Register =%x\n", - pcipriv->ndis_adapter.linkctrl_reg)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Link Control Register =%x\n", + pcipriv->ndis_adapter.linkctrl_reg); pci_read_config_byte(pdev, 0x98, &tmp); tmp |= BIT(4); @@ -551,11 +549,10 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) skb_pull(skb, EM_HDR_LEN); RT_TRACE(rtlpriv, (COMP_INTR | COMP_SEND), DBG_TRACE, - ("new ring->idx:%d, " - "free: skb_queue_len:%d, free: seq:%x\n", - ring->idx, - skb_queue_len(&ring->queue), - *(u16 *) (skb->data + 22))); + "new ring->idx:%d, free: skb_queue_len:%d, free: seq:%x\n", + ring->idx, + skb_queue_len(&ring->queue), + *(u16 *) (skb->data + 22)); if (prio == TXCMD_QUEUE) { dev_kfree_skb(skb); @@ -593,11 +590,9 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio) == 2) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("more desc left, wake" - "skb_queue@%d,ring->idx = %d," - "skb_queue_len = 0x%d\n", - prio, ring->idx, - skb_queue_len(&ring->queue))); + "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n", + prio, ring->idx, + skb_queue_len(&ring->queue)); ieee80211_wake_queue(hw, skb_get_queue_mapping @@ -709,9 +704,8 @@ static void _rtl_pci_rx_interrupt(struct ieee80211_hw *hw) new_skb = dev_alloc_skb(rtlpci->rxbuffersize); if (unlikely(!new_skb)) { - RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), - DBG_DMESG, - ("can't alloc skb for rx\n")); + RT_TRACE(rtlpriv, (COMP_INTR | COMP_RECV), DBG_DMESG, + "can't alloc skb for rx\n"); goto done; } @@ -796,38 +790,37 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) /*<1> beacon related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_TBDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon ok interrupt!\n")); + "beacon ok interrupt!\n"); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TBDER])) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon err interrupt!\n")); + "beacon err interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BDOK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("beacon interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "beacon interrupt!\n"); } if (inta & rtlpriv->cfg->maps[RTL_IMR_BcnInt]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("prepare beacon for interrupt!\n")); + "prepare beacon for interrupt!\n"); tasklet_schedule(&rtlpriv->works.irq_prepare_bcn_tasklet); } /*<3> Tx related */ if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_TXFOVW])) - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("IMR_TXFOVW!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "IMR_TXFOVW!\n"); if (inta & rtlpriv->cfg->maps[RTL_IMR_MGNTDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Manage ok interrupt!\n")); + "Manage ok interrupt!\n"); _rtl_pci_tx_isr(hw, MGNT_QUEUE); } if (inta & rtlpriv->cfg->maps[RTL_IMR_HIGHDOK]) { RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("HIGH_QUEUE ok interrupt!\n")); + "HIGH_QUEUE ok interrupt!\n"); _rtl_pci_tx_isr(hw, HIGH_QUEUE); } @@ -835,7 +828,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BK Tx OK interrupt!\n")); + "BK Tx OK interrupt!\n"); _rtl_pci_tx_isr(hw, BK_QUEUE); } @@ -843,7 +836,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("BE TX OK interrupt!\n")); + "BE TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, BE_QUEUE); } @@ -851,7 +844,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("VI TX OK interrupt!\n")); + "VI TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VI_QUEUE); } @@ -859,7 +852,7 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("Vo TX OK interrupt!\n")); + "Vo TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, VO_QUEUE); } @@ -868,25 +861,25 @@ static irqreturn_t _rtl_pci_interrupt(int irq, void *dev_id) rtlpriv->link_info.num_tx_inperiod++; RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, - ("CMD TX OK interrupt!\n")); + "CMD TX OK interrupt!\n"); _rtl_pci_tx_isr(hw, TXCMD_QUEUE); } } /*<2> Rx related */ if (inta & rtlpriv->cfg->maps[RTL_IMR_ROK]) { - RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, ("Rx ok interrupt!\n")); + RT_TRACE(rtlpriv, COMP_INTR, DBG_TRACE, "Rx ok interrupt!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RDU])) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("rx descriptor unavailable!\n")); + "rx descriptor unavailable!\n"); _rtl_pci_rx_interrupt(hw); } if (unlikely(inta & rtlpriv->cfg->maps[RTL_IMR_RXFOVW])) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("rx overflow !\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "rx overflow !\n"); _rtl_pci_rx_interrupt(hw); } @@ -1028,7 +1021,7 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, if (!ring || (unsigned long)ring & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate TX ring (prio = %d)\n", prio)); + "Cannot allocate TX ring (prio = %d)\n", prio); return -ENOMEM; } @@ -1039,8 +1032,8 @@ static int _rtl_pci_init_tx_ring(struct ieee80211_hw *hw, rtlpci->tx_ring[prio].entries = entries; skb_queue_head_init(&rtlpci->tx_ring[prio].queue); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("queue:%d, ring_addr:%p\n", prio, ring)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "queue:%d, ring_addr:%p\n", + prio, ring); for (i = 0; i < entries; i++) { nextdescaddress = (u32) dma + @@ -1078,7 +1071,7 @@ static int _rtl_pci_init_rx_ring(struct ieee80211_hw *hw) if (!rtlpci->rx_ring[rx_queue_idx].desc || (unsigned long)rtlpci->rx_ring[rx_queue_idx].desc & 0xFF) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Cannot allocate RX ring\n")); + "Cannot allocate RX ring\n"); return -ENOMEM; } @@ -1355,7 +1348,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, u8 temp_one = 1; if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -1388,10 +1381,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, if ((own == 1) && (hw_queue != BEACON_QUEUE)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("No more TX desc@%d, ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); spin_unlock_irqrestore(&rtlpriv->locks.irq_th_lock, flags); return skb->len; @@ -1426,11 +1418,9 @@ static int rtl_pci_tx(struct ieee80211_hw *hw, struct sk_buff *skb, hw_queue != BEACON_QUEUE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, - ("less desc left, stop skb_queue@%d, " - "ring->idx = %d," - "idx = %d, skb_queue_len = 0x%d\n", - hw_queue, ring->idx, idx, - skb_queue_len(&ring->queue))); + "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", + hw_queue, ring->idx, idx, + skb_queue_len(&ring->queue)); ieee80211_stop_queue(hw, skb_get_queue_mapping(skb)); } @@ -1497,7 +1487,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) err = _rtl_pci_init_trx_ring(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("tx ring initialization failed")); + "tx ring initialization failed\n"); return err; } @@ -1519,12 +1509,12 @@ static int rtl_pci_start(struct ieee80211_hw *hw) err = rtlpriv->cfg->ops->hw_init(hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Failed to config hardware!\n")); + "Failed to config hardware!\n"); return err; } rtlpriv->cfg->ops->enable_interrupt(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable_interrupt OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable_interrupt OK\n"); rtl_init_rx_config(hw); @@ -1535,7 +1525,7 @@ static int rtl_pci_start(struct ieee80211_hw *hw) rtlpci->up_first_time = false; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); return 0; } @@ -1622,20 +1612,20 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, switch (revisionid) { case RTL_PCI_REVISION_ID_8192PCIE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192 PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192 PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192E; break; case RTL_PCI_REVISION_ID_8192SE: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192SE is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192SE is found - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device - " - "vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = HARDWARE_TYPE_RTL8192SE; break; @@ -1646,18 +1636,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, deviceid == RTL_PCI_8188CE_DID) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192CE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192C PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192C PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else if (deviceid == RTL_PCI_8192DE_DID || deviceid == RTL_PCI_8192DE_DID2) { rtlhal->hw_type = HARDWARE_TYPE_RTL8192DE; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("8192D PCI-E is found - " - "vid/did=%x/%x\n", venderid, deviceid)); + "8192D PCI-E is found - vid/did=%x/%x\n", + venderid, deviceid); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Err: Unknown device -" - " vid/did=%x/%x\n", venderid, deviceid)); + "Err: Unknown device - vid/did=%x/%x\n", + venderid, deviceid); rtlhal->hw_type = RTL_DEFAULT_HARDWARE_TYPE; } @@ -1665,19 +1655,18 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) { if (revisionid == 0 || revisionid == 1) { if (revisionid == 0) { - RT_TRACE(rtlpriv, COMP_INIT, - DBG_LOUD, ("Find 92DE MAC0.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Find 92DE MAC0\n"); rtlhal->interfaceindex = 0; } else if (revisionid == 1) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Find 92DE MAC1.\n")); + "Find 92DE MAC1\n"); rtlhal->interfaceindex = 1; } } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Unknown device - " - "VendorID/DeviceID=%x/%x, Revision=%x\n", - venderid, deviceid, revisionid)); + "Unknown device - VendorID/DeviceID=%x/%x, Revision=%x\n", + venderid, deviceid, revisionid); rtlhal->interfaceindex = 0; } } @@ -1693,8 +1682,8 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, if (bridge_pdev->vendor == pcibridge_vendors[tmp]) { pcipriv->ndis_adapter.pcibridge_vendor = tmp; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Pci Bridge Vendor is found index:" - " %d\n", tmp)); + "Pci Bridge Vendor is found index: %d\n", + tmp); break; } } @@ -1723,23 +1712,21 @@ static bool _rtl_pci_find_adapter(struct pci_dev *pdev, } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pcidev busnumber:devnumber:funcnumber:" - "vendor:link_ctl %d:%d:%d:%x:%x\n", - pcipriv->ndis_adapter.busnumber, - pcipriv->ndis_adapter.devnumber, - pcipriv->ndis_adapter.funcnumber, - pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg)); + "pcidev busnumber:devnumber:funcnumber:vendor:link_ctl %d:%d:%d:%x:%x\n", + pcipriv->ndis_adapter.busnumber, + pcipriv->ndis_adapter.devnumber, + pcipriv->ndis_adapter.funcnumber, + pdev->vendor, pcipriv->ndis_adapter.linkctrl_reg); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("pci_bridge busnumber:devnumber:funcnumber:vendor:" - "pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", - pcipriv->ndis_adapter.pcibridge_busnum, - pcipriv->ndis_adapter.pcibridge_devnum, - pcipriv->ndis_adapter.pcibridge_funcnum, - pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], - pcipriv->ndis_adapter.pcibridge_pciehdr_offset, - pcipriv->ndis_adapter.pcibridge_linkctrlreg, - pcipriv->ndis_adapter.amd_l1_patch)); + "pci_bridge busnumber:devnumber:funcnumber:vendor:pcie_cap:link_ctl_reg:amd %d:%d:%d:%x:%x:%x:%x\n", + pcipriv->ndis_adapter.pcibridge_busnum, + pcipriv->ndis_adapter.pcibridge_devnum, + pcipriv->ndis_adapter.pcibridge_funcnum, + pcibridge_vendors[pcipriv->ndis_adapter.pcibridge_vendor], + pcipriv->ndis_adapter.pcibridge_pciehdr_offset, + pcipriv->ndis_adapter.pcibridge_linkctrlreg, + pcipriv->ndis_adapter.amd_l1_patch); rtl_pci_parse_configuration(pdev, hw); @@ -1828,10 +1815,9 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("mem mapped space: start: 0x%08lx len:%08lx " - "flags:%08lx, after map:0x%08lx\n", - pmem_start, pmem_len, pmem_flags, - rtlpriv->io.pci_mem_start)); + "mem mapped space: start: 0x%08lx len:%08lx flags:%08lx, after map:0x%08lx\n", + pmem_start, pmem_len, pmem_flags, + rtlpriv->io.pci_mem_start); /* Disable Clk Request */ pci_write_config_byte(pdev, 0x81, 0); @@ -1851,8 +1837,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto fail3; } @@ -1865,22 +1850,21 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto fail3; } /* Init PCI sw */ err = !rtl_pci_init(hw, pdev); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init PCI.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to init PCI\n"); goto fail3; } err = ieee80211_register_hw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + "Can't register mac80211 hw\n"); goto fail3; } else { rtlpriv->mac80211.mac80211_registered = 1; @@ -1889,7 +1873,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("failed to create sysfs device attributes\n")); + "failed to create sysfs device attributes\n"); goto fail3; } @@ -1901,8 +1885,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, IRQF_SHARED, KBUILD_MODNAME, hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%s: failed to register IRQ handler\n", - wiphy_name(hw->wiphy))); + "%s: failed to register IRQ handler\n", + wiphy_name(hw->wiphy)); goto fail3; } else { rtlpci->irq_alloc = 1; diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index 130fdd99d57..a36dc3d5e04 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -44,7 +44,7 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Driver is already down!\n")); + "Driver is already down!\n"); /*<2> Enable Adapter */ rtlpriv->cfg->ops->hw_init(hw); @@ -120,7 +120,7 @@ bool rtl_ps_set_rf_state(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -176,7 +176,7 @@ void rtl_ips_nic_off_wq_callback(void *data) if (mac->opmode != NL80211_IFTYPE_STATION) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("not station return\n")); + "not station return\n"); return; } @@ -207,7 +207,7 @@ void rtl_ips_nic_off_wq_callback(void *data) (mac->link_state == MAC80211_NOLINK) && !mac->act_scanning) { RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("IPSEnter(): Turn off RF.\n")); + "IPSEnter(): Turn off RF\n"); ppsc->inactive_pwrstate = ERFOFF; ppsc->in_powersavemode = true; @@ -280,8 +280,7 @@ static bool rtl_get_fwlps_doze(struct ieee80211_hw *hw) if (ps_timediff < 2000) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Delay enter Fw LPS for DHCP, ARP," - " or EAPOL exchanging state.\n")); + "Delay enter Fw LPS for DHCP, ARP, or EAPOL exchanging state\n"); return false; } @@ -328,8 +327,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) bool fw_current_inps; if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS leave ps_mode:%x\n", - FW_PS_ACTIVE_MODE)); + "FW LPS leave ps_mode:%x\n", + FW_PS_ACTIVE_MODE); rpwm_val = 0x0C; /* RF on */ fw_pwrmode = FW_PS_ACTIVE_MODE; @@ -347,8 +346,8 @@ static void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode) } else { if (rtl_get_fwlps_doze(hw)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("FW LPS enter ps_mode:%x\n", - ppsc->fwctrl_psmode)); + "FW LPS enter ps_mode:%x\n", + ppsc->fwctrl_psmode); rpwm_val = 0x02; /* RF off */ fw_current_inps = true; @@ -402,7 +401,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw) if (mac->cnt_after_linked >= 2) { if (ppsc->dot11_psmode == EACTIVE) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Enter 802.11 power save mode...\n")); + "Enter 802.11 power save mode...\n"); rtl_lps_set_psmode(hw, EAUTOPS); } @@ -434,7 +433,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Busy Traffic,Leave 802.11 power save..\n")); + "Busy Traffic,Leave 802.11 power save..\n"); rtl_lps_set_psmode(hw, EACTIVE); } @@ -518,8 +517,8 @@ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len) queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("u_bufferd: %x, " - "m_buffered: %x\n", u_buffed, m_buffed)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "u_bufferd: %x, m_buffered: %x\n", u_buffed, m_buffed); } } @@ -607,8 +606,8 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw) * sleep = dtim_period, that meaons, we should * awake before every dtim */ RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("dtim_counter:%x will sleep :%d" - " beacon_intv\n", rtlpriv->psc.dtim_counter, sleep_intv)); + "dtim_counter:%x will sleep :%d beacon_intv\n", + rtlpriv->psc.dtim_counter, sleep_intv); /* we tested that 40ms is enough for sw & hw sw delay */ queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_rfon_wq, diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 539df66dce0..4f560d6a386 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -251,7 +251,7 @@ static void *rtl_rate_alloc_sta(void *ppriv, rate_priv = kzalloc(sizeof(struct rtl_rate_priv), gfp); if (!rate_priv) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unable to allocate private rc structure\n")); + "Unable to allocate private rc structure\n"); return NULL; } diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index 9fedb1f7091..c263df21760 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -398,13 +398,11 @@ int rtl_regd_init(struct ieee80211_hw *hw, rtlpriv->regd.country_code = rtlpriv->efuse.channel_plan; RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: EEPROM regdomain: 0x%0x\n", - rtlpriv->regd.country_code)); + "rtl: EEPROM regdomain: 0x%0x\n", rtlpriv->regd.country_code); if (rtlpriv->regd.country_code >= COUNTRY_CODE_MAX) { RT_TRACE(rtlpriv, COMP_REGD, DBG_DMESG, - (KERN_DEBUG "rtl: EEPROM indicates invalid contry code" - "world wide 13 should be used\n")); + "rtl: EEPROM indicates invalid contry code, world wide 13 should be used\n"); rtlpriv->regd.country_code = COUNTRY_CODE_WORLD_WIDE_13; } @@ -420,8 +418,8 @@ int rtl_regd_init(struct ieee80211_hw *hw, } RT_TRACE(rtlpriv, COMP_REGD, DBG_TRACE, - (KERN_DEBUG "rtl: Country alpha2 being used: %c%c\n", - rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1])); + "rtl: Country alpha2 being used: %c%c\n", + rtlpriv->regd.alpha2[0], rtlpriv->regd.alpha2[1]); _rtl_regd_init_wiphy(&rtlpriv->regd, wiphy, reg_notifier); @@ -433,7 +431,7 @@ int rtl_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_REGD, DBG_LOUD, "\n"); return _rtl_reg_notifier_apply(wiphy, request, &rtlpriv->regd); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index 72a98cab6f6..bf94cbfb4e3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -246,16 +246,15 @@ static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_parity_fail = %d, cnt_rate_illegal = %d, " - "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", - falsealm_cnt->cnt_parity_fail, - falsealm_cnt->cnt_rate_illegal, - falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail)); + "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", + falsealm_cnt->cnt_parity_fail, + falsealm_cnt->cnt_rate_illegal, + falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", - falsealm_cnt->cnt_ofdm_fail, - falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all)); + "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", + falsealm_cnt->cnt_ofdm_fail, + falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); } static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) @@ -313,8 +312,8 @@ static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) dm_digtable.backoff_val; RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("rssi_val_min = %x backoff_val %x\n", - dm_digtable.rssi_val_min, dm_digtable.backoff_val)); + "rssi_val_min = %x backoff_val %x\n", + dm_digtable.rssi_val_min, dm_digtable.backoff_val); rtl92c_dm_write_dig(hw); } @@ -364,10 +363,9 @@ static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) } RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("curmultista_connectstate = " - "%x dig_ext_port_stage %x\n", - dm_digtable.curmultista_connectstate, - dm_digtable.dig_ext_port_stage)); + "curmultista_connectstate = %x dig_ext_port_stage %x\n", + dm_digtable.curmultista_connectstate, + dm_digtable.dig_ext_port_stage); } static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) @@ -375,10 +373,9 @@ static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("presta_connectstate = %x," - " cursta_connectctate = %x\n", - dm_digtable.presta_connectstate, - dm_digtable.cursta_connectctate)); + "presta_connectstate = %x, cursta_connectctate = %x\n", + dm_digtable.presta_connectstate, + dm_digtable.cursta_connectctate); if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT @@ -464,11 +461,11 @@ static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "CCKPDStage=%x\n", + dm_digtable.cur_cck_pd_state); - RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, - ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE, "is92C=%x\n", + IS_92C_SERIAL(rtlhal->version)); } static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) @@ -519,10 +516,9 @@ void rtl92c_dm_write_dig(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", - dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, - dm_digtable.backoff_val)); + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", + dm_digtable.cur_igvalue, dm_digtable.pre_igvalue, + dm_digtable.backoff_val); if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) { rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, @@ -676,15 +672,14 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.txpower_trackinginit = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n")); + "rtl92c_dm_txpower_tracking_callback_thermalmeter\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter); rtl92c_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); @@ -702,10 +697,9 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx, " - "ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATXIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -719,11 +713,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw MASKOFDM_D)) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial pathB ele_d reg0x%x = " - "0x%lx, ofdm_index=0x%x\n", - ROFDM0_XBTXIQIMBALANCE, ele_d, - ofdm_index_old[1])); + DBG_LOUD, + "Initial pathB ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", + ROFDM0_XBTXIQIMBALANCE, ele_d, + ofdm_index_old[1]); break; } } @@ -741,11 +734,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { @@ -757,11 +749,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch14 %d\n", - RCCK0_TXFILTER2, temp_cck, - cck_index_old, - rtlpriv->dm.cck_inch14)); + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -790,12 +781,10 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw (rtlpriv->dm.thermalvalue_iqk - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", thermalvalue, rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + delta_iqk); if (delta_lck > 1) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -815,18 +804,15 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x," - "cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } if (thermalvalue > rtlefuse->eeprom_thermalmeter) { @@ -918,16 +904,13 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, " - "OFDM_B_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], ofdm_index[1], - cck_index)); + "new OFDM_A_index=0x%x, OFDM_B_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], ofdm_index[1], + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x," - "cck_index=0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x, cck_index=0x%x\n", + ofdm_index[0], cck_index); } } @@ -1085,7 +1068,7 @@ static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } @@ -1098,8 +1081,8 @@ static void rtl92c_dm_initialize_txpower_tracking_thermalmeter( rtlpriv->dm.txpower_trackinginit = false; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1125,12 +1108,12 @@ static void rtl92c_dm_check_txpower_tracking_thermal_meter( rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK, 0x60); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92c_dm_txpower_tracking_directcall(hw); tm_trigger = 0; } @@ -1169,13 +1152,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) if (is_hal_stop(rtlhal)) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver is going to unload\n")); + "<---- driver is going to unload\n"); return; } if (!rtlpriv->dm.useramask) { RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("<---- driver does not control rate adaptive mask\n")); + "<---- driver does not control rate adaptive mask\n"); return; } @@ -1210,14 +1193,13 @@ static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) p_ra->ratr_state = DM_RATR_STA_LOW; if (p_ra->pre_ratr_state != p_ra->ratr_state) { + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, "RSSI = %ld\n", + rtlpriv->dm.undecorated_smoothed_pwdb); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI = %ld\n", - rtlpriv->dm.undecorated_smoothed_pwdb)); + "RSSI_LEVEL = %d\n", p_ra->ratr_state); RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("RSSI_LEVEL = %d\n", p_ra->ratr_state)); - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, - ("PreState = %d, CurState = %d\n", - p_ra->pre_ratr_state, p_ra->ratr_state)); + "PreState = %d, CurState = %d\n", + p_ra->pre_ratr_state, p_ra->ratr_state); rcu_read_lock(); sta = ieee80211_find_sta(mac->vif, mac->bssid); @@ -1316,8 +1298,7 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) if (((mac->link_state == MAC80211_NOLINK)) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { dm_pstable.rssi_val_min = 0; - RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("Not connected to any\n")); + RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, "Not connected to any\n"); } if (mac->link_state == MAC80211_LINKED) { @@ -1325,22 +1306,22 @@ static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Client PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } else { dm_pstable.rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "STA Default Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } } else { dm_pstable.rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - dm_pstable.rssi_val_min)); + "AP Ext Port PWDB = 0x%lx\n", + dm_pstable.rssi_val_min); } if (IS_92C_SERIAL(rtlhal->version)) @@ -1381,7 +1362,7 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -1394,28 +1375,28 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -1423,18 +1404,18 @@ void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 5401b32733d..12c025bf53b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -172,7 +172,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 *bufferPtr = (u8 *) buffer; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes\n", size); if (IS_CHIP_VER_B(version)) { u32 pageNums, remainSize; @@ -186,7 +186,7 @@ static void _rtl92c_write_fw(struct ieee80211_hw *hw, if (pageNums > 4) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 4\n")); + "Page numbers should not greater then 4\n"); } for (page = 0; page < pageNums; page++) { @@ -219,13 +219,12 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) if (counter >= FW_8192C_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; @@ -238,9 +237,8 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); if (value32 & WINTINI_RDY) { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Polling FW ready success!!" - " REG_MCUFWDL:0x%08x .\n", - value32)); + "Polling FW ready success!! REG_MCUFWDL:0x%08x\n", + value32); return 0; } @@ -249,7 +247,7 @@ static int _rtl92c_fw_free_to_go(struct ieee80211_hw *hw) } while (counter++ < FW_8192C_POLLING_TIMEOUT_COUNT); RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08x .\n", value32)); + "Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", value32); return -EIO; } @@ -272,10 +270,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Firmware Version(%d), Signature(%#x),Size(%d)\n", + "Firmware Version(%d), Signature(%#x),Size(%d)\n", le16_to_cpu(pfwheader->version), le16_to_cpu(pfwheader->signature), - (uint)sizeof(struct rtl92c_firmware_header))); + (uint)sizeof(struct rtl92c_firmware_header)); pfwdata = pfwdata + sizeof(struct rtl92c_firmware_header); fwsize = fwsize - sizeof(struct rtl92c_firmware_header); @@ -287,10 +285,10 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) if (_rtl92c_fw_free_to_go(hw)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is not ready to run!\n")); + "Firmware is not ready to run!\n"); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Firmware is ready to run!\n")); + "Firmware is ready to run!\n"); } return 0; @@ -328,22 +326,22 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, unsigned long flag; u8 idx; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -363,8 +361,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } @@ -388,7 +385,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -398,8 +395,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } @@ -408,14 +405,14 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, isfw_read = _rtl92c_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read\n", + boxnum); break; } @@ -423,8 +420,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: @@ -493,7 +490,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -504,15 +501,15 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, @@ -562,7 +559,7 @@ void rtl92c_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = {0}; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); @@ -798,14 +795,14 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92c_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } EXPORT_SYMBOL(rtl92c_set_fw_rsvdpagepkt); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 1f07558debf..8ab93a69f33 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -42,16 +42,15 @@ u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, - bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, - regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -64,9 +63,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -76,9 +75,9 @@ void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, - data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); @@ -114,7 +113,7 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, offset &= 0x3f; newoffset = offset; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); return 0xFFFFFFFF; } tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); @@ -144,9 +143,8 @@ u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, - retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); @@ -162,16 +160,15 @@ void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; if (RT_CANNOT_IO(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); return; } offset &= 0x3f; newoffset = offset; data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, - data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); @@ -216,16 +213,16 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } if (rtlphy->rf_type == RF_1T2R) { _rtl92c_phy_bb_config_1t(hw); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); } if (rtlefuse->autoload_failflag == false) { rtlphy->pwrgroup_cnt = 0; @@ -233,13 +230,13 @@ bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) BASEBAND_CONFIG_PHY_REG); } if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -260,114 +257,114 @@ void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, if (regaddr == RTXAGC_A_RATE18_06) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0]); } if (regaddr == RTXAGC_A_RATE54_24) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1]); } if (regaddr == RTXAGC_A_CCK1_MCS32) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7]); } if (regaddr == RTXAGC_A_MCS03_MCS00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2]); } if (regaddr == RTXAGC_A_MCS07_MCS04) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3]); } if (regaddr == RTXAGC_A_MCS11_MCS08) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4]); } if (regaddr == RTXAGC_A_MCS15_MCS12) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5]); } if (regaddr == RTXAGC_B_RATE18_06) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8]); } if (regaddr == RTXAGC_B_RATE54_24) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9]); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15]); } if (regaddr == RTXAGC_B_MCS03_MCS00) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10]); } if (regaddr == RTXAGC_B_MCS07_MCS04) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11]); } if (regaddr == RTXAGC_B_MCS11_MCS08) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12]); } if (regaddr == RTXAGC_B_MCS15_MCS12) { rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", - rtlphy->pwrgroup_cnt, - rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", + rtlphy->pwrgroup_cnt, + rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13]); rtlphy->pwrgroup_cnt++; } @@ -389,12 +386,11 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); @@ -402,8 +398,8 @@ void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) @@ -615,8 +611,8 @@ bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) else ofdmtxpwridx = 0; RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, - ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", - power_indbm, ccktxpwridx, ofdmtxpwridx)); + "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", + power_indbm, ccktxpwridx, ofdmtxpwridx); for (idx = 0; idx < 14; idx++) { for (rf_path = 0; rf_path < 2; rf_path++) { rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; @@ -710,7 +706,7 @@ void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -732,7 +728,7 @@ void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); rtlphy->set_bwmode_inprogress = false; rtlphy->current_chan_bw = tmp_bw; } @@ -747,7 +743,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) u32 delay; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); if (is_hal_stop(rtlhal)) return; do { @@ -765,7 +761,7 @@ void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); @@ -787,12 +783,11 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl92c_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false schdule workitem\n")); + "sw_chnl_inprogress false schdule workitem\n"); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or" - " unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); rtlphy->sw_chnl_inprogress = false; } return 1; @@ -916,7 +911,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -1920,23 +1915,23 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -1947,7 +1942,7 @@ bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92c_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); @@ -1958,8 +1953,8 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -1973,12 +1968,12 @@ void rtl92c_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } EXPORT_SYMBOL(rtl92c_phy_set_io); @@ -2018,7 +2013,7 @@ void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 2df33e53e15..6730e683aba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -54,7 +54,7 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -67,28 +67,28 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -96,18 +96,18 @@ void rtl92ce_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 2156378de1e..4aa228fe96e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -141,7 +141,7 @@ void rtl92ce_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -207,7 +207,7 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); @@ -246,8 +246,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -261,8 +261,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -310,8 +310,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -348,8 +348,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -365,14 +365,14 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -507,8 +507,8 @@ void rtl92ce_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -530,8 +530,8 @@ static bool _rtl92ce_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -669,18 +669,15 @@ static bool _rtl92ce_init_mac(struct ieee80211_hw *hw) udelay(2); retry = 0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); while ((bytetmp & BIT(0)) && retry < 1000) { retry++; udelay(50); bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("reg0xec:%x:%x\n", - rtl_read_dword(rtlpriv, - 0xEC), - bytetmp)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "reg0xec:%x:%x\n", + rtl_read_dword(rtlpriv, 0xEC), bytetmp); udelay(50); } @@ -864,13 +861,13 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("not open " - "hw encryption\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, + "not open hw encryption\n"); return; } @@ -886,7 +883,7 @@ void rtl92ce_enable_hw_security_config(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -910,7 +907,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtlpriv->intf_ops->disable_aspm(hw); rtstatus = _rtl92ce_init_mac(hw); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; return err; } @@ -918,8 +915,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; rtlhal->fw_ready = false; return err; @@ -968,12 +964,12 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) tmp_u1b = efuse_read_1byte(hw, 0x1FA); if (!(tmp_u1b & BIT(0))) { rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path A\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path A\n"); } if (!(tmp_u1b & BIT(1)) && is92c) { rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("PA BIAS path B\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "PA BIAS path B\n"); } if (!(tmp_u1b & BIT(4))) { @@ -982,7 +978,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x80); udelay(10); rtl_write_byte(rtlpriv, 0x16, tmp_u1b | 0x90); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("under 1.5V\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "under 1.5V\n"); } rtl92c_dm_init(hw); rtlpci->being_init_adapter = false; @@ -1008,23 +1004,23 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) switch (version) { case VERSION_B_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + "Chip Version ID: VERSION_B_CHIP_92C\n"); break; case VERSION_B_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_88C.\n")); + "Chip Version ID: VERSION_B_CHIP_88C\n"); break; case VERSION_A_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_92C.\n")); + "Chip Version ID: VERSION_A_CHIP_92C\n"); break; case VERSION_A_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_A_CHIP_88C.\n")); + "Chip Version ID: VERSION_A_CHIP_88C\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Chip Version ID: Unknown. Bug?\n")); + "Chip Version ID: Unknown. Bug?\n"); break; } @@ -1041,13 +1037,12 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) default: rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("ERROR RF_Type is set!!")); + "ERROR RF_Type is set!!\n"); break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); return version; } @@ -1069,8 +1064,8 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, _rtl92ce_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: " - "No such media status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } switch (type) { @@ -1078,27 +1073,27 @@ static int _rtl92ce_set_media_status(struct ieee80211_hw *hw, bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1300,7 +1295,7 @@ void rtl92ce_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); rtl92ce_disable_interrupt(hw); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); rtl92ce_enable_interrupt(hw); @@ -1312,8 +1307,8 @@ void rtl92ce_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1567,7 +1562,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", @@ -1576,10 +1571,10 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1591,8 +1586,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92ce_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, @@ -1608,7 +1602,7 @@ static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1662,7 +1656,7 @@ static void _rtl92ce_hal_customized_behavior(struct ieee80211_hw *hw) break; } RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + "RT Customized ID: 0x%02X\n", rtlhal->oem_id); } void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) @@ -1679,22 +1673,22 @@ void rtl92ce_read_eeprom_info(struct ieee80211_hw *hw) else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92ce_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } _rtl92ce_hal_customized_behavior(hw); } @@ -1790,8 +1784,8 @@ static void rtl92ce_update_hal_rate_table(struct ieee80211_hw *hw, rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -1919,16 +1913,15 @@ static void rtl92ce_update_hal_rate_mask(struct ieee80211_hw *hw, break; } RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x\n", ratr_bitmap)); + "ratr_bitmap :%x\n", ratr_bitmap); *(u32 *)&rate_mask = EF4BYTE((ratr_bitmap & 0x0fffffff) | (ratr_index << 28)); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); if (macid != 0) @@ -1994,7 +1987,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; @@ -2002,7 +1995,7 @@ bool rtl92ce_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) } else if ((ppsc->hwradiooff == false) && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2053,7 +2046,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2081,8 +2074,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2100,9 +2093,8 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2116,22 +2108,22 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -2140,7 +2132,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2149,7 +2141,7 @@ void rtl92ce_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 28a1a707d09..09758f48d3e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -45,8 +45,8 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -62,7 +62,7 @@ void rtl92ce_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -97,7 +97,7 @@ void rtl92ce_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -145,7 +145,7 @@ void rtl92ce_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d.\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", + ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index ce9eea94bb5..03ee82e05f2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -47,9 +47,9 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -67,9 +67,8 @@ u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -121,8 +120,8 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -153,10 +152,9 @@ void rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), " - "rfpath(%#x)\n", regaddr, - bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) @@ -166,11 +164,10 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = RTL8192CEMAC_2T_ARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -215,10 +212,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -226,10 +222,9 @@ bool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -269,7 +264,7 @@ bool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -291,20 +286,20 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = RADIOB_2TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_2TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = RADIOA_1TARRAYLENGTH; radioa_array_table = RTL8192CE_RADIOA_1TARRAY; radiob_arraylen = RADIOB_1TARRAYLENGTH; radiob_array_table = RTL8192CE_RADIOB_1TARRAY; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -352,11 +347,11 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -371,10 +366,9 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; @@ -398,7 +392,7 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -423,12 +417,12 @@ void rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) @@ -499,7 +493,7 @@ static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Switch RF timeout !!!.\n")); + "Switch RF timeout !!!\n"); return; } rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); @@ -526,7 +520,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -534,10 +528,10 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -553,7 +547,7 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -578,35 +572,33 @@ static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92ce_phy_set_rf_sleep(hw); break; } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index d3b01e6023b..3ba1a4feeb3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -56,7 +56,7 @@ void rtl92ce_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -512,12 +512,12 @@ static bool _rtl92ce_phy_rf6052_config_parafile(struct ieee80211_hw *hw) if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!\n", rfpath); return false; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 89ef6982ce5..d2a3576fdaa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -159,7 +159,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -174,12 +174,12 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x4000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 378bc567346..9f6fac450a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -725,7 +725,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -763,7 +763,7 @@ void rtl92ce_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(pdesc, 1); } - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92ce_tx_fill_cmddesc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index f311baee668..c0016f3194e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -52,7 +52,7 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; @@ -65,28 +65,28 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && (undecorated_smoothed_pwdb >= @@ -94,18 +94,18 @@ void rtl92cu_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 778c0e6e836..80bd17d8593 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -494,17 +494,17 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP", hwinfo, HWSET_MAX_SIZE); eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0])); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) @@ -518,16 +518,15 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->autoload_failflag, hwinfo); rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]); rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" VID = 0x%02x PID = 0x%02x\n", - rtlefuse->eeprom_vid, rtlefuse->eeprom_did)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n", + rtlefuse->eeprom_vid, rtlefuse->eeprom_did); rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->eeprom_version = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]); rtlefuse->txpwr_fromeprom = true; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", + rtlefuse->eeprom_oemid); if (rtlhal->oem_id == RT_CID_DEFAULT) { switch (rtlefuse->eeprom_oemid) { case EEPROM_CID_DEFAULT: @@ -579,8 +578,8 @@ static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) default: break; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("RT Customized ID: 0x%02X\n", rtlhal->oem_id)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", + rtlhal->oem_id); } void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) @@ -596,11 +595,11 @@ void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? EEPROM_93C46 : EEPROM_BOOT_EFUSE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from %s\n", - (tmp_u1b & BOOT_FROM_EEPROM) ? "EERROM" : "EFUSE")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", + tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload %s\n", - (tmp_u1b & EEPROM_EN) ? "OK!!" : "ERR!!")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", + tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); _rtl92cu_read_adapter_info(hw); _rtl92cu_hal_customized_behavior(hw); return; @@ -618,13 +617,12 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) do { if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Autoload Done!\n")); + "Autoload Done!\n"); break; } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[PFM_ALDN]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); return -ENODEV; } } while (true); @@ -639,8 +637,8 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) value8 |= LDV12_EN; rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - (" power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x.\n", - value8)); + " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", + value8); udelay(100); value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); value8 &= ~ISO_MD2PP; @@ -658,8 +656,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw) } if (pollingCount++ > 100) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Failed to polling REG_APS_FSMCO[APFM_ONMAC]" - " done!\n")); + "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); return -ENODEV; } } while (true); @@ -877,8 +874,8 @@ static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw, hiQ = QUEUE_HIGH; } _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", queue_sel)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + queue_sel); } static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw, @@ -937,8 +934,8 @@ static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw, break; } rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Tx queue select :0x%02x..\n", hq_sele)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n", + hq_sele); } static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, @@ -998,7 +995,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init power on!\n")); + "Failed to init power on!\n"); return err; } if (!wmm_enable) { @@ -1010,7 +1007,7 @@ static int _rtl92cu_init_mac(struct ieee80211_hw *hw) } if (false == rtl92c_init_llt_table(hw, boundary)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to init LLT Table!\n")); + "Failed to init LLT Table!\n"); return -EINVAL; } _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, @@ -1043,12 +1040,12 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtlpriv); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open sw encryption\n")); + "not open sw encryption\n"); return; } sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable; @@ -1059,8 +1056,8 @@ void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) if (IS_NORMAL_CHIP(rtlhal->version)) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -1163,13 +1160,13 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; err = _rtl92cu_init_mac(hw); if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("init mac failed!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); return err; } err = rtl92c_download_fw(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW without FW now..\n")); + "Failed to download FW. Init HW without FW now..\n"); err = 1; rtlhal->fw_ready = false; return err; @@ -1280,8 +1277,7 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) } if (retry_cnts >= 100) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("#####=> 8051 reset failed!.." - ".......................\n");); + "#####=> 8051 reset failed!.........................\n"); /* if 8051 reset fail, reset MAC. */ rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, @@ -1495,35 +1491,36 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw, _rtl92cu_resume_tx_beacon(hw); _rtl92cu_disable_bcn_sub_func(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("Set HW_VAR_MEDIA_" - "STATUS:No such media status(%x).\n", type)); + RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, + "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", + type); } switch (type) { case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= MSR_NOLINK; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); goto error_out; } rtl_write_byte(rtlpriv, (MSR), bt_msr); @@ -1684,8 +1681,8 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) value32 |= TSFRST; rtl_write_dword(rtlpriv, REG_TCR, value32); RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD, - ("SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", - value32)); + "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", + value32); /* TODO: Modify later (Find the right parameters) * NOTE: Fix test chip's bug (about contention windows's randomness) */ if ((mac->opmode == NL80211_IFTYPE_ADHOC) || @@ -1702,8 +1699,8 @@ void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u16 bcn_interval = mac->beacon_interval; - RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", + bcn_interval); rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); } @@ -1767,7 +1764,7 @@ void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -1827,8 +1824,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); - RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SIFS\n")); + RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); break; } case HW_VAR_SLOT_TIME:{ @@ -1837,7 +1833,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, REG_SLOT, val[0]); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); if (QOS_MODE) { for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -1901,8 +1897,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -1916,8 +1912,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg &= 0x07; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -1950,8 +1946,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) p_regtoset[index]); } RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -1969,8 +1965,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) AC_PARAM_ECW_MAX_OFFSET); u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("queue:%x, ac_param:%x\n", e_aci, - u4b_ac_param)); + "queue:%x, ac_param:%x\n", + e_aci, u4b_ac_param); switch (e_aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, @@ -2020,8 +2016,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -2037,13 +2033,13 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -2051,7 +2047,7 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); mac->rx_conf = ((u32 *) (val))[0]; RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG, - ("### Set RCR(0x%08x) ###\n", mac->rx_conf)); + "### Set RCR(0x%08x) ###\n", mac->rx_conf); break; } case HW_VAR_RETRY_LIMIT:{ @@ -2060,8 +2056,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RL, retry_limit << RETRY_LIMIT_SHORT_SHIFT | retry_limit << RETRY_LIMIT_LONG_SHIFT); - RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, ("Set HW_VAR_R" - "ETRY_LIMIT(0x%08x)\n", retry_limit)); + RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG, + "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", + retry_limit); break; } case HW_VAR_DUAL_TSF_RST: @@ -2165,8 +2162,8 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -2239,8 +2236,8 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("%x\n", rtl_read_dword(rtlpriv, - REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) @@ -2344,17 +2341,16 @@ void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) ratr_bitmap &= 0x0f0ff0ff; break; } - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("ratr_bitmap :%x\n", - ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "ratr_bitmap :%x\n", + ratr_bitmap); *(u32 *)&rate_mask = ((ratr_bitmap & 0x0fffffff) | ratr_index << 28); rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, ("Rate_index:%x, " - "ratr_val:%x, %x:%x:%x:%x:%x\n", - ratr_index, ratr_bitmap, - rate_mask[0], rate_mask[1], - rate_mask[2], rate_mask[3], - rate_mask[4])); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, + "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x\n", + ratr_index, ratr_bitmap, + rate_mask[0], rate_mask[1], rate_mask[2], rate_mask[3], + rate_mask[4]); rtl92c_fill_h2c_cmd(hw, H2C_RA_MASK, 5, rate_mask); } @@ -2404,7 +2400,7 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(7)) ? ERFOFF : ERFON; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("pwrdown, 0x5c(BIT7)=%02x\n", u1tmp)); + "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); } else { rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, @@ -2413,27 +2409,26 @@ bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("GPIO_IN=%02x\n", u1tmp)); + "GPIO_IN=%02x\n", u1tmp); } - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("N-SS RF =%x\n", - e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", + e_rfpowerstate_toset); } if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW " - "Radio ON, RF ON\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio ON, RF ON\n"); ppsc->hwradiooff = false; actuallyset = true; } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("GPIOChangeRF - HW" - " Radio OFF\n")); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "GPIOChangeRF - HW Radio OFF\n"); ppsc->hwradiooff = true; actuallyset = true; } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD , - ("pHalData->bHwRadioOff and eRfPowerStateToSet do not" - " match: pHalData->bHwRadioOff %x, eRfPowerStateToSet " - "%x\n", ppsc->hwradiooff, e_rfpowerstate_toset)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", + ppsc->hwradiooff, e_rfpowerstate_toset); } if (actuallyset) { ppsc->hwradiooff = true; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 2ff9d8314e7..65fd0442462 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -47,8 +47,8 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -62,7 +62,7 @@ void rtl92cu_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -74,8 +74,8 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_usb_priv *usbpriv = rtl_usbpriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -95,7 +95,7 @@ void rtl92cu_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -136,7 +136,6 @@ void rtl92cu_led_control(struct ieee80211_hw *hw, ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92cu_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 487ee908d7c..9f09844d7d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -88,67 +88,59 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_B_CHIP_92C.\n")); + "Chip Version ID: VERSION_B_CHIP_92C\n"); break; case VERSION_NORMAL_TSMC_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C.\n")); + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C\n"); break; case VERSION_NORMAL_TSMC_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C.\n")); + "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_i" - "92C_1T2R_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_i92C_1T2R_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP_" - "92C_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_A_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_A_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_1T2R_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_92C_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_B_CUT\n"); break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMAL_UMC_CHIP" - "_88C_B_CUT.\n")); + "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_B_CUT\n"); break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_A_CUT.\n")); + "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT\n"); break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_NORMA_UMC_CHIP" - "_8723_1T1R_B_CUT.\n")); + "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT\n"); break; case VERSION_TEST_CHIP_92C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_92C.\n")); + "Chip Version ID: VERSION_TEST_CHIP_92C\n"); break; case VERSION_TEST_CHIP_88C: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: VERSION_TEST_CHIP_88C.\n")); + "Chip Version ID: VERSION_TEST_CHIP_88C\n"); break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Chip Version ID: ???????????????.\n")); + "Chip Version ID: ???????????????\n"); break; } if (IS_92C_SERIAL(rtlhal->version)) @@ -157,15 +149,15 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) else rtlphy->rf_type = RF_1T1R; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? - "RF_2T2R" : "RF_1T1R")); + "Chip RF Type: %s\n", + rtlphy->rf_type == RF_2T2R ? "RF_2T2R" : "RF_1T1R"); if (get_rf_type(rtlphy) == RF_1T1R) rtlpriv->dm.rfpath_rxenable[0] = true; else rtlpriv->dm.rfpath_rxenable[0] = rtlpriv->dm.rfpath_rxenable[1] = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("VersionID = 0x%4x\n", - rtlhal->version)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", + rtlhal->version); } /** @@ -192,9 +184,8 @@ bool rtl92c_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at" - " address %d! _LLT_OP_VALUE(%x)\n", - address, _LLT_OP_VALUE(value))); + "Failed to polling write LLT done at address %d! _LLT_OP_VALUE(%x)\n", + address, _LLT_OP_VALUE(value)); status = false; break; } @@ -272,7 +263,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -298,7 +289,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("iillegal switch case\n")); + "illegal switch case\n"); enc_algo = CAM_TKIP; break; } @@ -317,18 +308,18 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry\n")); + "delete one entry\n"); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -336,7 +327,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, rtlpriv->sec. key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -345,7 +336,7 @@ void rtl92c_set_key(struct ieee80211_hw *hw, u32 key_index, key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, @@ -421,8 +412,8 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) AC_PARAM_ECW_MAX_OFFSET; u4b_ac_param |= (u32) le16_to_cpu(mac->ac[aci].tx_op) << AC_PARAM_TXOP_OFFSET; - RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, - ("queue:%x, ac_param:%x\n", aci, u4b_ac_param)); + RT_TRACE(rtlpriv, COMP_QOS, DBG_LOUD, "queue:%x, ac_param:%x\n", + aci, u4b_ac_param); switch (aci) { case AC1_BK: rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, u4b_ac_param); @@ -453,14 +444,14 @@ void rtl92c_set_mac_addr(struct ieee80211_hw *hw, const u8 *addr) for (i = 0 ; i < ETH_ALEN ; i++) rtl_write_byte(rtlpriv, (REG_MACID + i), *(addr+i)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("MAC Address: %02X-%02X-%02X-" - "%02X-%02X-%02X\n", - rtl_read_byte(rtlpriv, REG_MACID), - rtl_read_byte(rtlpriv, REG_MACID+1), - rtl_read_byte(rtlpriv, REG_MACID+2), - rtl_read_byte(rtlpriv, REG_MACID+3), - rtl_read_byte(rtlpriv, REG_MACID+4), - rtl_read_byte(rtlpriv, REG_MACID+5))); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, + "MAC Address: %02X-%02X-%02X-%02X-%02X-%02X\n", + rtl_read_byte(rtlpriv, REG_MACID), + rtl_read_byte(rtlpriv, REG_MACID+1), + rtl_read_byte(rtlpriv, REG_MACID+2), + rtl_read_byte(rtlpriv, REG_MACID+3), + rtl_read_byte(rtlpriv, REG_MACID+4), + rtl_read_byte(rtlpriv, REG_MACID+5)); } void rtl92c_init_driver_info_size(struct ieee80211_hw *hw, u8 size) @@ -478,26 +469,26 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) case NL80211_IFTYPE_UNSPECIFIED: value = NT_NO_LINK; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: value = NT_LINK_AD_HOC; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: value = NT_LINK_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: value = NT_AS_AP; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return -EOPNOTSUPP; } rtl_write_byte(rtlpriv, (REG_CR + 2), value); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index df491d38ecc..e7ea2bae210 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -44,9 +44,9 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; struct rtl_phy *rtlphy = &(rtlpriv->phy); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); if (rtlphy->rf_mode != RF_OP_BY_FW) { original_value = _rtl92c_phy_rf_serial_read(hw, rfpath, regaddr); @@ -57,9 +57,8 @@ u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw, bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -72,8 +71,8 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, u32 original_value, bitshift; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (rtlphy->rf_mode != RF_OP_BY_FW) { if (bitmask != RFREG_OFFSET_MASK) { original_value = _rtl92c_phy_rf_serial_read(hw, @@ -97,9 +96,9 @@ void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw, } _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); } - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw) @@ -152,11 +151,10 @@ bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = rtlphy->hwparam_tables[MAC_REG].length ; ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Img:RTL8192CEMAC_2T_ARRAY\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); return true; @@ -202,10 +200,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -213,10 +210,9 @@ bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_array_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The agctab_array_table[0] is " - "%x Rtl819XPHY_REGArray[1] is %x\n", - agctab_array_table[i], - agctab_array_table[i + 1])); + "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + agctab_array_table[i], + agctab_array_table[i + 1]); } } return true; @@ -255,7 +251,7 @@ bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -277,20 +273,20 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CERADIOA_2TARRAY\n")); + "Radio_A:RTL8192CERADIOA_2TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_2TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); } else { radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length; radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata; radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length; radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_A:RTL8192CE_RADIOA_1TARRAY\n")); + "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio_B:RTL8192CE_RADIOB_1TARRAY\n")); + "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); switch (rfpath) { case RF90_PATH_A: for (i = 0; i < radioa_arraylen; i = i + 2) { @@ -338,11 +334,11 @@ bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -357,10 +353,9 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) u8 reg_bw_opmode; u8 reg_prsr_rsc; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; return; @@ -381,7 +376,7 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -403,12 +398,12 @@ void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } void rtl92cu_bb_block_on(struct ieee80211_hw *hw) @@ -480,7 +475,7 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -488,10 +483,9 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFON sleeped:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc-> - last_sleep_jiffies))); + "Set ERFON sleeped:%d ms\n", + jiffies_to_msecs(jiffies - + ppsc->last_sleep_jiffies)); ppsc->last_awake_jiffies = jiffies; rtl92ce_phy_set_rf_on(hw); } @@ -513,27 +507,25 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] " - "=%d before doze!\n", (i + 1), - queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, + queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -557,33 +549,30 @@ static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue))); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", - jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + "Set ERFSLEEP awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); ppsc->last_sleep_jiffies = jiffies; _rtl92c_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 1e851aae58d..7b48ee9acb1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -56,7 +56,7 @@ void rtl92cu_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -482,11 +482,11 @@ static bool _rtl92c_phy_rf6052_config_parafile(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: return rtstatus; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 6d2ca773bbc..dee7aab4faa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -65,7 +65,7 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } /* request fw */ @@ -73,12 +73,12 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x4000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 128cfcd09fa..b875af75b89 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -108,7 +108,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB Chip-B & WMM Setting.....\n")); + "USB Chip-B & WMM Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 2; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -118,7 +118,7 @@ static void _TwoOutEpMapping(struct ieee80211_hw *hw, bool bIsChipB, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB typical Setting.....\n")); + "USB typical Setting.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 3; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 2; @@ -135,7 +135,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, struct rtl_priv *rtlpriv = rtl_priv(hw); if (bwificfg) { /* for WMM */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for WMM.....\n")); + "USB 3EP Setting for WMM.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 3; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -145,7 +145,7 @@ static void _ThreeOutEpMapping(struct ieee80211_hw *hw, bool bwificfg, ep_map->ep_mapping[RTL_TXQ_HI] = 2; } else { /* typical setting */ RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB 3EP Setting for typical.....\n")); + "USB 3EP Setting for typical.....\n"); ep_map->ep_mapping[RTL_TXQ_BE] = 5; ep_map->ep_mapping[RTL_TXQ_BK] = 5; ep_map->ep_mapping[RTL_TXQ_VI] = 3; @@ -270,23 +270,23 @@ static enum rtl_desc_qsel _rtl8192cu_mq_to_descq(struct ieee80211_hw *hw, case 0: /* VO */ qsel = QSLT_VO; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VO queue, set qsel = 0x%x\n", QSLT_VO)); + "VO queue, set qsel = 0x%x\n", QSLT_VO); break; case 1: /* VI */ qsel = QSLT_VI; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("VI queue, set qsel = 0x%x\n", QSLT_VI)); + "VI queue, set qsel = 0x%x\n", QSLT_VI); break; case 3: /* BK */ qsel = QSLT_BK; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BK queue, set qsel = 0x%x\n", QSLT_BK)); + "BK queue, set qsel = 0x%x\n", QSLT_BK); break; case 2: /* BE */ default: qsel = QSLT_BE; RT_TRACE(rtlpriv, COMP_USB, DBG_DMESG, - ("BE queue, set qsel = 0x%x\n", QSLT_BE)); + "BE queue, set qsel = 0x%x\n", QSLT_BE); break; } out: @@ -422,17 +422,17 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb) bv = ieee80211_is_probe_resp(fc); if (bv) RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got probe response frame.\n")); + "Got probe response frame\n"); if (ieee80211_is_beacon(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Got beacon frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got beacon frame\n"); if (ieee80211_is_data(fc)) - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Got data frame.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Got data frame\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:" - "0x%02X\n", fc, (u32)hdr->addr1[0], (u32)hdr->addr1[1], - (u32)hdr->addr1[2], (u32)hdr->addr1[3], (u32)hdr->addr1[4], - (u32)hdr->addr1[5])); + "Fram: fc = 0x%X addr1 = 0x%02X:0x%02X:0x%02X:0x%02X:0x%02X:0x%02X\n", + fc, + (u32)hdr->addr1[0], (u32)hdr->addr1[1], + (u32)hdr->addr1[2], (u32)hdr->addr1[3], + (u32)hdr->addr1[4], (u32)hdr->addr1[5]); memcpy(IEEE80211_SKB_RXCB(skb), rx_status, sizeof(*rx_status)); ieee80211_rx_irqsafe(hw, skb); } @@ -594,7 +594,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(txdesc, 1); SET_TX_DESC_HTC(txdesc, 1); } @@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(txdesc, 1); _rtl_fill_usb_tx_desc(txdesc); _rtl_tx_desc_checksum(txdesc); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, (" %s ==>\n", __func__)); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, " %s ==>\n", __func__); } void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 3cd0736fe8e..32537c4faf9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -246,23 +246,21 @@ static void rtl92d_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Fast_Fsync_fail = %x, " - "Cnt_SB_Search_fail = %x\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Fast_Fsync_fail = %x, Cnt_SB_Search_fail = %x\n", falsealm_cnt->cnt_fast_fsync_fail, - falsealm_cnt->cnt_sb_search_fail)); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Cnt_Parity_Fail = %x, " - "Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, " - "Cnt_Mcs_fail = %x\n", + falsealm_cnt->cnt_sb_search_fail); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "Cnt_Parity_Fail = %x, Cnt_Rate_Illegal = %x, Cnt_Crc8_fail = %x, Cnt_Mcs_fail = %x\n", falsealm_cnt->cnt_parity_fail, falsealm_cnt->cnt_rate_illegal, falsealm_cnt->cnt_crc8_fail, - falsealm_cnt->cnt_mcs_fail)); + falsealm_cnt->cnt_mcs_fail); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Cnt_Ofdm_fail = %x, " "Cnt_Cck_fail = %x, " - "Cnt_all = %x\n", + "Cnt_Ofdm_fail = %x, Cnt_Cck_fail = %x, Cnt_all = %x\n", falsealm_cnt->cnt_ofdm_fail, falsealm_cnt->cnt_cck_fail, - falsealm_cnt->cnt_all)); + falsealm_cnt->cnt_all); } static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) @@ -275,7 +273,7 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { de_digtable.min_undecorated_pwdb_for_dm = 0; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("Not connected to any\n")); + "Not connected to any\n"); } if (mac->link_state >= MAC80211_LINKED) { if (mac->opmode == NL80211_IFTYPE_AP || @@ -283,25 +281,25 @@ static void rtl92d_dm_find_minimum_rssi(struct ieee80211_hw *hw) de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - rtlpriv->dm.UNDEC_SM_PWDB)); + "AP Client PWDB = 0x%lx\n", + rtlpriv->dm.UNDEC_SM_PWDB); } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("STA Default Port PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "STA Default Port PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } } else { de_digtable.min_undecorated_pwdb_for_dm = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, - ("AP Ext Port or disconnet PWDB = 0x%x\n", - de_digtable.min_undecorated_pwdb_for_dm)); + "AP Ext Port or disconnet PWDB = 0x%x\n", + de_digtable.min_undecorated_pwdb_for_dm); } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("MinUndecoratedPWDBForDM =%d\n", - de_digtable.min_undecorated_pwdb_for_dm)); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n", + de_digtable.min_undecorated_pwdb_for_dm); } static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) @@ -340,14 +338,14 @@ static void rtl92d_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) } de_digtable.pre_cck_pd_state = de_digtable.cur_cck_pd_state; } - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CurSTAConnectState=%s\n", - (de_digtable.cursta_connectctate == DIG_STA_CONNECT ? - "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("CCKPDStage=%s\n", - (de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? - "Low RSSI " : "High RSSI "))); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("is92d single phy =%x\n", - IS_92D_SINGLEPHY(rtlpriv->rtlhal.version))); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CurSTAConnectState=%s\n", + de_digtable.cursta_connectctate == DIG_STA_CONNECT ? + "DIG_STA_CONNECT " : "DIG_STA_DISCONNECT"); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "CCKPDStage=%s\n", + de_digtable.cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI ? + "Low RSSI " : "High RSSI "); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "is92d single phy =%x\n", + IS_92D_SINGLEPHY(rtlpriv->rtlhal.version)); } @@ -355,12 +353,12 @@ void rtl92d_dm_write_dig(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("cur_igvalue = 0x%x, " - "pre_igvalue = 0x%x, backoff_val = %d\n", + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, + "cur_igvalue = 0x%x, pre_igvalue = 0x%x, backoff_val = %d\n", de_digtable.cur_igvalue, de_digtable.pre_igvalue, - de_digtable.backoff_val)); + de_digtable.backoff_val); if (de_digtable.dig_enable_flag == false) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("DIG is disabled\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "DIG is disabled\n"); de_digtable.pre_igvalue = 0x17; return; } @@ -377,22 +375,21 @@ static void rtl92d_early_mode_enabled(struct rtl_priv *rtlpriv) { if ((rtlpriv->mac80211.link_state >= MAC80211_LINKED) && (rtlpriv->mac80211.vendor == PEER_CISCO)) { - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("IOT_PEER = CISCO\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "IOT_PEER = CISCO\n"); if (de_digtable.last_min_undecorated_pwdb_for_dm >= 50 && de_digtable.min_undecorated_pwdb_for_dm < 50) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x00); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode Off\n")); + "Early Mode Off\n"); } else if (de_digtable.last_min_undecorated_pwdb_for_dm <= 55 && de_digtable.min_undecorated_pwdb_for_dm > 55) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("Early Mode On\n")); + "Early Mode On\n"); } } else if (!(rtl_read_byte(rtlpriv, REG_EARLY_MODE_CONTROL) & 0xf)) { rtl_write_byte(rtlpriv, REG_EARLY_MODE_CONTROL, 0x0f); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("Early Mode On\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "Early Mode On\n"); } } @@ -402,7 +399,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) u8 value_igi = de_digtable.cur_igvalue; struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "==>\n"); if (rtlpriv->rtlhal.earlymode_enable) { rtl92d_early_mode_enabled(rtlpriv); de_digtable.last_min_undecorated_pwdb_for_dm = @@ -421,7 +418,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) /* Not STA mode return tmp */ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION) return; - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("progress\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "progress\n"); /* Decide the current status and if modify initial gain or not */ if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) de_digtable.cursta_connectctate = DIG_STA_CONNECT; @@ -438,16 +435,16 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) else if (falsealm_cnt->cnt_all >= DM_DIG_FA_TH2) value_igi += 2; RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() Before: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() Before: Recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); /* deal with abnorally large false alarm */ if (falsealm_cnt->cnt_all > 10000) { RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG(): Abnornally false alarm case.\n")); + "dm_DIG(): Abnormally false alarm case\n"); de_digtable.large_fa_hit++; if (de_digtable.forbidden_igi < de_digtable.cur_igvalue) { @@ -486,11 +483,11 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) } } RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", - de_digtable.large_fa_hit, de_digtable.forbidden_igi)); + "dm_DIG() After: large_fa_hit=%d, forbidden_igi=%x\n", + de_digtable.large_fa_hit, de_digtable.forbidden_igi); RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, - ("dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", - de_digtable.recover_cnt, de_digtable.rx_gain_range_min)); + "dm_DIG() After: recover_cnt=%d, rx_gain_range_min=%x\n", + de_digtable.recover_cnt, de_digtable.rx_gain_range_min); if (value_igi > DM_DIG_MAX) value_igi = DM_DIG_MAX; @@ -500,7 +497,7 @@ static void rtl92d_dm_dig(struct ieee80211_hw *hw) rtl92d_dm_write_dig(hw); if (rtlpriv->rtlhal.current_bandtype != BAND_ON_5G) rtl92d_dm_cck_packet_detection_thresh(hw); - RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, ("<<==\n")); + RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD, "<<==\n"); } static void rtl92d_dm_init_dynamic_txpower(struct ieee80211_hw *hw) @@ -528,7 +525,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.UNDEC_SM_PWDB == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; return; @@ -538,40 +535,40 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("IBSS Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "IBSS Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.UNDEC_SM_PWDB; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } if (rtlhal->current_bandtype == BAND_ON_5G) { if (undecorated_smoothed_pwdb >= 0x33) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n")); + "5G:TxHighPwrLevel_Level2 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < 0x33) && (undecorated_smoothed_pwdb >= 0x2b)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n")); + "5G:TxHighPwrLevel_Level1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < 0x2b) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_HIPWR, DBG_LOUD, - ("5G:TxHighPwrLevel_Normal\n")); + "5G:TxHighPwrLevel_Normal\n"); } } else { if (undecorated_smoothed_pwdb >= @@ -579,7 +576,7 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL2; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); } else if ((undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) @@ -589,19 +586,19 @@ static void rtl92d_dm_dynamic_txpower(struct ieee80211_hw *hw) rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n")); + "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); } else if (undecorated_smoothed_pwdb < (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("TXHIGHPWRLEVEL_NORMAL\n")); + "TXHIGHPWRLEVEL_NORMAL\n"); } } if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("PHY_SetTxPowerLevel8192S() Channel = %d\n", - rtlphy->current_channel)); + "PHY_SetTxPowerLevel8192S() Channel = %d\n", + rtlphy->current_channel); rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); } rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; @@ -717,7 +714,7 @@ static void rtl92d_dm_rxgain_tracking_thermalmeter(struct ieee80211_hw *hw) u4tmp = (index_mapping[(rtlpriv->efuse.eeprom_thermalmeter - rtlpriv->dm.thermalvalue_rxgain)]) << 12; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("===> Rx Gain %x\n", u4tmp)); + "===> Rx Gain %x\n", u4tmp); for (i = RF90_PATH_A; i < rtlpriv->phy.num_total_rfpath; i++) rtl_set_rfreg(hw, i, 0x3C, BRFREGOFFSETMASK, (rtlpriv->phy.reg_rf3c[i] & (~(0xF000))) | u4tmp); @@ -741,27 +738,22 @@ static void rtl92d_bandtype_2_4G(struct ieee80211_hw *hw, long *temp_cckg, if (!memcmp((void *)&temp_cck, (void *)&cckswing_table_ch14[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, - COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index=0x%x, ch 14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index=0x%x, ch 14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } else { if (!memcmp((void *) &temp_cck, &cckswing_table_ch1ch13[i][2], 4)) { *cck_index_old = (u8) i; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, - DBG_LOUD, - ("Initial reg0x%x = 0x%lx, " - "cck_index = 0x%x, ch14 %d\n", - RCCK0_TXFILTER2, - temp_cck, *cck_index_old, - rtlpriv->dm.cck_inch14)); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, + "Initial reg0x%x = 0x%lx, cck_index = 0x%x, ch14 %d\n", + RCCK0_TXFILTER2, temp_cck, + *cck_index_old, + rtlpriv->dm.cck_inch14); break; } } @@ -884,12 +876,12 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( }; rtlpriv->dm.txpower_trackinginit = true; - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "\n"); thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0xf800); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); rtl92d_phy_ap_calibrate(hw, (thermalvalue - rtlefuse->eeprom_thermalmeter)); if (is2t) @@ -904,10 +896,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[0] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathA ele_d reg0x%x = 0x%lx," - " ofdm_index=0x%x\n", + "Initial pathA ele_d reg0x%x = 0x%lx, ofdm_index=0x%x\n", ROFDM0_XATxIQIMBALANCE, - ele_d, ofdm_index_old[0])); + ele_d, ofdm_index_old[0]); break; } } @@ -920,11 +911,9 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( ofdm_index_old[1] = (u8) i; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Initial pathB ele_d reg " - "0x%x = 0x%lx, ofdm_index " - "= 0x%x\n", + "Initial pathB ele_d reg 0x%x = 0x%lx, ofdm_index = 0x%x\n", ROFDM0_XBTxIQIMBALANCE, ele_d, - ofdm_index_old[1])); + ofdm_index_old[1]); break; } } @@ -952,7 +941,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i]; rtlpriv->dm.cck_index = cck_index_old; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("reload ofdm index for band switch\n")); + "reload ofdm index for band switch\n"); } rtlpriv->dm.thermalvalue_avg [rtlpriv->dm.thermalvalue_avg_index] = thermalvalue; @@ -995,12 +984,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( (thermalvalue - rtlpriv->dm.thermalvalue_rxgain) : (rtlpriv->dm.thermalvalue_rxgain - thermalvalue); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x" - " eeprom_thermalmeter 0x%x delta 0x%x " - "delta_lck 0x%x delta_iqk 0x%x\n", - thermalvalue, rtlpriv->dm.thermalvalue, - rtlefuse->eeprom_thermalmeter, delta, delta_lck, - delta_iqk)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n", + thermalvalue, rtlpriv->dm.thermalvalue, + rtlefuse->eeprom_thermalmeter, delta, delta_lck, + delta_iqk); if ((delta_lck > rtlefuse->delta_lck) && (rtlefuse->delta_lck != 0)) { rtlpriv->dm.thermalvalue_lck = thermalvalue; @@ -1036,17 +1023,15 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x, OFDM_B_index" - " = 0x%x,cck_index=0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.ofdm_index[1], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x, OFDM_B_index = 0x%x,cck_index=0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.ofdm_index[1], + rtlpriv->dm.cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("temp OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - rtlpriv->dm.ofdm_index[0], - rtlpriv->dm.cck_index)); + "temp OFDM_A_index=0x%x,cck_index = 0x%x\n", + rtlpriv->dm.ofdm_index[0], + rtlpriv->dm.cck_index); } for (i = 0; i < rf; i++) { if (ofdm_index[i] > OFDM_TABLE_SIZE_92D - 1) @@ -1070,15 +1055,13 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } if (is2t) { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x, OFDM_B_index " - "= 0x%x, cck_index=0x%x\n", + "new OFDM_A_index=0x%x, OFDM_B_index = 0x%x, cck_index=0x%x\n", ofdm_index[0], ofdm_index[1], - cck_index)); + cck_index); } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("new OFDM_A_index=0x%x,cck_index = " - "0x%x\n", - ofdm_index[0], cck_index)); + "new OFDM_A_index=0x%x,cck_index = 0x%x\n", + ofdm_index[0], cck_index); } ele_d = (ofdmswing_table[(u8) ofdm_index[0]] & 0xFFC00000) >> 22; @@ -1124,12 +1107,10 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking for interface %d path A: X =" - " 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = " - "0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = " - "0x%lx\n", rtlhal->interfaceindex, + "TxPwrTracking for interface %d path A: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xe94 = 0x%lx 0xe9c = 0x%lx\n", + rtlhal->interfaceindex, val_x, val_y, ele_a, ele_c, ele_d, - val_x, val_y)); + val_x, val_y); if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* Adjust CCK according to IQK result */ @@ -1232,20 +1213,16 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( BIT(28), 0x00); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking path B: X = 0x%lx, " - "Y = 0x%lx ele_A = 0x%lx ele_C = 0x" - "%lx ele_D = 0x%lx 0xeb4 = 0x%lx " - "0xebc = 0x%lx\n", - val_x, val_y, ele_a, ele_c, - ele_d, val_x, val_y)); + "TxPwrTracking path B: X = 0x%lx, Y = 0x%lx ele_A = 0x%lx ele_C = 0x%lx ele_D = 0x%lx 0xeb4 = 0x%lx 0xebc = 0x%lx\n", + val_x, val_y, ele_a, ele_c, + ele_d, val_x, val_y); } RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("TxPwrTracking 0xc80 = 0x%x, 0xc94 = " - "0x%x RF 0x24 = 0x%x\n", + "TxPwrTracking 0xc80 = 0x%x, 0xc94 = 0x%x RF 0x24 = 0x%x\n", rtl_get_bbreg(hw, 0xc80, BMASKDWORD), rtl_get_bbreg(hw, 0xc94, BMASKDWORD), rtl_get_rfreg(hw, RF90_PATH_A, 0x24, - BRFREGOFFSETMASK))); + BRFREGOFFSETMASK)); } if ((delta_iqk > rtlefuse->delta_iqk) && (rtlefuse->delta_iqk != 0)) { @@ -1262,7 +1239,7 @@ static void rtl92d_dm_txpower_tracking_callback_thermalmeter( rtlpriv->dm.thermalvalue = thermalvalue; } - RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===\n"); } static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) @@ -1273,8 +1250,8 @@ static void rtl92d_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) rtlpriv->dm.txpower_trackinginit = false; rtlpriv->dm.txpower_track_control = true; RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("pMgntInfo->txpower_tracking = %d\n", - rtlpriv->dm.txpower_tracking)); + "pMgntInfo->txpower_tracking = %d\n", + rtlpriv->dm.txpower_tracking); } void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) @@ -1289,12 +1266,12 @@ void rtl92d_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw *hw) rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16), 0x03); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Trigger 92S Thermal Meter!!\n")); + "Trigger 92S Thermal Meter!!\n"); tm_trigger = 1; return; } else { RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Schedule TxPowerTracking direct call!!\n")); + "Schedule TxPowerTracking direct call!!\n"); rtl92d_dm_txpower_tracking_callback_thermalmeter(hw); tm_trigger = 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index db6972ffe50..b84f10d60c0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -124,14 +124,14 @@ static void _rtl92d_write_fw(struct ieee80211_hw *hw, u32 pagenums, remainSize; u32 page, offset; - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, ("FW size is %d bytes,\n", size)); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "FW size is %d bytes,\n", size); if (rtlhal->hw_type == HARDWARE_TYPE_RTL8192DE) _rtl92d_fill_dummy(bufferPtr, &size); pagenums = size / FW_8192D_PAGE_SIZE; remainSize = size % FW_8192D_PAGE_SIZE; if (pagenums > 8) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Page numbers should not greater then 8\n")); + "Page numbers should not greater then 8\n"); } for (page = 0; page < pagenums; page++) { offset = page * FW_8192D_PAGE_SIZE; @@ -158,12 +158,12 @@ static int _rtl92d_fw_free_to_go(struct ieee80211_hw *hw) (!(value32 & FWDL_ChkSum_rpt))); if (counter >= FW_8192D_POLLING_TIMEOUT_COUNT) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("chksum report faill ! REG_MCUFWDL:0x%08x .\n", - value32)); + "chksum report faill ! REG_MCUFWDL:0x%08x\n", + value32); return -EIO; } RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("Checksum report OK ! REG_MCUFWDL:0x%08x .\n", value32)); + "Checksum report OK ! REG_MCUFWDL:0x%08x\n", value32); value32 = rtl_read_dword(rtlpriv, REG_MCUFWDL); value32 |= MCUFWDL_RDY; rtl_write_dword(rtlpriv, REG_MCUFWDL, value32); @@ -188,7 +188,7 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) } RT_ASSERT((delay > 0), ("8051 reset failed!\n")); RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("=====> 8051 reset success (%d) .\n", delay)); + "=====> 8051 reset success (%d)\n", delay); } static int _rtl92d_fw_init(struct ieee80211_hw *hw) @@ -197,7 +197,7 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 counter; - RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, ("FW already have download\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "FW already have download\n"); /* polling for FW ready */ counter = 0; do { @@ -205,10 +205,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC0_READY) & MAC0_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC0_READY))); + FW_MAC0_READY)); return 0; } udelay(5); @@ -216,10 +215,9 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtl_read_byte(rtlpriv, FW_MAC1_READY) & MAC1_READY) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready success!! " - "REG_MCUFWDL: 0x%x .\n", + "Polling FW ready success!! REG_MCUFWDL: 0x%x\n", rtl_read_byte(rtlpriv, - FW_MAC1_READY))); + FW_MAC1_READY)); return 0; } udelay(5); @@ -228,18 +226,16 @@ static int _rtl92d_fw_init(struct ieee80211_hw *hw) if (rtlhal->interfaceindex == 0) { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC0 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC0_READY))); + "Polling FW ready fail!! MAC0 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC0_READY)); } else { RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! MAC1 FW init not ready: " - "0x%x .\n", - rtl_read_byte(rtlpriv, FW_MAC1_READY))); + "Polling FW ready fail!! MAC1 FW init not ready: 0x%x\n", + rtl_read_byte(rtlpriv, FW_MAC1_READY)); } RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Polling FW ready fail!! REG_MCUFWDL:0x%08ul .\n", - rtl_read_dword(rtlpriv, REG_MCUFWDL))); + "Polling FW ready fail!! REG_MCUFWDL:0x%08ul\n", + rtl_read_dword(rtlpriv, REG_MCUFWDL)); return -1; } @@ -264,13 +260,13 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) pfwdata = (u8 *) rtlhal->pfirmware; rtlhal->fw_version = (u16) GET_FIRMWARE_HDR_VERSION(pfwheader); rtlhal->fw_subversion = (u16) GET_FIRMWARE_HDR_SUB_VER(pfwheader); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, (" FirmwareVersion(%d)," - "FirmwareSubVersion(%d), Signature(%#x)\n", - rtlhal->fw_version, rtlhal->fw_subversion, - GET_FIRMWARE_HDR_SIGNATURE(pfwheader))); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "FirmwareVersion(%d), FirmwareSubVersion(%d), Signature(%#x)\n", + rtlhal->fw_version, rtlhal->fw_subversion, + GET_FIRMWARE_HDR_SIGNATURE(pfwheader)); if (IS_FW_HEADER_EXIST(pfwheader)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Shift 32 bytes for FW header!!\n")); + "Shift 32 bytes for FW header!!\n"); pfwdata = pfwdata + 32; fwsize = fwsize - 32; } @@ -302,8 +298,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) break; else RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, - ("Wait for another mac " - "download fw\n")); + "Wait for another mac download fw\n"); } spin_lock_irqsave(&globalmutex_for_fwdownload, flags); value = rtl_read_byte(rtlpriv, 0x1f); @@ -337,11 +332,10 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_fwdownload, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("fw is not ready to run!\n")); + "fw is not ready to run!\n"); goto exit; } else { - RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, - ("fw is ready to run!\n")); + RT_TRACE(rtlpriv, COMP_FW, DBG_TRACE, "fw is ready to run!\n"); } exit: err = _rtl92d_fw_init(hw); @@ -381,24 +375,24 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (ppsc->rfpwr_state == ERFOFF || ppsc->inactive_pwrstate == ERFOFF) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Return as RF is off!!!\n")); + "Return as RF is off!!!\n"); return; } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("come in\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "come in\n"); while (true) { spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); if (rtlhal->h2c_setinprogress) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("H2C set in progress! Wait to set.." - "element_id(%d).\n", element_id)); + "H2C set in progress! Wait to set..element_id(%d)\n", + element_id); while (rtlhal->h2c_setinprogress) { spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); h2c_waitcounter++; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wait 100 us (%d times)...\n", - h2c_waitcounter)); + "Wait 100 us (%d times)...\n", + h2c_waitcounter); udelay(100); if (h2c_waitcounter > 1000) @@ -418,8 +412,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_writeh2c_limmit--; if (wait_writeh2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Write H2C fail because no trigger " - "for FW INT!\n")); + "Write H2C fail because no trigger for FW INT!\n"); break; } boxnum = rtlhal->last_hmeboxnum; @@ -442,7 +435,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); @@ -450,29 +443,29 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, wait_h2c_limmit--; if (wait_h2c_limmit == 0) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating too long for FW read " - "clear HMEBox(%d)!\n", boxnum)); + "Waiting too long for FW read clear HMEBox(%d)!\n", + boxnum); break; } udelay(10); isfw_read = _rtl92d_check_fw_read_last_h2c(hw, boxnum); u1b_tmp = rtl_read_byte(rtlpriv, 0x1BF); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Wating for FW read clear HMEBox(%d)!!! " - "0x1BF = %2x\n", boxnum, u1b_tmp)); + "Waiting for FW read clear HMEBox(%d)!!! 0x1BF = %2x\n", + boxnum, u1b_tmp); } if (!isfw_read) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write H2C register BOX[%d] fail!!!!! " - "Fw do not read.\n", boxnum)); + "Write H2C register BOX[%d] fail!!!!! Fw do not read.\n", + boxnum); break; } memset(boxcontent, 0, sizeof(boxcontent)); memset(boxextcontent, 0, sizeof(boxextcontent)); boxcontent[0] = element_id; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Write element_id box_reg(%4x) = %2x\n", - box_reg, element_id)); + "Write element_id box_reg(%4x) = %2x\n", + box_reg, element_id); switch (cmd_len) { case 1: boxcontent[0] &= ~(BIT(7)); @@ -519,7 +512,7 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } bwrite_sucess = true; @@ -527,13 +520,13 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, if (rtlhal->last_hmeboxnum == 4) rtlhal->last_hmeboxnum = 0; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("pHalData->last_hmeboxnum = %d\n", - rtlhal->last_hmeboxnum)); + "pHalData->last_hmeboxnum = %d\n", + rtlhal->last_hmeboxnum); } spin_lock_irqsave(&rtlpriv->locks.h2c_lock, flag); rtlhal->h2c_setinprogress = false; spin_unlock_irqrestore(&rtlpriv->locks.h2c_lock, flag); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("go out\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "go out\n"); } void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, @@ -559,7 +552,7 @@ void rtl92d_set_fw_pwrmode_cmd(struct ieee80211_hw *hw, u8 mode) u8 u1_h2c_set_pwrmode[3] = { 0 }; struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("FW LPS mode = %d\n", mode)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "FW LPS mode = %d\n", mode); SET_H2CCMD_PWRMODE_PARM_MODE(u1_h2c_set_pwrmode, mode); SET_H2CCMD_PWRMODE_PARM_SMART_PS(u1_h2c_set_pwrmode, 1); SET_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1_h2c_set_pwrmode, @@ -771,14 +764,14 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) dlok = true; if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Set RSVD page location to Fw.\n")); + "Set RSVD page location to Fw\n"); RT_PRINT_DATA(rtlpriv, COMP_CMD, DBG_DMESG, "H2C_RSVDPAGE", u1RsvdPageLoc, 3); rtl92d_fill_h2c_cmd(hw, H2C_RSVDPAGE, sizeof(u1RsvdPageLoc), u1RsvdPageLoc); } else RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set RSVD page location to Fw FAIL!!!!!!.\n")); + "Set RSVD page location to Fw FAIL!!!!!!\n"); } void rtl92d_set_fw_joinbss_report_cmd(struct ieee80211_hw *hw, u8 mstatus) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 5c8a639582a..5eecf403a5c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -166,7 +166,7 @@ void rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -230,7 +230,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, REG_SLOT, val[0]); for (e_aci = 0; e_aci < AC_MAX; e_aci++) rtlpriv->cfg->ops->set_hw_reg(hw, @@ -261,8 +261,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) min_spacing_to_set); *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); } @@ -275,8 +275,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, mac->min_space_cfg); break; @@ -310,8 +310,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoSet); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -344,8 +344,8 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -361,13 +361,13 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("SetHwReg8190pci(): [HW_VAR_ACM_CTRL] " - "Write 0x%X\n", acm_ctrl)); + "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", + acm_ctrl); rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); break; } @@ -502,7 +502,7 @@ void rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } @@ -522,8 +522,8 @@ static bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) break; if (count > POLLING_LLT_THRESHOLD) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to polling write LLT done at " - "address %d!\n", address)); + "Failed to polling write LLT done at address %d!\n", + address); status = false; break; } @@ -879,12 +879,12 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) u8 sec_reg_value; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", - rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", + rtlpriv->sec.pairwise_enc_algorithm, + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; @@ -895,7 +895,7 @@ void rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The SECR-value %x\n", sec_reg_value)); + "The SECR-value %x\n", sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); } @@ -921,7 +921,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) /* rtlpriv->intf_ops->disable_aspm(hw); */ rtstatus = _rtl92de_init_mac(hw); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Init MAC failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Init MAC failed\n"); err = 1; spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); return err; @@ -930,8 +930,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. Init HW " - "without FW..\n")); + "Failed to download FW. Init HW without FW..\n"); rtlhal->fw_ready = false; return 1; } else { @@ -946,7 +945,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (rtlhal->earlymode_enable) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EarlyMode Enabled!!!\n")); + "EarlyMode Enabled!!!\n"); tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); tmp_u1b = tmp_u1b | 0x1f; @@ -1064,10 +1063,10 @@ static enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw) value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (!(value32 & 0x000f0000)) { version = VERSION_TEST_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("TEST CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n"); } else { version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Normal CHIP!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n"); } return version; } @@ -1092,8 +1091,8 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, _rtl92de_disable_bcn_sub_func(hw); } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Set HW_VAR_MEDIA_STATUS: No such media " - "status(%x).\n", type)); + "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", + type); } bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); switch (type) { @@ -1102,30 +1101,30 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw, ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= MSR_ADHOC; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= MSR_INFRA; ledaction = LED_CTL_LINK; bcnfunc_enable &= 0xF7; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= MSR_AP; bcnfunc_enable |= 0x08; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1189,7 +1188,7 @@ void rtl92d_linked_set_reg(struct ieee80211_hw *hw) indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); if (!rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done) { RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, - ("Do IQK for channel:%d.\n", channel)); + "Do IQK for channel:%d\n", channel); rtl92d_phy_iq_calibrate(hw); } } @@ -1305,8 +1304,8 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("In PowerOff,reg0x%x=%X\n", REG_SPS0_CTRL, - rtl_read_byte(rtlpriv, REG_SPS0_CTRL))); + "In PowerOff,reg0x%x=%X\n", + REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); /* r. Note: for PCIe interface, PON will not turn */ /* off m-bias and BandGap in PCIe suspend mode. */ @@ -1319,7 +1318,7 @@ static void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) spin_unlock_irqrestore(&globalmutex_power, flags); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<=======\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); } void rtl92de_card_disable(struct ieee80211_hw *hw) @@ -1377,7 +1376,7 @@ void rtl92de_card_disable(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); udelay(50); rtl_write_byte(rtlpriv, REG_CR, 0x0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==> Do power off.......\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); if (rtl92d_phy_check_poweroff(hw)) _rtl92de_poweroff_adapter(hw); return; @@ -1425,7 +1424,7 @@ void rtl92de_set_beacon_interval(struct ieee80211_hw *hw) u16 bcn_interval = mac->beacon_interval; RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, - ("beacon_interval:%d\n", bcn_interval)); + "beacon_interval:%d\n", bcn_interval); /* rtl92de_disable_interrupt(hw); */ rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); /* rtl92de_enable_interrupt(hw); */ @@ -1437,8 +1436,8 @@ void rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; if (rm_msr) @@ -1615,9 +1614,9 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, rtlefuse->internal_pa_5g[1] = !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6); RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Is D cut,Internal PA0 %d Internal PA1 %d\n", + "Is D cut,Internal PA0 %d Internal PA1 %d\n", rtlefuse->internal_pa_5g[0], - rtlefuse->internal_pa_5g[1])); + rtlefuse->internal_pa_5g[1]); } rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; @@ -1667,14 +1666,14 @@ static void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, if (rtlefuse->eeprom_c9 == 0xFF) rtlefuse->eeprom_c9 = 0x00; RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("CrystalCap = 0x%x\n", rtlefuse->crystalcap)); + "CrystalCap = 0x%x\n", rtlefuse->crystalcap); RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("Delta_IQK = 0x%x Delta_LCK = 0x%x\n", rtlefuse->delta_iqk, - rtlefuse->delta_lck)); + "Delta_IQK = 0x%x Delta_LCK = 0x%x\n", + rtlefuse->delta_iqk, rtlefuse->delta_lck); for (rfPath = 0; rfPath < RF6052_MAX_PATH; rfPath++) { for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { @@ -1710,11 +1709,11 @@ static void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, if (macphy_crvalue & BIT(3)) { rtlhal->macphymode = SINGLEMAC_SINGLEPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode SINGLEMAC_SINGLEPHY\n"); } else { rtlhal->macphymode = DUALMAC_DUALPHY; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode DUALMAC_DUALPHY\n")); + "MacPhyMode DUALMAC_DUALPHY\n"); } } @@ -1741,15 +1740,15 @@ static void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) switch (chipvalue) { case 0xAA55: chipver |= CHIP_92D_C_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("C-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n"); break; case 0x9966: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("D-CUT!!!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); break; default: chipver |= CHIP_92D_D_CUT; - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("Unkown CUT!\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unkown CUT!\n"); break; } rtlpriv->rtlhal.version = chipver; @@ -1775,7 +1774,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) HWSET_MAX_SIZE); } else if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", hwinfo, HWSET_MAX_SIZE); @@ -1783,15 +1782,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } if (rtlefuse->autoload_failflag) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); return; } rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMER_ID]; @@ -1802,16 +1801,15 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); /* Read Permanent MAC address */ if (rtlhal->interfaceindex == 0) { @@ -1827,8 +1825,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) } rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, rtlefuse->dev_addr); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); /* Read Channel Plan */ @@ -1849,7 +1846,7 @@ static void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; rtlefuse->txpwr_fromeprom = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid)); + "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); } void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) @@ -1863,19 +1860,19 @@ void rtl92de_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); rtlefuse->autoload_status = tmp_u1b; if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92de_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); } return; } @@ -1958,8 +1955,8 @@ static void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, REG_ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, REG_ARFR0)); } static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2092,8 +2089,8 @@ static void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("ratr_bitmap :%x value0:%x value1:%x\n", - ratr_bitmap, value[0], value[1])); + "ratr_bitmap :%x value0:%x value1:%x\n", + ratr_bitmap, value[0], value[1]); rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); if (macid != 0) sta_entry->ratr_index = ratr_index; @@ -2153,14 +2150,14 @@ bool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio ON, RF ON\n")); + "GPIOChangeRF - HW Radio ON, RF ON\n"); e_rfpowerstate_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; } else if ((ppsc->hwradiooff == false) && (e_rfpowerstate_toset == ERFOFF)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("GPIOChangeRF - HW Radio OFF, RF OFF\n")); + "GPIOChangeRF - HW Radio OFF, RF OFF\n"); e_rfpowerstate_toset = ERFOFF; ppsc->hwradiooff = true; actuallyset = true; @@ -2204,7 +2201,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, u8 idx; u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); rtl_cam_empty_entry(hw, cam_offset + idx); @@ -2230,8 +2227,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, enc_algo = CAM_AES; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("switch case " - "not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2248,9 +2245,8 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, COMP_SEC, - DBG_EMERG, ("Can not " - "find free hw security" - " cam entry\n")); + DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2262,21 +2258,21 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, } if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, "Pairwise Key content", @@ -2284,7 +2280,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, rtlpriv-> sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, CAM_CONFIG_NO_USEDK, @@ -2292,7 +2288,7 @@ void rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, rtlefuse->dev_addr, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index f1552f4df65..f2358f20b9c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -45,8 +45,8 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); switch (pled->ledpin) { case LED_PIN_GPIO0: @@ -71,7 +71,7 @@ void rtl92de_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -83,8 +83,8 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", REG_LEDCFG2, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + REG_LEDCFG2, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, REG_LEDCFG2); @@ -106,7 +106,7 @@ void rtl92de_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -153,7 +153,7 @@ void rtl92de_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d,\n", ledaction); _rtl92ce_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 0883349e1c8..82cc052fc98 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -204,8 +204,8 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) u32 returnvalue, originalvalue, bitshift; u8 dbi_direct; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x)\n", regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); if (rtlhal->during_mac1init_radioa || rtlhal->during_mac0init_radiob) { /* mac1 use phy0 read radio_b. */ /* mac0 use phy1 read radio_b. */ @@ -220,8 +220,9 @@ u32 rtl92d_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) } bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " - "Addr[0x%x]=0x%x\n", bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; } @@ -233,8 +234,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, u8 dbi_direct = 0; u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (rtlhal->during_mac1init_radioa) dbi_direct = BIT(3); else if (rtlhal->during_mac0init_radiob) @@ -255,8 +257,9 @@ void rtl92d_phy_set_bb_reg(struct ieee80211_hw *hw, rtl92de_write_dword_dbi(hw, (u16) regaddr, data, dbi_direct); else rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, @@ -300,8 +303,8 @@ static u32 _rtl92d_phy_rf_serial_read(struct ieee80211_hw *hw, else retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSIREADBACKDATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x] = 0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x] = 0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; } @@ -319,8 +322,8 @@ static void _rtl92d_phy_rf_serial_write(struct ieee80211_hw *hw, /* T65 RF */ data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, BMASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, @@ -330,17 +333,17 @@ u32 rtl92d_phy_query_rf_reg(struct ieee80211_hw *hw, u32 original_value, readback_value, bitshift; unsigned long flags; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "rfpath(%#x), bitmask(%#x)\n", - regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); original_value = _rtl92d_phy_rf_serial_read(hw, rfpath, regaddr); bitshift = _rtl92d_phy_calculate_bit_shift(bitmask); readback_value = (original_value & bitmask) >> bitshift; spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -353,8 +356,8 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, unsigned long flags; RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); if (bitmask == 0) return; spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); @@ -369,9 +372,9 @@ void rtl92d_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, _rtl92d_phy_rf_serial_write(hw, rfpath, regaddr, data); } spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " - "bitmask(%#x), data(%#x), rfpath(%#x)\n", - regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) @@ -381,10 +384,10 @@ bool rtl92d_phy_mac_config(struct ieee80211_hw *hw) u32 arraylength; u32 *ptrarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Read Rtl819XMACPHY_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); arraylength = MAC_2T_ARRAYLENGTH; ptrarray = rtl8192de_mac_2tarray; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Img:Rtl819XMAC_Array\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:Rtl819XMAC_Array\n"); for (i = 0; i < arraylength; i = i + 2) rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { @@ -561,25 +564,25 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, agctab_arraylen = AGCTAB_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_array; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC0, Rtl819XAGCTAB_Array\n")); + " ===> phy:MAC0, Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { agctab_arraylen = AGCTAB_2G_ARRAYLENGTH; agctab_array_table = rtl8192de_agctab_2garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_2GArray\n"); } else { agctab_5garraylen = AGCTAB_5G_ARRAYLENGTH; agctab_5garray_table = rtl8192de_agctab_5garray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n")); + " ===> phy:MAC1, Rtl819XAGCTAB_5GArray\n"); } } phy_reg_arraylen = PHY_REG_2T_ARRAYLENGTH; phy_regarray_table = rtl8192de_phy_reg_2tarray; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> phy:Rtl819XPHY_REG_Array_PG\n")); + " ===> phy:Rtl819XPHY_REG_Array_PG\n"); if (configtype == BASEBAND_CONFIG_PHY_REG) { for (i = 0; i < phy_reg_arraylen; i = i + 2) { if (phy_regarray_table[i] == 0xfe) @@ -598,10 +601,9 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, phy_regarray_table[i + 1]); udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The phy_regarray_table[0] is %x" - " Rtl819XPHY_REGArray[1] is %x\n", - phy_regarray_table[i], - phy_regarray_table[i + 1])); + "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", + phy_regarray_table[i], + phy_regarray_table[i + 1]); } } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { if (rtlhal->interfaceindex == 0) { @@ -613,15 +615,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul " - "Rtl819XPHY_REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Normal Chip, MAC0, load " - "Rtl819XAGCTAB_Array\n")); + "Normal Chip, MAC0, load Rtl819XAGCTAB_Array\n"); } else { if (rtlhal->current_bandtype == BAND_ON_2_4G) { for (i = 0; i < agctab_arraylen; i = i + 2) { @@ -632,14 +631,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_Array_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_Array_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_array_table[i], - agctab_array_table[i + 1])); + agctab_array_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_2GArray\n")); + "Load Rtl819XAGCTAB_2GArray\n"); } else { for (i = 0; i < agctab_5garraylen; i = i + 2) { rtl_set_bbreg(hw, @@ -650,14 +647,12 @@ static bool _rtl92d_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, * setting. */ udelay(1); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("The Rtl819XAGCTAB_5GArray_" - "Table[0] is %ul Rtl819XPHY_" - "REGArray[1] is %ul\n", + "The Rtl819XAGCTAB_5GArray_Table[0] is %ul Rtl819XPHY_REGArray[1] is %ul\n", agctab_5garray_table[i], - agctab_5garray_table[i + 1])); + agctab_5garray_table[i + 1]); } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Load Rtl819XAGCTAB_5GArray\n")); + "Load Rtl819XAGCTAB_5GArray\n"); } } } @@ -675,145 +670,145 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][0])); + [rtlphy->pwrgroup_cnt][0]); } if (regaddr == RTXAGC_A_RATE54_24) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][1])); + [rtlphy->pwrgroup_cnt][1]); } if (regaddr == RTXAGC_A_CCK1_MCS32) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][6])); + [rtlphy->pwrgroup_cnt][6]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][7])); + [rtlphy->pwrgroup_cnt][7]); } if (regaddr == RTXAGC_A_MCS03_MCS00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][2])); + [rtlphy->pwrgroup_cnt][2]); } if (regaddr == RTXAGC_A_MCS07_MCS04) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][3])); + [rtlphy->pwrgroup_cnt][3]); } if (regaddr == RTXAGC_A_MCS11_MCS08) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][4])); + [rtlphy->pwrgroup_cnt][4]); } if (regaddr == RTXAGC_A_MCS15_MCS12) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][5])); + [rtlphy->pwrgroup_cnt][5]); } if (regaddr == RTXAGC_B_RATE18_06) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][8])); + [rtlphy->pwrgroup_cnt][8]); } if (regaddr == RTXAGC_B_RATE54_24) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][9])); + [rtlphy->pwrgroup_cnt][9]); } if (regaddr == RTXAGC_B_CCK1_55_MCS32) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][14])); + [rtlphy->pwrgroup_cnt][14]); } if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][15])); + [rtlphy->pwrgroup_cnt][15]); } if (regaddr == RTXAGC_B_MCS03_MCS00) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][10])); + [rtlphy->pwrgroup_cnt][10]); } if (regaddr == RTXAGC_B_MCS07_MCS04) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", + "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%ulx\n", rtlphy->pwrgroup_cnt, rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][11])); + [rtlphy->pwrgroup_cnt][11]); } if (regaddr == RTXAGC_B_MCS11_MCS08) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][12])); + "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][12]); } if (regaddr == RTXAGC_B_MCS15_MCS12) { rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = data; RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", - rtlphy->pwrgroup_cnt, - rtlphy->mcs_txpwrlevel_origoffset - [rtlphy->pwrgroup_cnt][13])); + "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%ulx\n", + rtlphy->pwrgroup_cnt, + rtlphy->mcs_txpwrlevel_origoffset + [rtlphy->pwrgroup_cnt][13]); rtlphy->pwrgroup_cnt++; } } @@ -849,7 +844,7 @@ static bool _rtl92d_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, } } else { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("configtype != BaseBand_Config_PHY_REG\n")); + "configtype != BaseBand_Config_PHY_REG\n"); } return true; } @@ -861,17 +856,17 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); return false; } /* if (rtlphy->rf_type == RF_1T2R) { * _rtl92c_phy_bb_config_1t(hw); - * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); + * RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); *} */ if (rtlefuse->autoload_failflag == false) { @@ -880,13 +875,13 @@ static bool _rtl92d_phy_bb_config(struct ieee80211_hw *hw) BASEBAND_CONFIG_PHY_REG); } if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); return false; } rtstatus = _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, @@ -951,19 +946,17 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, radiob_array_table = rtl8192de_radiob_2t_int_paarray; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_A:Rtl819XRadioA_1TArray\n")); + "PHY_ConfigRFWithHeaderFile() Radio_A:Rtl819XRadioA_1TArray\n"); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("PHY_ConfigRFWithHeaderFile() " - "Radio_B:Rtl819XRadioB_1TArray\n")); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Radio No %x\n", rfpath)); + "PHY_ConfigRFWithHeaderFile() Radio_B:Rtl819XRadioB_1TArray\n"); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); /* this only happens when DMDP, mac0 start on 2.4G, * mac1 start on 5G, mac 0 has to set phy0&phy1 * pathA or mac1 has to set phy0&phy1 pathA */ if ((content == radiob_txt) && (rfpath == RF90_PATH_A)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - (" ===> althougth Path A, we load radiob.txt\n")); + " ===> althougth Path A, we load radiob.txt\n"); radioa_arraylen = radiob_arraylen; radioa_array_table = radiob_array_table; } @@ -1022,11 +1015,11 @@ bool rtl92d_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, break; case RF90_PATH_C: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; case RF90_PATH_D: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } return true; @@ -1046,19 +1039,18 @@ void rtl92d_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) rtlphy->default_initialgain[3] = (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, BMASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default initial gain (c50=0x%x, " - "c58=0x%x, c60=0x%x, c68=0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, BMASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, BMASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } static void _rtl92d_get_txpower_index(struct ieee80211_hw *hw, u8 channel, @@ -1172,7 +1164,7 @@ void rtl92d_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown Scan Backup operation.\n")); + "Unknown Scan Backup operation\n"); break; } } @@ -1193,14 +1185,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, return; if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("FALSE driver sleep or unload\n")); + "FALSE driver sleep or unload\n"); return; } rtlphy->set_bwmode_inprogress = true; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); switch (rtlphy->current_chan_bw) { @@ -1218,7 +1209,7 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } switch (rtlphy->current_chan_bw) { @@ -1250,13 +1241,13 @@ void rtl92d_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92d_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static void _rtl92d_phy_stop_trx_before_changeband(struct ieee80211_hw *hw) @@ -1273,7 +1264,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 value8; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); rtlhal->bandset = band; rtlhal->current_bandtype = band; if (IS_92D_SINGLEPHY(rtlhal->version)) @@ -1283,13 +1274,13 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) /* reconfig BB/RF according to wireless mode */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* BB & RF Config */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>2.4G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); } else { /* 5G band */ - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "====>5G\n"); if (rtlhal->interfaceindex == 1) _rtl92d_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); @@ -1317,7 +1308,7 @@ static void rtl92d_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) 0 ? REG_MAC0 : REG_MAC1), value8); } mdelay(1); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==Switch Band OK.\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==Switch Band OK\n"); } static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, @@ -1329,9 +1320,9 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, u8 group, i; unsigned long flag = 0; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>path %d\n", rfpath)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>path %d\n", rfpath); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); /* fc area 0xd2c */ @@ -1353,14 +1344,13 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, } else { /* G band. */ RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters for G band. IMR already " - "setting %d\n", - rtlpriv->rtlhal.load_imrandiqk_setting_for2g)); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + "Load RF IMR parameters for G band. IMR already setting %d\n", + rtlpriv->rtlhal.load_imrandiqk_setting_for2g); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); if (!rtlpriv->rtlhal.load_imrandiqk_setting_for2g) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Load RF IMR parameters " - "for G band. %d\n", rfpath)); + "Load RF IMR parameters for G band. %d\n", + rfpath); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(25) | BIT(24), 0); rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, @@ -1378,7 +1368,7 @@ static void _rtl92d_phy_reload_imr_setting(struct ieee80211_hw *hw, rtl92d_release_cckandrw_pagea_ctl(hw, &flag); } } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, @@ -1388,7 +1378,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /*----Store original RFENV control type----*/ switch (rfpath) { case RF90_PATH_A: @@ -1414,7 +1404,7 @@ static void _rtl92d_phy_enable_rf_env(struct ieee80211_hw *hw, /*Set 0 to 12 bits for 8255 */ rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0); udelay(1); - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, @@ -1424,7 +1414,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, struct rtl_phy *rtlphy = &(rtlpriv->phy); struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("=====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "=====>\n"); /*----Restore RFENV control type----*/ ; switch (rfpath) { case RF90_PATH_A: @@ -1437,7 +1427,7 @@ static void _rtl92d_phy_restore_rf_env(struct ieee80211_hw *hw, u8 rfpath, *pu4_regval); break; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<=====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<=====\n"); } static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) @@ -1451,10 +1441,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) bool need_pwr_down = false, internal_pa = false; u32 u4regvalue, mask = 0x1C000, value = 0, u4tmp, u4tmp2; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>\n"); /* config path A for 5G */ if (rtlhal->current_bandtype == BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>5G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); u4tmp = curveindex_5g[channel - 1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " "0x28 = 0x%x !!\n", u4tmp)); @@ -1503,12 +1493,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_pram_c_5g[index][i]); } RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x " - "path %d index %d readback 0x%x\n", - rf_reg_for_c_cut_5g[i], - rf_reg_pram_c_5g[index][i], path, - index, rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_5g[i], BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_5g[i], + rf_reg_pram_c_5g[index][i], + path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_5g[i], + BRFREGOFFSETMASK)); } if (need_pwr_down) _rtl92d_phy_restore_rf_env(hw, path, &u4regvalue); @@ -1541,11 +1532,10 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) BRFREGOFFSETMASK, rf_pram_c_5g_int_pa[index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("offset 0x%x value 0x%x " - "path %d index %d\n", + "offset 0x%x value 0x%x path %d index %d\n", rf_for_c_cut_5g_internal_pa[i], rf_pram_c_5g_int_pa[index][i], - rfpath, index)); + rfpath, index); } } else { rtl_set_rfreg(hw, (enum radio_path)rfpath, 0x0B, @@ -1553,7 +1543,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) } } } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("====>2.4G\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); u4tmp = curveindex_2g[channel - 1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " "0x28 = 0x%x !!\n", u4tmp)); @@ -1590,14 +1580,13 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) rf_reg_param_for_c_cut_2g [index][i]); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("offset 0x%x value 0x%x mak 0x%x path %d " - "index %d readback 0x%x\n", - rf_reg_for_c_cut_2g[i], - rf_reg_param_for_c_cut_2g[index][i], - rf_reg_mask_for_c_cut_2g[i], path, index, - rtl_get_rfreg(hw, (enum radio_path)path, - rf_reg_for_c_cut_2g[i], - BRFREGOFFSETMASK))); + "offset 0x%x value 0x%x mak 0x%x path %d index %d readback 0x%x\n", + rf_reg_for_c_cut_2g[i], + rf_reg_param_for_c_cut_2g[index][i], + rf_reg_mask_for_c_cut_2g[i], path, index, + rtl_get_rfreg(hw, (enum radio_path)path, + rf_reg_for_c_cut_2g[i], + BRFREGOFFSETMASK)); } RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", @@ -1611,7 +1600,7 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) if (rtlhal->during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } u8 rtl92d_get_rightchnlplace_for_iqk(u8 chnl) @@ -2618,7 +2607,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) true; RT_TRACE(rtlpriv, COMP_SCAN | COMP_MLME, DBG_LOUD, - ("\nIQK OK indexforchannel %d.\n", indexforchannel)); + "IQK OK indexforchannel %d\n", indexforchannel); } } @@ -2629,17 +2618,17 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); u8 indexforchannel; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("channel %d\n", channel)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "channel %d\n", channel); /*------Do IQK for normal chip and test chip 5G band------- */ indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("indexforchannel %d done %d\n", indexforchannel, - rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "indexforchannel %d done %d\n", + indexforchannel, + rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done); if (0 && !rtlphy->iqk_matrix_regsetting[indexforchannel].iqk_done && rtlphy->need_iqk) { /* Re Do IQK. */ RT_TRACE(rtlpriv, COMP_SCAN | COMP_INIT, DBG_LOUD, - ("Do IQK Matrix reg for channel:%d....\n", channel)); + "Do IQK Matrix reg for channel:%d....\n", channel); rtl92d_phy_iq_calibrate(hw); } else { /* Just load the value. */ @@ -2647,8 +2636,8 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) if (((!rtlhal->load_imrandiqk_setting_for2g) && indexforchannel == 0) || indexforchannel > 0) { RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, - ("Just Read IQK Matrix reg for channel:%d" - "....\n", channel)); + "Just Read IQK Matrix reg for channel:%d....\n", + channel); if ((rtlphy->iqk_matrix_regsetting[indexforchannel]. value[0] != NULL) /*&&(regea4 != 0) */) @@ -2672,7 +2661,7 @@ void rtl92d_phy_reload_iqk_setting(struct ieee80211_hw *hw, u8 channel) } } rtlphy->need_iqk = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static u32 _rtl92d_phy_get_abs(u32 val1, u32 val2) @@ -2743,7 +2732,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, u32 u4tmp = 0, u4regvalue = 0; bool bneed_powerdown_radio = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("path %d\n", erfpath)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", rtlpriv->rtlhal.current_bandtype)); RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); @@ -2788,7 +2777,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, if (rtlpriv->rtlhal.during_mac0init_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); } - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "<====\n"); } static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) @@ -2962,10 +2951,10 @@ void rtl92d_phy_reset_iqk_result(struct ieee80211_hw *hw) u8 i; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("settings regs %d default regs %d\n", - (int)(sizeof(rtlphy->iqk_matrix_regsetting) / - sizeof(struct iqk_matrix_regs)), - IQK_MATRIX_REG_NUM)); + "settings regs %d default regs %d\n", + (int)(sizeof(rtlphy->iqk_matrix_regsetting) / + sizeof(struct iqk_matrix_regs)), + IQK_MATRIX_REG_NUM); /* 0xe94, 0xe9c, 0xea4, 0xeac, 0xeb4, 0xebc, 0xec4, 0xecc */ for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { rtlphy->iqk_matrix_regsetting[i].value[0][0] = 0x100; @@ -3084,7 +3073,7 @@ static bool _rtl92d_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } break; @@ -3111,7 +3100,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - ("sw_chnl_inprogress false driver sleep or unload\n")); + "sw_chnl_inprogress false driver sleep or unload\n"); return 0; } while (rtlphy->lck_inprogress && timecount < timeout) { @@ -3154,7 +3143,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", rtlphy->current_channel)); + "switch to channel%d\n", rtlphy->current_channel); do { if (!rtlphy->sw_chnl_inprogress) @@ -3171,7 +3160,7 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) } break; } while (true); - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); rtlphy->sw_chnl_inprogress = false; return 1; } @@ -3182,8 +3171,8 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress)); + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); switch (rtlphy->current_io_type) { case IO_CMD_RESUME_DM_BY_SCAN: de_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; @@ -3197,12 +3186,12 @@ static void rtl92d_phy_set_io(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("<---(%#x)\n", rtlphy->current_io_type)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", + rtlphy->current_io_type); } bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) @@ -3212,23 +3201,23 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) bool postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", - iotype, rtlphy->set_io_inprogress)); + "-->IO Cmd(%#x), set_io_inprogress(%d)\n", + iotype, rtlphy->set_io_inprogress); do { switch (iotype) { case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Resume DM after scan.\n")); + "[IO CMD] Resume DM after scan\n"); postprocessing = true; break; case IO_CMD_PAUSE_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - ("[IO CMD] Pause DM before scan.\n")); + "[IO CMD] Pause DM before scan\n"); postprocessing = true; break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } while (false); @@ -3239,7 +3228,7 @@ bool rtl92d_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return false; } rtl92d_phy_set_io(hw); - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); return true; } @@ -3297,7 +3286,7 @@ static void _rtl92d_phy_set_rfsleep(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Fail !!! Switch RF timeout.\n")); + "Fail !!! Switch RF timeout\n"); return; } /* e. For PCIE: SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB TRX function */ @@ -3332,7 +3321,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -3341,11 +3330,10 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms state_" - "inap:%x\n", + "awake, sleeped:%d ms state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + ppsc->last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; _rtl92d_phy_set_rfon(hw); } @@ -3360,7 +3348,7 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF: if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -3385,41 +3373,40 @@ bool rtl92d_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else if (rtlpci->pdev->current_state != PCI_D0) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] !=0 but lower power state!\n", - (i + 1), queue_id)); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", + i + 1, queue_id); break; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: %d times TcbBusyQueu" - "e[%d] =%d " - "before doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times TcbBusyQueue[%d] " - "= %d !\n", - MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, queue_id, + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set rfsleep awaked:%d ms\n", - jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies))); - RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), rtlpriv->psc.state_inap)); + "Set rfsleep awaked:%d ms\n", + jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92d_phy_set_rfsleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -3437,17 +3424,17 @@ void rtl92d_phy_config_macphymode(struct ieee80211_hw *hw) switch (rtlhal->macphymode) { case DUALMAC_DUALPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_DUALPHY\n")); + "MacPhyMode: DUALMAC_DUALPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF3); break; case SINGLEMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: SINGLEMAC_SINGLEPHY\n")); + "MacPhyMode: SINGLEMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF4); break; case DUALMAC_SINGLEPHY: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MacPhyMode: DUALMAC_SINGLEPHY\n")); + "MacPhyMode: DUALMAC_SINGLEPHY\n"); rtl_write_byte(rtlpriv, offset, 0xF1); break; } @@ -3615,7 +3602,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); u8 rfpath, i; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("==>\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "==>\n"); /* r_select_5G for path_A/B 0 for 2.4G, 1 for 5G */ if (rtlhal->current_bandtype == BAND_ON_2_4G) { /* r_select_5G for path_A/B,0x878 */ @@ -3764,7 +3751,7 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) } else { rtl92d_phy_enable_anotherphy(hw, false); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("MAC1 use DBI to update 0x888")); + "MAC1 use DBI to update 0x888\n"); /* 0x888 */ rtl92de_write_dword_dbi(hw, RFPGA0_ADDALLOCKEN, rtl92de_read_dword_dbi(hw, @@ -3789,9 +3776,9 @@ void rtl92d_update_bbrf_configuration(struct ieee80211_hw *hw) BRFREGOFFSETMASK); } for (i = 0; i < 2; i++) - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[i])); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("<==\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[i]); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<==\n"); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index db27cebaac2..3bf21c2cf08 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -50,8 +50,8 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) BIT(11), 0x01); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("20M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "20M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; @@ -62,13 +62,13 @@ void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11), 0x00); RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, - ("40M RF 0x18 = 0x%x\n", - rtlphy->rfreg_chnlval[rfpath])); + "40M RF 0x18 = 0x%x\n", + rtlphy->rfreg_chnlval[rfpath]); } break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } @@ -423,11 +423,11 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n"); /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n"); /* Enable BB and RF power */ rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL, rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) | @@ -437,7 +437,7 @@ bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0) * and radio_b.txt has been load. */ bresult = false; } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n"); return bresult; } @@ -453,17 +453,17 @@ void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0) rtlhal->during_mac0init_radiob = false; rtlhal->during_mac1init_radioa = false; - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n"); /* check MAC0 enable or not again now, if * enabled, not power down radio A. */ u1btmp = rtl_read_byte(rtlpriv, mac_reg); if (!(u1btmp & mac_on_bit)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n"); /* power down RF radio A according to YuNan's advice. */ rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER, 0x00000000, direct); } - RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n")); + RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n"); } bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) @@ -606,7 +606,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Radio[%d] Fail!!", rfpath)); + "Radio[%d] Fail!!", rfpath); goto phy_rf_cfg_fail; } @@ -620,7 +620,7 @@ bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw) rtl92d_phy_powerdown_anotherphy(hw, false); else if (need_pwrdown_radiob) rtl92d_phy_powerdown_anotherphy(hw, true); - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n"); return rtstatus; phy_rf_cfg_fail: diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 7911c9c8708..db7579684b1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -174,7 +174,7 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -188,12 +188,12 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > 0x8000) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index e84b8d5e4b1..f6ec0a12884 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -602,8 +602,8 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, EM_HDR_LEN); if (ptcb_desc->empkt_num) { RT_TRACE(rtlpriv, COMP_SEND, DBG_LOUD, - ("Insert 8 byte.pTcb->EMPktNum:%d\n", - ptcb_desc->empkt_num)); + "Insert 8 byte.pTcb->EMPktNum:%d\n", + ptcb_desc->empkt_num); _rtl92de_insert_emcontent(ptcb_desc, (u8 *)(skb->data)); } @@ -700,7 +700,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, if (ieee80211_is_data_qos(fc)) { if (mac->rdg_en) { RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, - ("Enable RDG function.\n")); + "Enable RDG function\n"); SET_TX_DESC_RDG_ENABLE(pdesc, 1); SET_TX_DESC_HTC(pdesc, 1); } @@ -726,7 +726,7 @@ void rtl92de_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_PKT_ID(pdesc, 8); } SET_TX_DESC_MORE_FRAG(pdesc, (lastseg ? 0 : 1)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92de_tx_fill_cmddesc(struct ieee80211_hw *hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4203a8531ca..4a5e3a952a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -170,9 +170,9 @@ static void _rtl92s_dm_txpowertracking_callback_thermalmeter( thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f); RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, - ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x " - "eeprom_thermalmeter 0x%x\n", thermalvalue, - rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter)); + "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n", + thermalvalue, + rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter); if (thermalvalue) { rtlpriv->dm.thermalvalue = thermalvalue; @@ -282,11 +282,11 @@ static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw) } if (ra->pre_ratr_state != ra->ratr_state) { - RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, ("RSSI = %ld " - "RSSI_LEVEL = %d PreState = %d, CurState = %d\n", - rtlpriv->dm.undecorated_smoothed_pwdb, - ra->ratr_state, - ra->pre_ratr_state, ra->ratr_state)); + RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD, + "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n", + rtlpriv->dm.undecorated_smoothed_pwdb, + ra->ratr_state, + ra->pre_ratr_state, ra->ratr_state); rtlpriv->cfg->ops->update_rate_tbl(hw, sta, ra->ratr_state); @@ -586,7 +586,7 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) if ((mac->link_state < MAC80211_LINKED) && (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) { RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - ("Not connected to any\n")); + "Not connected to any\n"); rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL; @@ -599,22 +599,22 @@ static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw) undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Client PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Client PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } else { undecorated_smoothed_pwdb = rtlpriv->dm.undecorated_smoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("STA Default Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "STA Default Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } } else { undecorated_smoothed_pwdb = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("AP Ext Port PWDB = 0x%lx\n", - undecorated_smoothed_pwdb)); + "AP Ext Port PWDB = 0x%lx\n", + undecorated_smoothed_pwdb); } txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 3fda6b1dcf4..2a9699feee3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -66,7 +66,7 @@ static bool _rtl92s_firmware_enable_cpu(struct ieee80211_hw *hw) cpustatus = rtl_read_byte(rtlpriv, TCR); if (cpustatus & IMEM_RDY) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("IMEM Ready after CPU has refilled.\n")); + "IMEM Ready after CPU has refilled\n"); break; } @@ -120,9 +120,8 @@ static u8 _rtl92s_firmware_header_map_rftype(struct ieee80211_hw *hw) return 0x22; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown RF type(%x)\n", - rtlphy->rf_type)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Unknown RF type(%x)\n", + rtlphy->rf_type); break; } return 0x22; @@ -177,7 +176,7 @@ static bool _rtl92s_firmware_downloadcode(struct ieee80211_hw *hw, if (buffer_len >= MAX_FIRMWARE_CODE_SIZE) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Size over FIRMWARE_CODE_SIZE!\n")); + "Size over FIRMWARE_CODE_SIZE!\n"); return false; } @@ -231,8 +230,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, short pollingcnt = 1000; bool rtstatus = true; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("LoadStaus(%d)\n", - loadfw_status)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "LoadStaus(%d)\n", loadfw_status); firmware->fwstatus = (enum fw_status)loadfw_status; @@ -248,8 +247,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & IMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_IMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_IMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } break; @@ -266,8 +265,8 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & EMEM_CHK_RPT) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("FW_STATUS_LOAD_EMEM" - " FAIL CPU, Status=%x\r\n", cpustatus)); + "FW_STATUS_LOAD_EMEM FAIL CPU, Status=%x\n", + cpustatus); goto status_check_fail; } @@ -275,7 +274,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, rtstatus = _rtl92s_firmware_enable_cpu(hw); if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Enable CPU fail!\n")); + "Enable CPU fail!\n"); goto status_check_fail; } break; @@ -291,14 +290,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, if (!(cpustatus & DMEM_CODE_DONE) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling DMEM code done" - " fail ! cpustatus(%#x)\n", cpustatus)); + "Polling DMEM code done fail ! cpustatus(%#x)\n", + cpustatus); goto status_check_fail; } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("DMEM code download success," - " cpustatus(%#x)\n", cpustatus)); + "DMEM code download success, cpustatus(%#x)\n", + cpustatus); /* Prevent Delay too much and being scheduled out */ /* Polling Load Firmware ready */ @@ -311,14 +310,14 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, } while (pollingcnt--); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Polling Load Firmware ready," - " cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready, cpustatus(%x)\n", + cpustatus); if (((cpustatus & LOAD_FW_READY) != LOAD_FW_READY) || (pollingcnt <= 0)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling Load Firmware" - " ready fail ! cpustatus(%x)\n", cpustatus)); + "Polling Load Firmware ready fail ! cpustatus(%x)\n", + cpustatus); goto status_check_fail; } @@ -332,7 +331,7 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, RCR_APP_ICV | RCR_APP_MIC)); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Current RCR settings(%#x)\n", tmpu4b)); + "Current RCR settings(%#x)\n", tmpu4b); /* Set to normal mode. */ rtl_write_byte(rtlpriv, LBKMD_SEL, LBK_NORMAL); @@ -340,14 +339,15 @@ static bool _rtl92s_firmware_checkready(struct ieee80211_hw *hw, default: RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Unknown status check!\n")); + "Unknown status check!\n"); rtstatus = false; break; } status_check_fail: - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("loadfw_status(%d), " - "rtstatus(%x)\n", loadfw_status, rtstatus)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "loadfw_status(%d), rtstatus(%x)\n", + loadfw_status, rtstatus); return rtstatus; } @@ -378,17 +378,17 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) firmware->firmwareversion = byte(pfwheader->version, 0); firmware->pfwheader->fwpriv.hci_sel = 1;/* pcie */ - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("signature:%x, version:" - "%x, size:%x," - "imemsize:%x, sram size:%x\n", pfwheader->signature, + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "signature:%x, version:%x, size:%x, imemsize:%x, sram size:%x\n", + pfwheader->signature, pfwheader->version, pfwheader->dmem_size, - pfwheader->img_imem_size, pfwheader->img_sram_size)); + pfwheader->img_imem_size, pfwheader->img_sram_size); /* 2. Retrieve IMEM image. */ if ((pfwheader->img_imem_size == 0) || (pfwheader->img_imem_size > sizeof(firmware->fw_imem))) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than IMEM required\n")); + "memory for data image is less than IMEM required\n"); goto fail; } else { puc_mappedfile += fwhdr_size; @@ -401,7 +401,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) /* 3. Retriecve EMEM image. */ if (pfwheader->img_sram_size > sizeof(firmware->fw_emem)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("memory for data image is less than EMEM required\n")); + "memory for data image is less than EMEM required\n"); goto fail; } else { puc_mappedfile += firmware->fw_imem_len; @@ -436,7 +436,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unexpected Download step!!\n")); + "Unexpected Download step!!\n"); goto fail; break; } @@ -446,14 +446,14 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) ul_filelength); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } /* <3> Check whether load FW process is ready */ rtstatus = _rtl92s_firmware_checkready(hw, fwstatus); if (rtstatus != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("fail!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "fail!\n"); goto fail; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index f9ba077bc18..dffcafe01a3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -80,8 +80,8 @@ void rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; } default: { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "switch case not processed\n"); break; } } @@ -140,7 +140,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u8 e_aci; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("HW_VAR_SLOT_TIME %x\n", val[0])); + "HW_VAR_SLOT_TIME %x\n", val[0]); rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); @@ -185,8 +185,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) *val = min_spacing_to_set; RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -201,8 +201,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) mac->min_space_cfg |= (density_to_set << 3); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_SHORTGI_DENSITY: %#x\n", - mac->min_space_cfg)); + "Set HW_VAR_SHORTGI_DENSITY: %#x\n", + mac->min_space_cfg); rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, mac->min_space_cfg); @@ -244,8 +244,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, - ("Set HW_VAR_AMPDU_FACTOR: %#x\n", - factor_toset)); + "Set HW_VAR_AMPDU_FACTOR: %#x\n", + factor_toset); } break; } @@ -282,8 +282,8 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("HW_VAR_ACM_CTRL acm set " - "failed: eACI is %d\n", acm)); + "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", + acm); break; } } else { @@ -299,13 +299,13 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } } RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE, - ("HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl)); + "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); rtl_write_byte(rtlpriv, AcmHwCtrl, acm_ctrl); break; } @@ -404,7 +404,7 @@ void rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) } default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -415,14 +415,14 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) struct rtl_priv *rtlpriv = rtl_priv(hw); u8 sec_reg_value = 0x0; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("PairwiseEncAlgorithm = %d " - "GroupEncAlgorithm = %d\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", rtlpriv->sec.pairwise_enc_algorithm, - rtlpriv->sec.group_enc_algorithm)); + rtlpriv->sec.group_enc_algorithm); if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("not open hw encryption\n")); + "not open hw encryption\n"); return; } @@ -433,8 +433,8 @@ void rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) sec_reg_value |= SCR_RXUSEDK; } - RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, ("The SECR-value %x\n", - sec_reg_value)); + RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", + sec_reg_value); rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); @@ -718,8 +718,8 @@ static void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) if (pollingcnt <= 0) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Polling TXDMA_INIT_VALUE " - "timeout!! Current TCR(%#x)\n", tmpu1b)); + "Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", + tmpu1b); tmpu1b = rtl_read_byte(rtlpriv, CMDR); rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); udelay(2); @@ -870,10 +870,10 @@ static void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) /* Change Program timing */ rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("EFUSE CONFIG OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); } @@ -951,9 +951,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("Failed to download FW. " - "Init HW without FW now.., Please copy FW into" - "/lib/firmware/rtlwifi\n")); + "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); rtlhal->fw_ready = false; } else { rtlhal->fw_ready = true; @@ -968,7 +966,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ if (rtl92s_phy_mac_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("MAC Config failed\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "MAC Config failed\n"); return rtstatus; } @@ -978,7 +976,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ if (rtl92s_phy_bb_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, ("BB Config failed\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "BB Config failed\n"); return rtstatus; } @@ -1014,7 +1012,7 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, RF_CTRL, 0x07); if (rtl92s_phy_rf_config(hw) != true) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("RF Config failed\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); return rtstatus; } @@ -1129,26 +1127,26 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw, case NL80211_IFTYPE_UNSPECIFIED: bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to NO LINK!\n")); + "Set Network type to NO LINK!\n"); break; case NL80211_IFTYPE_ADHOC: bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to Ad Hoc!\n")); + "Set Network type to Ad Hoc!\n"); break; case NL80211_IFTYPE_STATION: bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to STA!\n")); + "Set Network type to STA!\n"); break; case NL80211_IFTYPE_AP: bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - ("Set Network type to AP!\n")); + "Set Network type to AP!\n"); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Network type %d not support!\n", type)); + "Network type %d not supported!\n", type); return 1; break; @@ -1583,8 +1581,8 @@ void rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, - ("add_msr:%x, rm_msr:%x\n", add_msr, rm_msr)); + RT_TRACE(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", + add_msr, rm_msr); if (add_msr) rtlpci->irq_mask[0] |= add_msr; @@ -1627,7 +1625,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (rtlefuse->epromtype == EEPROM_93C46) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("RTL819X Not boot from eeprom, check it !!")); + "RTL819X Not boot from eeprom, check it !!\n"); } else if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { rtl_efuse_shadow_map_update(hw); @@ -1642,10 +1640,10 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) eeprom_id = *((u16 *)&hwinfo[0]); if (eeprom_id != RTL8190_EEPROM_ID) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("EEPROM ID(%#x) is invalid!!\n", eeprom_id)); + "EEPROM ID(%#x) is invalid!!\n", eeprom_id); rtlefuse->autoload_failflag = true; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; } @@ -1663,15 +1661,15 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROMId = 0x%4x\n", eeprom_id)); + "EEPROMId = 0x%4x\n", eeprom_id); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid)); + "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did)); + "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid)); + "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid)); + "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); for (i = 0; i < 6; i += 2) { usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; @@ -1681,8 +1679,7 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 6; i++) rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("%pM\n", rtlefuse->dev_addr)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); /* Get Tx Power Level by Channel */ /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ @@ -1937,14 +1934,14 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) if (!(tempval & BIT(0))) { rtlefuse->b1x1_recvcombine = true; RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("RF_TYPE=1T2R but only 1SS\n")); + "RF_TYPE=1T2R but only 1SS\n"); } } rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; rtlefuse->eeprom_oemid = *(u8 *)&hwinfo[EEPROM_CUSTOMID]; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("EEPROM Customer ID: 0x%2x", - rtlefuse->eeprom_oemid)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x", + rtlefuse->eeprom_oemid); /* set channel paln to world wide 13 */ rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; @@ -1959,19 +1956,19 @@ void rtl92se_read_eeprom_info(struct ieee80211_hw *hw) tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); if (tmp_u1b & BIT(4)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EEPROM\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); rtlefuse->epromtype = EEPROM_93C46; } else { - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("Boot from EFUSE\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); rtlefuse->epromtype = EEPROM_BOOT_EFUSE; } if (tmp_u1b & BIT(5)) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Autoload OK\n")); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); rtlefuse->autoload_failflag = false; _rtl92se_read_adapter_info(hw); } else { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Autoload ERR!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Autoload ERR!!\n"); rtlefuse->autoload_failflag = true; } } @@ -2071,8 +2068,8 @@ static void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, else rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, - ("%x\n", rtl_read_dword(rtlpriv, ARFR0))); + RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", + rtl_read_dword(rtlpriv, ARFR0)); } static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, @@ -2224,8 +2221,8 @@ static void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); - RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, ("mask = %x, bitmap = %x\n", - mask, ratr_bitmap)); + RT_TRACE(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", + mask, ratr_bitmap); rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); @@ -2301,14 +2298,14 @@ bool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio ON, RF ON\n")); + "RFKILL-HW Radio ON, RF ON\n"); rfpwr_toset = ERFON; ppsc->hwradiooff = false; actuallyset = true; } else if ((ppsc->hwradiooff == false) && (rfpwr_toset == ERFOFF)) { - RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("RFKILL-HW Radio OFF, RF OFF\n")); + RT_TRACE(rtlpriv, COMP_RF, + DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); rfpwr_toset = ERFOFF; ppsc->hwradiooff = true; @@ -2372,7 +2369,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, u8 cam_offset = 0; u8 clear_number = 5; - RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, ("clear_all\n")); + RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); for (idx = 0; idx < clear_number; idx++) { rtl_cam_mark_invalid(hw, cam_offset + idx); @@ -2401,7 +2398,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); enc_algo = CAM_TKIP; break; } @@ -2419,9 +2416,8 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, p_macaddr); if (entry_id >= TOTAL_CAM_ENTRY) { RT_TRACE(rtlpriv, - COMP_SEC, DBG_EMERG, - ("Can not find free hw" - " security cam entry\n")); + COMP_SEC, DBG_EMERG, + "Can not find free hw security cam entry\n"); return; } } else { @@ -2435,30 +2431,31 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, if (rtlpriv->sec.key_len[key_index] == 0) { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("delete one entry, entry_id is %d\n", - entry_id)); + "delete one entry, entry_id is %d\n", + entry_id); if (mac->opmode == NL80211_IFTYPE_AP) rtl_cam_del_entry(hw, p_macaddr); rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY length is %d\n", - rtlpriv->sec.key_len[PAIRWISE_KEYIDX])); + "The insert KEY length is %d\n", + rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, - ("The insert KEY is %x %x\n", - rtlpriv->sec.key_buf[0][0], - rtlpriv->sec.key_buf[0][1])); + "The insert KEY is %x %x\n", + rtlpriv->sec.key_buf[0][0], + rtlpriv->sec.key_buf[0][1]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("add one entry\n")); + "add one entry\n"); if (is_pairwise) { RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, - "Pairwise Key content", - rtlpriv->sec.pairwise_key, - rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); + "Pairwise Key content", + rtlpriv->sec.pairwise_key, + rtlpriv->sec. + key_len[PAIRWISE_KEYIDX]); RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set Pairwiase key\n")); + "set Pairwise key\n"); rtl_cam_add_one_entry(hw, macaddr, key_index, entry_id, enc_algo, @@ -2466,7 +2463,7 @@ void rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, rtlpriv->sec.key_buf[key_index]); } else { RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, - ("set group key\n")); + "set group key\n"); if (mac->opmode == NL80211_IFTYPE_ADHOC) { rtl_cam_add_one_entry(hw, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index e3fe7c90ebf..1a6b0caf084 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -52,8 +52,8 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) u8 ledcfg; struct rtl_priv *rtlpriv = rtl_priv(hw); - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -68,7 +68,7 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = true; @@ -80,8 +80,8 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, - ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", + LEDCFG, pled->ledpin); ledcfg = rtl_read_byte(rtlpriv, LEDCFG); @@ -101,7 +101,7 @@ void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } pled->ledon = false; @@ -141,8 +141,7 @@ void rtl92se_led_control(struct ieee80211_hw *hw, enum led_ctl_mode ledaction) ledaction == LED_CTL_POWER_ON)) { return; } - RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, ("ledaction %d,\n", - ledaction)); + RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "ledaction %d\n", ledaction); _rtl92se_sw_led_control(hw, ledaction); } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index f10ac1ad908..ec5520e6847 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -58,16 +58,15 @@ u32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) struct rtl_priv *rtlpriv = rtl_priv(hw); u32 returnvalue = 0, originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)\n", - regaddr, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", + regaddr, bitmask); originalvalue = rtl_read_dword(rtlpriv, regaddr); bitshift = _rtl92s_phy_calculate_bit_shift(bitmask); returnvalue = (originalvalue & bitmask) >> bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - ("BBR MASK=0x%x Addr[0x%x]=0x%x\n", - bitmask, regaddr, originalvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", + bitmask, regaddr, originalvalue); return returnvalue; @@ -79,8 +78,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 originalvalue, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); if (bitmask != MASKDWORD) { originalvalue = rtl_read_dword(rtlpriv, regaddr); @@ -90,8 +90,9 @@ void rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, rtl_write_dword(rtlpriv, regaddr, data); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x)\n", regaddr, bitmask, data)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x)\n", + regaddr, bitmask, data); } @@ -149,8 +150,8 @@ static u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, BLSSI_READBACK_DATA); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rflssi_readback, retvalue)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rflssi_readback, retvalue); return retvalue; @@ -172,8 +173,8 @@ static void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", - rfpath, pphyreg->rf3wire_offset, data_and_addr)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", + rfpath, pphyreg->rf3wire_offset, data_and_addr); } @@ -183,8 +184,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 original_value, readback_value, bitshift; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x)\n", regaddr, rfpath, bitmask)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", + regaddr, rfpath, bitmask); spin_lock(&rtlpriv->locks.rf_lock); @@ -195,9 +197,9 @@ u32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", regaddr, rfpath, - bitmask, original_value)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -212,8 +214,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) return; - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," - " data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); spin_lock(&rtlpriv->locks.rf_lock); @@ -228,8 +231,9 @@ void rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock(&rtlpriv->locks.rf_lock); - RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x), " - "data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, rfpath)); + RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, + "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", + regaddr, bitmask, data, rfpath); } @@ -249,7 +253,7 @@ void rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Unknown operation.\n")); + "Unknown operation\n"); break; } } @@ -264,9 +268,9 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (rtlphy->set_bwmode_inprogress) return; @@ -290,8 +294,7 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } @@ -316,13 +319,13 @@ void rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", rtlphy->current_chan_bw)); + "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); break; } rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); rtlphy->set_bwmode_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); } static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, @@ -438,7 +441,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); break; } @@ -458,9 +461,8 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) u32 delay; bool ret; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, - ("switch to channel%d\n", - rtlphy->current_channel)); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", + rtlphy->current_channel); if (rtlphy->sw_chnl_inprogress) return 0; @@ -496,7 +498,7 @@ u8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) rtlphy->sw_chnl_inprogress = false; - RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); + RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); return 1; } @@ -556,7 +558,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, do { InitializeCount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic enable\n")); + "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); } while ((rtstatus != true) && (InitializeCount < 10)); @@ -565,11 +567,11 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, RT_RF_OFF_LEVL_HALT_NIC); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("awake, sleeped:%d ms " - "state_inap:%x\n", - jiffies_to_msecs(jiffies - - ppsc->last_sleep_jiffies), - rtlpriv->psc.state_inap)); + "awake, sleeped:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc-> + last_sleep_jiffies), + rtlpriv->psc.state_inap); ppsc->last_awake_jiffies = jiffies; rtl_write_word(rtlpriv, CMDR, 0x37FC); rtl_write_byte(rtlpriv, TXPAUSE, 0x00); @@ -587,7 +589,7 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, case ERFOFF:{ if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, - ("IPS Set eRf nic disable\n")); + "IPS Set eRf nic disable\n"); rtl_ps_disable_nic(hw); RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -613,11 +615,9 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("eRf Off/Sleep: " - "%d times TcbBusyQueue[%d] = " - "%d before doze!\n", - (i + 1), queue_id, - skb_queue_len(&ring->queue))); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", + i + 1, queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; @@ -625,31 +625,30 @@ bool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - ("\nERFOFF: %d times" - "TcbBusyQueue[%d] = %d !\n", + "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", MAX_DOZE_WAITING_TIMES_9x, queue_id, - skb_queue_len(&ring->queue))); + skb_queue_len(&ring->queue)); break; } } RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("Set ERFSLEEP awaked:%d ms\n", + "Set ERFSLEEP awaked:%d ms\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies))); + ppsc->last_awake_jiffies)); RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG, - ("sleep awaked:%d ms " - "state_inap:%x\n", jiffies_to_msecs(jiffies - - ppsc->last_awake_jiffies), - rtlpriv->psc.state_inap)); + "sleep awaked:%d ms state_inap:%x\n", + jiffies_to_msecs(jiffies - + ppsc->last_awake_jiffies), + rtlpriv->psc.state_inap); ppsc->last_sleep_jiffies = jiffies; _rtl92se_phy_set_rf_sleep(hw); break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("switch case not process\n")); + "switch case not processed\n"); bresult = false; break; } @@ -995,7 +994,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Write BB Reg Fail!!")); + "Write BB Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1009,8 +1008,7 @@ static bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) } if (rtstatus != true) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("_rtl92s_phy_bb_config_parafile(): " - "BB_PG Reg Fail!!")); + "_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); goto phy_BB8190_Config_ParaFile_Fail; } @@ -1053,7 +1051,7 @@ u8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) radio_b_tblen = RADIOB_ARRAYLENGTH; } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Radio No %x\n", rfpath)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); rtstatus = true; switch (rfpath) { @@ -1175,11 +1173,11 @@ bool rtl92s_phy_bb_config(struct ieee80211_hw *hw) (rtlphy->rf_type == RF_2T2R && rf_num != 2) || (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("RF_Type(%x) does not match " - "RF_Num(%x)!!\n", rtlphy->rf_type, rf_num)); + "RF_Type(%x) does not match RF_Num(%x)!!\n", + rtlphy->rf_type, rf_num); RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("path1 0x%x, path2 0x%x, pathmap " - "0x%x\n", path1, path2, pathmap)); + "path1 0x%x, path2 0x%x, pathmap 0x%x\n", + path1, path2, pathmap); } return rtstatus; @@ -1214,20 +1212,20 @@ void rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) ROFDM0_XCAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("Default initial gain " - "(c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", rtlphy->default_initialgain[0], rtlphy->default_initialgain[1], rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3])); + rtlphy->default_initialgain[3]); /* read framesync */ rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - ("Default framesync (0x%x) = 0x%x\n", - ROFDM0_RXDETECTOR3, rtlphy->framesync)); + "Default framesync (0x%x) = 0x%x\n", + ROFDM0_RXDETECTOR3, rtlphy->framesync); } @@ -1287,10 +1285,9 @@ void rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) &ofdmpowerLevel[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Channel-%d, cckPowerLevel (A / B) = " - "0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", - channel, cckpowerlevel[0], cckpowerlevel[1], - ofdmpowerLevel[0], ofdmpowerLevel[1])); + "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", + channel, cckpowerlevel[0], cckpowerlevel[1], + ofdmpowerLevel[0], ofdmpowerLevel[1]); _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], &ofdmpowerLevel[0]); @@ -1316,7 +1313,7 @@ void rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) } while (--pollingcnt); if (pollingcnt == 0) - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Set FW Cmd fail!!\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Set FW Cmd fail!!\n"); } @@ -1345,20 +1342,17 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) switch (rtlhal->current_fwcmd_io) { case FW_CMD_RA_RESET: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_RESET\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_ACTIVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_ACTIVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_N: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); input = FW_RA_REFRESH; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); @@ -1367,7 +1361,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_BG: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG\n")); + "FW_CMD_RA_REFRESH_BG\n"); rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); rtl92s_phy_chk_fwcmd_iodone(hw); rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); @@ -1375,21 +1369,20 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) break; case FW_CMD_RA_REFRESH_N_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_N_COMB\n")); + "FW_CMD_RA_REFRESH_N_COMB\n"); input = FW_RA_IOT_N_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_RA_REFRESH_BG_COMB: RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_RA_REFRESH_BG_COMB\n")); + "FW_CMD_RA_REFRESH_BG_COMB\n"); input = FW_RA_IOT_BG_COMB; rtl_write_dword(rtlpriv, WFM5, input); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_IQK_ENABLE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_IQK_ENABLE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1424,8 +1417,7 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); break; case FW_CMD_LPS_ENTER: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_ENTER\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); current_aid = rtlpriv->mac80211.assoc_id; rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | ((current_aid | 0xc000) << 8))); @@ -1434,20 +1426,18 @@ static void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) * turbo mode until driver leave LPS */ break; case FW_CMD_LPS_LEAVE: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_LPS_LEAVE\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_ADD_A2_ENTRY: - RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, - ("FW_CMD_ADD_A2_ENTRY\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); rtl92s_phy_chk_fwcmd_iodone(hw); break; case FW_CMD_CTRL_DM_BY_DRIVER: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("FW_CMD_CTRL_DM_BY_DRIVER\n")); + "FW_CMD_CTRL_DM_BY_DRIVER\n"); rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); rtl92s_phy_chk_fwcmd_iodone(hw); break; @@ -1472,8 +1462,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) bool bPostProcessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", - fw_cmdio, rtlhal->set_fwcmd_inprogress)); + "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", + fw_cmdio, rtlhal->set_fwcmd_inprogress); do { /* We re-map to combined FW CMD ones if firmware version */ @@ -1501,7 +1491,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) * DM map table in the future. */ switch (fw_cmdio) { case FW_CMD_RA_INIT: - RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, ("RA init!!\n")); + RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); fw_cmdmap |= FW_RA_INIT_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); /* Clear control flag to sync with FW. */ @@ -1509,7 +1499,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_DIG_DISABLE: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG disable!!\n")); + "Set DIG disable!!\n"); fw_cmdmap &= ~FW_DIG_ENABLE_CTL; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1517,14 +1507,14 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) case FW_CMD_DIG_RESUME: if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG enable or resume!!\n")); + "Set DIG enable or resume!!\n"); fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); } break; case FW_CMD_DIG_HALT: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set DIG halt!!\n")); + "Set DIG halt!!\n"); fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); break; @@ -1540,9 +1530,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) (rtlefuse->thermalmeter[0] << 16)); RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("Set TxPwr tracking!! " - "FwCmdMap(%#x), FwParam(%#x)\n", - fw_cmdmap, fw_param)); + "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1563,9 +1552,8 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) fw_param &= FW_RA_PARAM_CLR; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] [New Version] " - "Set RA/IOT Comb in n mode!! FwCmdMap(%#x), " - "FwParam(%#x)\n", fw_cmdmap, fw_param)); + "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", + fw_cmdmap, fw_param); FW_CMD_PARA_SET(rtlpriv, fw_param); FW_CMD_IO_SET(rtlpriv, fw_cmdmap); @@ -1652,7 +1640,7 @@ bool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) break; case FW_CMD_PAPE_CONTROL: RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, - ("[FW CMD] Set PAPE Control\n")); + "[FW CMD] Set PAPE Control\n"); fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; FW_CMD_IO_SET(rtlpriv, fw_cmdmap); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 0ad50fe44aa..8966b731f7e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -123,13 +123,13 @@ static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, } if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "40MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } else { - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx " - "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], - p_final_pwridx[1])); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, + "20MHz finalpwr_idx (A / B) = 0x%x / 0x%x\n", + p_final_pwridx[0], p_final_pwridx[1]); } } @@ -153,9 +153,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, ant_pwr_diff = -8; RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Antenna Diff from RF-B " - "to RF-A = %d (0x%x)\n", ant_pwr_diff, - ant_pwr_diff & 0xf)); + "Antenna Diff from RF-B to RF-A = %d (0x%x)\n", + ant_pwr_diff, ant_pwr_diff & 0xf); ant_pwr_diff &= 0xf; } @@ -172,9 +171,8 @@ static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), u4reg_val); - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Write BCD-Diff(0x%x) = 0x%x\n", - RFPGA0_TXGAINSTAGE, u4reg_val)); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Write BCD-Diff(0x%x) = 0x%x\n", + RFPGA0_TXGAINSTAGE, u4reg_val); } static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, @@ -201,8 +199,7 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; case 1: /* Realtek regulatory increase power diff defined @@ -211,8 +208,8 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "40MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 40MHz, writeval = 0x%x\n", + writeval); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -234,16 +231,15 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Realtek regulatory, " - "20MHz, writeval = 0x%x\n", writeval)); + "Realtek regulatory, 20MHz, writeval = 0x%x\n", + writeval); } break; case 2: /* Better regulatory don't increase any power diff */ writeval = ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Better regulatory, " - "writeval = 0x%x\n", writeval)); + "Better regulatory, writeval = 0x%x\n", writeval); break; case 3: /* Customer defined power diff. increase power diff @@ -252,14 +248,14 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 40MHz = 0x%x\n", - rtlefuse->pwrgroup_ht40 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 40MHz = 0x%x\n", + rtlefuse->pwrgroup_ht40 + [RF90_PATH_A][chnl - 1]); } else { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("customer's limit, 20MHz = 0x%x\n", - rtlefuse->pwrgroup_ht20 - [RF90_PATH_A][chnl - 1])); + "customer's limit, 20MHz = 0x%x\n", + rtlefuse->pwrgroup_ht20 + [RF90_PATH_A][chnl - 1]); } for (i = 0; i < 4; i++) { @@ -293,22 +289,19 @@ static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, (pwrdiff_limit[1] << 8) | (pwrdiff_limit[0]); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer's limit = 0x%x\n", - customer_limit)); + "Customer's limit = 0x%x\n", customer_limit); writeval = customer_limit + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("Customer, writeval = " - "0x%x\n", writeval)); + "Customer, writeval = 0x%x\n", writeval); break; default: chnlgroup = 0; writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + ((index < 2) ? pwrbase0 : pwrbase1); RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - ("RTK better performance, " - "writeval = 0x%x\n", writeval)); + "RTK better performance, writeval = 0x%x\n", writeval); break; } @@ -541,8 +534,7 @@ void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) break; default: RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("unknown bandwidth: %#X\n", - bandwidth)); + "unknown bandwidth: %#X\n", bandwidth); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 78723cf5949..bc4b6fa4fc8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -188,7 +188,7 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + "Can't alloc buffer for fw\n"); return 1; } @@ -199,12 +199,12 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->io.dev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Failed to request firmware!\n")); + "Failed to request firmware!\n"); return 1; } if (firmware->size > sizeof(struct rt_firmware)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Firmware is too big!\n")); + "Firmware is too big!\n"); release_firmware(firmware); return 1; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index fbebe3ea0a2..1f266d1d795 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -756,7 +756,7 @@ void rtl92se_tx_fill_desc(struct ieee80211_hw *hw, /* DOWRD 8 */ SET_TX_DESC_TX_BUFFER_ADDRESS(pdesc, cpu_to_le32(mapping)); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, ("\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "\n"); } void rtl92se_tx_fill_cmddesc(struct ieee80211_hw *hw, u8 *pdesc, diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 1b8e68e70f8..d670e6886c1 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -276,14 +276,14 @@ static int _rtl_usb_init_tx(struct ieee80211_hw *hw) ? USB_HIGH_SPEED_BULK_SIZE : USB_FULL_SPEED_BULK_SIZE; - RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, ("USB Max Bulk-out Size=%d\n", - rtlusb->max_bulk_out_size)); + RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "USB Max Bulk-out Size=%d\n", + rtlusb->max_bulk_out_size); for (i = 0; i < __RTL_TXQ_NUM; i++) { u32 ep_num = rtlusb->ep_map.ep_mapping[i]; if (!ep_num) { RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("Invalid endpoint map setting!\n")); + "Invalid endpoint map setting!\n"); return -EINVAL; } } @@ -345,9 +345,9 @@ static int _rtl_usb_init(struct ieee80211_hw *hw) rtlusb->out_ep_nums++; RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, - ("USB EP(0x%02x), MaxPacketSize=%d ,Interval=%d.\n", + "USB EP(0x%02x), MaxPacketSize=%d, Interval=%d\n", pep_desc->bEndpointAddress, pep_desc->wMaxPacketSize, - pep_desc->bInterval)); + pep_desc->bInterval); } if (rtlusb->in_ep_nums < rtlpriv->cfg->usb_interface_cfg->in_ep_num) return -EINVAL ; @@ -414,7 +414,7 @@ static struct sk_buff *_rtl_prep_rx_urb(struct ieee80211_hw *hw, gfp_mask); if (!skb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to __dev_alloc_skb!!\n")); + "Failed to __dev_alloc_skb!!\n"); return ERR_PTR(-ENOMEM); } @@ -575,7 +575,7 @@ static void _rtl_rx_completed(struct urb *_urb) if (IS_ERR(_skb)) { err = PTR_ERR(_skb); RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate skb for bulk IN!\n")); + "Can't allocate skb for bulk IN!\n"); return; } skb = _skb; @@ -632,14 +632,14 @@ static int _rtl_usb_receive(struct ieee80211_hw *hw) urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to alloc URB!!\n")); + "Failed to alloc URB!!\n"); goto err_out; } skb = _rtl_prep_rx_urb(hw, rtlusb, urb, GFP_KERNEL); if (IS_ERR(skb)) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to prep_rx_urb!!\n")); + "Failed to prep_rx_urb!!\n"); err = PTR_ERR(skb); goto err_out; } @@ -745,7 +745,7 @@ static void _rtl_submit_tx_urb(struct ieee80211_hw *hw, struct urb *_urb) struct sk_buff *skb; RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Failed to submit urb.\n")); + "Failed to submit urb\n"); usb_unanchor_urb(_urb); skb = (struct sk_buff *)_urb->context; kfree_skb(skb); @@ -768,7 +768,7 @@ static int _usb_tx_post(struct ieee80211_hw *hw, struct urb *urb, if (urb->status) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Urb has error status 0x%X\n", urb->status)); + "Urb has error status 0x%X\n", urb->status); goto out; } /* TODO: statistics */ @@ -805,7 +805,7 @@ static struct urb *_rtl_usb_tx_urb_setup(struct ieee80211_hw *hw, _urb = usb_alloc_urb(0, GFP_ATOMIC); if (!_urb) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("Can't allocate URB for bulk out!\n")); + "Can't allocate URB for bulk out!\n"); kfree_skb(skb); return NULL; } @@ -830,7 +830,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, WARN_ON(NULL == rtlusb->usb_tx_aggregate_hdl); if (unlikely(IS_USB_STOP(rtlusb))) { RT_TRACE(rtlpriv, COMP_USB, DBG_EMERG, - ("USB device is stopping...\n")); + "USB device is stopping...\n"); kfree_skb(skb); return; } @@ -840,7 +840,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, _urb = _rtl_usb_tx_urb_setup(hw, _skb, ep_num); if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate urb. Drop skb!\n")); + "Can't allocate urb. Drop skb!\n"); return; } urb_list = &rtlusb->tx_pending[ep_num]; @@ -865,7 +865,7 @@ static void _rtl_usb_tx_preprocess(struct ieee80211_hw *hw, struct sk_buff *skb, memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc)); if (ieee80211_is_auth(fc)) { - RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n")); + RT_TRACE(rtlpriv, COMP_SEND, DBG_DMESG, "MAC80211_LINKING\n"); rtl_ips_nic_on(hw); } @@ -969,8 +969,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, /*like read eeprom and so on */ rtlpriv->cfg->ops->read_eeprom_info(hw); if (rtlpriv->cfg->ops->init_sw_vars(hw)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't init_sw_vars.\n")); + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); goto error_out; } rtlpriv->cfg->ops->init_sw_leds(hw); @@ -980,7 +979,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = rtl_init_core(hw); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't allocate sw for mac80211.\n")); + "Can't allocate sw for mac80211\n"); goto error_out; } @@ -990,7 +989,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, err = ieee80211_register_hw(hw); if (err) { RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - ("Can't register mac80211 hw.\n")); + "Can't register mac80211 hw\n"); goto error_out; } else { rtlpriv->mac80211.mac80211_registered = 1; -- cgit v1.2.3-70-g09d2 From 4c48869f5d6e4ee4a773fd67a01e1b934faa57f8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:42 -0800 Subject: rtlwifi: Convert RTPRINT macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RTPRINT parentheses. Coalesce formats. Align arguments. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 590002 55333 127560 772895 bcb1f drivers/net/wireless/rtlwifi/built-in.o.new 594841 55333 129680 779854 be64e drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 6 +- drivers/net/wireless/rtlwifi/efuse.c | 28 +-- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 74 ++++---- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 77 ++++----- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 71 ++++---- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 65 ++++--- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 250 +++++++++++++-------------- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 69 ++++---- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 85 ++++----- 9 files changed, 355 insertions(+), 370 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 8c139693354..8b51a828eff 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -175,11 +175,11 @@ do { \ } \ } while (0) -#define RTPRINT(rtlpriv, dbgtype, dbgflag, printstr) \ +#define RTPRINT(rtlpriv, dbgtype, dbgflag, fmt, ...) \ do { \ if (unlikely(rtlpriv->dbg.dbgp_type[dbgtype] & dbgflag)) { \ - printk(KERN_DEBUG "%s: ", KBUILD_MODNAME); \ - printk printstr; \ + printk(KERN_DEBUG KBUILD_MODNAME ": " fmt, \ + ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index 2885131cf1a..a079a31b4ed 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -280,7 +280,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (*rtemp8 != 0xFF) { efuse_utilized++; RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); efuse_addr++; } @@ -290,13 +290,13 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) if (offset < efuse_max_section) { wren = (*rtemp8 & 0x0f); RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("offset-%d Worden=%x\n", offset, wren)); + "offset-%d Worden=%x\n", offset, wren); for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) { if (!(wren & 0x01)) { RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -308,8 +308,8 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) break; RTPRINT(rtlpriv, FEEPROM, - EFUSE_READ_ALL, ("Addr=%d\n", - efuse_addr)); + EFUSE_READ_ALL, + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); efuse_addr++; @@ -326,7 +326,7 @@ void read_efuse(struct ieee80211_hw *hw, u16 _offset, u16 _size_byte, u8 *pbuf) } RTPRINT(rtlpriv, FEEPROM, EFUSE_READ_ALL, - ("Addr=%d\n", efuse_addr)); + "Addr=%d\n", efuse_addr); read_efuse_byte(hw, efuse_addr, rtemp8); if (*rtemp8 != 0xFF && (efuse_addr < efuse_len)) { efuse_utilized++; @@ -850,7 +850,7 @@ static void efuse_write_data_case1(struct ieee80211_hw *hw, u16 *efuse_addr, } } } - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse PG_STATE_HEADER-1\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse PG_STATE_HEADER-1\n"); } static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, @@ -915,7 +915,7 @@ static void efuse_write_data_case2(struct ieee80211_hw *hw, u16 *efuse_addr, } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-2\n")); + "efuse PG_STATE_HEADER-2\n"); } } @@ -935,7 +935,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (efuse_get_current_size(hw) >= (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES)) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse_pg_packet_write error\n")); + "efuse_pg_packet_write error\n"); return false; } @@ -947,7 +947,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, efuse_word_enable_data_read(word_en, data, target_pkt.data); target_word_cnts = efuse_calculate_word_cnts(target_pkt.word_en); - RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, ("efuse Power ON\n")); + RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, "efuse Power ON\n"); while (continual && (efuse_addr < (EFUSE_MAX_SIZE - EFUSE_OOB_PROTECT_BYTES))) { @@ -955,7 +955,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, if (write_state == PG_STATE_HEADER) { badworden = 0x0F; RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER\n")); + "efuse PG_STATE_HEADER\n"); if (efuse_one_byte_read(hw, efuse_addr, &efuse_data) && (efuse_data != 0xFF)) @@ -975,7 +975,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, } else if (write_state == PG_STATE_DATA) { RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_DATA\n")); + "efuse PG_STATE_DATA\n"); badworden = efuse_word_enable_data_write(hw, efuse_addr + 1, target_pkt.word_en, @@ -998,7 +998,7 @@ static int efuse_pg_packet_write(struct ieee80211_hw *hw, result = false; } RTPRINT(rtlpriv, FEEPROM, EFUSE_PG, - ("efuse PG_STATE_HEADER-3\n")); + "efuse PG_STATE_HEADER-3\n"); } } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 4aa228fe96e..2d01673a208 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1362,25 +1362,24 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, - rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { @@ -1411,11 +1410,11 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1452,13 +1451,13 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1497,27 +1496,27 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; @@ -1526,10 +1525,9 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } - RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; @@ -1542,7 +1540,7 @@ static void _rtl92ce_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92ce_read_adapter_info(struct ieee80211_hw *hw) diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 3ba1a4feeb3..5ef960499a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -123,8 +123,8 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; @@ -133,22 +133,22 @@ void rtl92ce_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -171,8 +171,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -187,8 +187,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -215,9 +215,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { @@ -225,9 +224,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 40MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 40MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } else { if (rtlphy->pwrgroup_cnt == 1) chnlgroup = 0; @@ -249,9 +247,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); } break; case 2: @@ -259,27 +256,24 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht40[rf][channel - - 1])); + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht40[rf][channel - + 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - rtlefuse->pwrgroup_ht20[rf][channel - - 1])); + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', + rtlefuse->pwrgroup_ht20[rf][channel - + 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -311,15 +305,15 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; @@ -329,9 +323,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeVal " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance, writeVal rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } @@ -383,7 +376,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 80bd17d8593..de1542f1485 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -162,24 +162,24 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse-> - eeprom_chnlarea_txpwr_cck[rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_cck[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_1s[rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse-> - eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path] - [i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse-> + eeprom_chnlarea_txpwr_ht40_2sdiif[rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { for (i = 0; i < 14; i++) { index = _rtl92c_get_chnl_group((u8) i); @@ -205,11 +205,10 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, } for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } for (i = 0; i < 3; i++) { @@ -242,13 +241,13 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, & 0xf0) >> 4); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } for (i = 0; i < 14; i++) { @@ -277,26 +276,26 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); if (!autoload_fail) rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); else rtlefuse->eeprom_regulatory = 0; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); if (!autoload_fail) { rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; @@ -305,9 +304,9 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); if (!autoload_fail) tempval = hwinfo[EEPROM_THERMAL_METER]; else @@ -320,7 +319,7 @@ static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, rtlefuse->apk_thermalmeterignore = true; rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter)); + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); } static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index 7b48ee9acb1..e132cb30a30 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -140,26 +140,26 @@ void rtl92cu_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; if (mac->mode == WIRELESS_MODE_B) tmpval = tmpval & 0xff00ffff; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, @@ -181,8 +181,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase0 << 8) | powerBase0; *(ofdmbase + i) = powerBase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { @@ -194,8 +194,8 @@ static void rtl92c_phy_get_power_base(struct ieee80211_hw *hw, (powerBase1 << 16) | (powerBase1 << 8) | powerBase1; *(mcsbase + i) = powerBase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -219,8 +219,8 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, [chnlgroup][index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "RTK better performance,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -244,32 +244,31 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, 20MHz, " - "writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Realtek regulatory, 20MHz, writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 2: writeVal = ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Better regulatory,writeVal(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Better regulatory,writeVal(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHzrf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHzrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -297,22 +296,22 @@ static void _rtl92c_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[2] << 16) | (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeVal = customer_limit + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeVal rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + "Customer, writeVal rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; default: chnlgroup = 0; writeVal = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup] [index + (rf ? 8 : 0)] + ((index < 2) ? powerBase0[rf] : powerBase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeValrf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeVal)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeValrf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeVal); break; } if (rtlpriv->dm.dynamic_txhighpower_lvl == @@ -365,7 +364,7 @@ static void _rtl92c_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, MASKDWORD, writeVal); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeVal)); + "Set 0x%x = %08x\n", regoffset, writeVal); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index 82cc052fc98..c736b933488 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1446,8 +1446,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) if (rtlhal->current_bandtype == BAND_ON_5G) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>5G\n"); u4tmp = curveindex_5g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 1 set RF-A, 5G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp); for (i = 0; i < RF_CHNL_NUM_5G; i++) { if (channel == rf_chnl_5g[i] && channel <= 140) index = 0; @@ -1545,8 +1545,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) } else if (rtlhal->current_bandtype == BAND_ON_2_4G) { RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "====>2.4G\n"); u4tmp = curveindex_2g[channel - 1]; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ver 3 set RF-B, 2G, " - "0x28 = 0x%x !!\n", u4tmp)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp); if (channel == 1 || channel == 2 || channel == 4 || channel == 9 || channel == 10 || channel == 11 || channel == 12) index = 0; @@ -1589,8 +1589,8 @@ static void _rtl92d_phy_switch_rf_setting(struct ieee80211_hw *hw, u8 channel) BRFREGOFFSETMASK)); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", - rf_syn_g4_for_c_cut_2g | (u4tmp << 11))); + "cosa ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", + rf_syn_g4_for_c_cut_2g | (u4tmp << 11)); rtl_set_rfreg(hw, (enum radio_path)path, RF_SYN_G4, BRFREGOFFSETMASK, @@ -1637,9 +1637,9 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) u32 regeac, rege94, rege9c, regea4; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); if (rtlhal->interfaceindex == 0) { rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x10008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x10008c1f); @@ -1657,26 +1657,26 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x28160206); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* One shot, path A LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & BIT(28)) && (((rege94 & 0x03FF0000) >> 16) != 0x142) && (((rege9c & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1687,7 +1687,7 @@ static u8 _rtl92d_phy_patha_iqk(struct ieee80211_hw *hw, bool configpathb) (((regeac & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A Rx IQK fail!!\n"); return result; } @@ -1708,9 +1708,9 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, TxOKBit = BIT(31); RxOKBit = BIT(30); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82140307); @@ -1723,7 +1723,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68110000); } /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-A PA on */ rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BMASKDWORD, 0x07000f60); @@ -1731,29 +1731,29 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, for (i = 0; i < retrycount; i++) { /* One shot, path A LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf9000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path A LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path A LOK & IQK.\n", + IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); rege94 = rtl_get_bbreg(hw, 0xe94, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe94 = 0x%x\n", rege94)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe94 = 0x%x\n", rege94); rege9c = rtl_get_bbreg(hw, 0xe9c, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xe9c = 0x%x\n", rege9c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xe9c = 0x%x\n", rege9c); regea4 = rtl_get_bbreg(hw, 0xea4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xea4 = 0x%x\n", regea4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xea4 = 0x%x\n", regea4); if (!(regeac & TxOKBit) && (((rege94 & 0x03FF0000) >> 16) != 0x142)) { result |= 0x01; } else { /* if Tx not OK, ignore Rx */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Tx IQK fail!!\n")); + "Path A Tx IQK fail!!\n"); continue; } @@ -1764,7 +1764,7 @@ static u8 _rtl92d_phy_patha_iqk_5g_normal(struct ieee80211_hw *hw, break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A Rx IQK fail!!\n")); + "Path A Rx IQK fail!!\n"); } } /* path A PA off */ @@ -1782,27 +1782,26 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) u32 regeac, regeb4, regebc, regec4, regecc; u8 result = 0; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* One shot, path B LOK & IQK */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("One shot, path A LOK & IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000002); rtl_set_bbreg(hw, 0xe60, BMASKDWORD, 0x00000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", - IQK_DELAY_TIME)); + "Delay %d ms for One shot, path B LOK & IQK\n", IQK_DELAY_TIME); mdelay(IQK_DELAY_TIME); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142) && (((regebc & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; @@ -1812,7 +1811,7 @@ static u8 _rtl92d_phy_pathb_iqk(struct ieee80211_hw *hw) (((regecc & 0x03FF0000) >> 16) != 0x36)) result |= 0x02; else - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B Rx IQK fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B Rx IQK fail!!\n"); return result; } @@ -1826,9 +1825,9 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) u8 i; u8 retrycount = 2; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQK!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQK!\n"); /* path-A IQK setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A IQK setting!\n"); rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x18008c1f); rtl_set_bbreg(hw, 0xe38, BMASKDWORD, 0x82110000); @@ -1841,7 +1840,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) rtl_set_bbreg(hw, 0xe5c, BMASKDWORD, 0x68160960); /* LO calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LO calibration setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LO calibration setting!\n"); rtl_set_bbreg(hw, 0xe4c, BMASKDWORD, 0x00462911); /* path-B PA on */ @@ -1851,26 +1850,26 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) for (i = 0; i < retrycount; i++) { /* One shot, path B LOK & IQK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("One shot, path A LOK & IQK!\n")); + "One shot, path A LOK & IQK!\n"); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xfa000000); rtl_set_bbreg(hw, 0xe48, BMASKDWORD, 0xf8000000); /* delay x ms */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Delay %d ms for One shot, path B LOK & IQK.\n", 10)); + "Delay %d ms for One shot, path B LOK & IQK.\n", 10); mdelay(IQK_DELAY_TIME * 10); /* Check failed */ regeac = rtl_get_bbreg(hw, 0xeac, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeac = 0x%x\n", regeac)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeac = 0x%x\n", regeac); regeb4 = rtl_get_bbreg(hw, 0xeb4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xeb4 = 0x%x\n", regeb4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xeb4 = 0x%x\n", regeb4); regebc = rtl_get_bbreg(hw, 0xebc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xebc = 0x%x\n", regebc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xebc = 0x%x\n", regebc); regec4 = rtl_get_bbreg(hw, 0xec4, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xec4 = 0x%x\n", regec4)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xec4 = 0x%x\n", regec4); regecc = rtl_get_bbreg(hw, 0xecc, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xecc = 0x%x\n", regecc)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xecc = 0x%x\n", regecc); if (!(regeac & BIT(31)) && (((regeb4 & 0x03FF0000) >> 16) != 0x142)) result |= 0x01; @@ -1882,7 +1881,7 @@ static u8 _rtl92d_phy_pathb_iqk_5g_normal(struct ieee80211_hw *hw) break; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Rx IQK fail!!\n")); + "Path B Rx IQK fail!!\n"); } } @@ -1901,7 +1900,7 @@ static void _rtl92d_phy_save_adda_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save ADDA parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save ADDA parameters.\n"); for (i = 0; i < regnum; i++) adda_backup[i] = rtl_get_bbreg(hw, adda_reg[i], BMASKDWORD); } @@ -1912,7 +1911,7 @@ static void _rtl92d_phy_save_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Save MAC parameters.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Save MAC parameters.\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); @@ -1926,7 +1925,7 @@ static void _rtl92d_phy_reload_adda_registers(struct ieee80211_hw *hw, u32 i; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Reload ADDA power saving parameters !\n")); + "Reload ADDA power saving parameters !\n"); for (i = 0; i < regnum; i++) rtl_set_bbreg(hw, adda_reg[i], BMASKDWORD, adda_backup[i]); } @@ -1937,7 +1936,7 @@ static void _rtl92d_phy_reload_mac_registers(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Reload MAC parameters !\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Reload MAC parameters !\n"); for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); rtl_write_byte(rtlpriv, macreg[i], macbackup[i]); @@ -1950,7 +1949,7 @@ static void _rtl92d_phy_path_adda_on(struct ieee80211_hw *hw, u32 pathon; u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("ADDA ON.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "ADDA ON.\n"); pathon = patha_on ? 0x04db25a4 : 0x0b1b25a4; if (patha_on) pathon = rtlpriv->rtlhal.interfaceindex == 0 ? @@ -1965,7 +1964,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, struct rtl_priv *rtlpriv = rtl_priv(hw); u32 i; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("MAC settings for Calibration.\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "MAC settings for Calibration.\n"); rtl_write_byte(rtlpriv, macreg[0], 0x3F); for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) @@ -1977,7 +1976,7 @@ static void _rtl92d_phy_mac_setting_calibration(struct ieee80211_hw *hw, static void _rtl92d_phy_patha_standby(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path-A standby mode!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path-A standby mode!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x0); rtl_set_bbreg(hw, RFPGA0_XA_LSSIPARAMETER, BMASKDWORD, 0x00010000); @@ -1990,7 +1989,7 @@ static void _rtl92d_phy_pimode_switch(struct ieee80211_hw *hw, bool pi_mode) u32 mode; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("BB Switch to %s mode!\n", (pi_mode ? "PI" : "SI"))); + "BB Switch to %s mode!\n", pi_mode ? "PI" : "SI"); mode = pi_mode ? 0x01000100 : 0x01000000; rtl_set_bbreg(hw, 0x820, BMASKDWORD, mode); rtl_set_bbreg(hw, 0x828, BMASKDWORD, mode); @@ -2022,12 +2021,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], const u32 retrycount = 2; u32 bbvalue; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 2.4G :Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 2.4G :Start!!!\n"); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, @@ -2065,7 +2064,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x01007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); @@ -2073,7 +2072,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], patha_ok = _rtl92d_phy_patha_iqk(hw, is2t); if (patha_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Success!!\n")); + "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2086,7 +2085,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; @@ -2095,7 +2094,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } } if (0x00 == patha_ok) - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK failed!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK failed!!\n"); if (is2t) { _rtl92d_phy_patha_standby(hw); /* Turn Path B ADDA on */ @@ -2104,7 +2103,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], pathb_ok = _rtl92d_phy_pathb_iqk(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2117,7 +2116,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } else if (i == (retrycount - 1) && pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, @@ -2126,12 +2125,12 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], } if (0x00 == pathb_ok) RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { @@ -2156,7 +2155,7 @@ static void _rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], rtl_set_bbreg(hw, 0xe30, BMASKDWORD, 0x01008c00); rtl_set_bbreg(hw, 0xe34, BMASKDWORD, 0x01008c00); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, @@ -2188,13 +2187,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, /* Note: IQ calibration must be performed after loading * PHY_REG.txt , and radio_a, radio_b.txt */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK for 5G NORMAL:Start!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK for 5G NORMAL:Start!!!\n"); mdelay(IQK_DELAY_TIME * 20); if (t == 0) { bbvalue = rtl_get_bbreg(hw, RFPGA0_RFMOD, BMASKDWORD); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("==>0x%08x\n", bbvalue)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQ Calibration for %s\n", - (is2t ? "2T2R" : "1T1R"))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "==>0x%08x\n", bbvalue); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQ Calibration for %s\n", + is2t ? "2T2R" : "1T1R"); /* Save ADDA parameters, turn Path A ADDA on */ _rtl92d_phy_save_adda_registers(hw, adda_reg, rtlphy->adda_backup, @@ -2231,13 +2230,13 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, 0xb6c, BMASKDWORD, 0x0f600000); /* IQ calibration setting */ - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("IQK setting!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "IQK setting!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0x80800000); rtl_set_bbreg(hw, 0xe40, BMASKDWORD, 0x10007c00); rtl_set_bbreg(hw, 0xe44, BMASKDWORD, 0x01004800); patha_ok = _rtl92d_phy_patha_iqk_5g_normal(hw, is2t); if (patha_ok == 0x03) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Success!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & @@ -2248,14 +2247,14 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (patha_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQK Only Tx Success!!\n")); + "Path A IQK Only Tx Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, BMASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, BMASKDWORD) & 0x3FF0000) >> 16; } else { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path A IQK Fail!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path A IQK Fail!!\n"); } if (is2t) { /* _rtl92d_phy_patha_standby(hw); */ @@ -2264,7 +2263,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, pathb_ok = _rtl92d_phy_pathb_iqk_5g_normal(hw); if (pathb_ok == 0x03) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK Success!!\n")); + "Path B IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & @@ -2275,20 +2274,20 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, 0x3FF0000) >> 16; } else if (pathb_ok == 0x01) { /* Tx IQK OK */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B Only Tx IQK Success!!\n")); + "Path B Only Tx IQK Success!!\n"); result[t][4] = (rtl_get_bbreg(hw, 0xeb4, BMASKDWORD) & 0x3FF0000) >> 16; result[t][5] = (rtl_get_bbreg(hw, 0xebc, BMASKDWORD) & 0x3FF0000) >> 16; } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path B IQK failed!!\n")); + "Path B IQK failed!!\n"); } } /* Back to BB mode, load original value */ RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Back to BB mode, load original value!\n")); + "IQK:Back to BB mode, load original value!\n"); rtl_set_bbreg(hw, 0xe28, BMASKDWORD, 0); if (t != 0) { if (is2t) @@ -2310,7 +2309,7 @@ static void _rtl92d_phy_iq_calibrate_5g_normal(struct ieee80211_hw *hw, rtlphy->adda_backup, IQK_ADDA_REG_NUM); } - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("<==\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "<==\n"); } static bool _rtl92d_phy_simularity_compare(struct ieee80211_hw *hw, @@ -2384,8 +2383,7 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->macphymode == DUALMAC_DUALPHY; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("Path A IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + "Path A IQ Calibration %s !\n", iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2395,8 +2393,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx0_a = (val_x * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx0_a = 0x%x," - " oldval_0 0x%x\n", val_x, tx0_a, oldval_0)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "X = 0x%x, tx0_a = 0x%x, oldval_0 0x%x\n", + val_x, tx0_a, oldval_0); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x3FF, tx0_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), ((val_x * oldval_0 >> 7) & 0x1)); @@ -2408,8 +2407,9 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx0_c = (val_y * oldval_0) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx0_c = 0x%lx\n", - val_y, tx0_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, + "Y = 0x%lx, tx0_c = 0x%lx\n", + val_y, tx0_c); rtl_set_bbreg(hw, ROFDM0_XCTxAFE, 0xF0000000, ((tx0_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XATxIQIMBALANCE, 0x003F0000, @@ -2417,11 +2417,11 @@ static void _rtl92d_phy_patha_fill_iqk_matrix(struct ieee80211_hw *hw, if (is2t) rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(26), ((val_y * oldval_0 >> 7) & 0x1)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("0xC80 = 0x%x\n", - rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, - BMASKDWORD))); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "0xC80 = 0x%x\n", + rtl_get_bbreg(hw, ROFDM0_XATxIQIMBALANCE, + BMASKDWORD)); if (txonly) { - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("only Tx OK\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "only Tx OK\n"); return; } reg = result[final_candidate][2]; @@ -2441,8 +2441,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, u32 oldval_1, val_x, tx1_a, reg; long val_y, tx1_c; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Path B IQ Calibration %s !\n", - (iqk_ok) ? "Success" : "Failed")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Path B IQ Calibration %s !\n", + iqk_ok ? "Success" : "Failed"); if (final_candidate == 0xFF) { return; } else if (iqk_ok) { @@ -2452,8 +2452,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if ((val_x & 0x00000200) != 0) val_x = val_x | 0xFFFFFC00; tx1_a = (val_x * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("X = 0x%x, tx1_a = 0x%x\n", - val_x, tx1_a)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "X = 0x%x, tx1_a = 0x%x\n", + val_x, tx1_a); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x3FF, tx1_a); rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(28), ((val_x * oldval_1 >> 7) & 0x1)); @@ -2463,8 +2463,8 @@ static void _rtl92d_phy_pathb_fill_iqk_matrix(struct ieee80211_hw *hw, if (rtlhal->current_bandtype == BAND_ON_5G) val_y += 3; tx1_c = (val_y * oldval_1) >> 8; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("Y = 0x%lx, tx1_c = 0x%lx\n", - val_y, tx1_c)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "Y = 0x%lx, tx1_c = 0x%lx\n", + val_y, tx1_c); rtl_set_bbreg(hw, ROFDM0_XDTxAFE, 0xF0000000, ((tx1_c & 0x3C0) >> 6)); rtl_set_bbreg(hw, ROFDM0_XBTxIQIMBALANCE, 0x003F0000, @@ -2496,7 +2496,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) unsigned long flag = 0; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK:Start!!!channel %d\n", rtlphy->current_channel)); + "IQK:Start!!!channel %d\n", rtlphy->current_channel); for (i = 0; i < 8; i++) { result[0][i] = 0; result[1][i] = 0; @@ -2510,7 +2510,7 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) is23simular = false; is13simular = false; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK !!!currentband %d\n", rtlhal->current_bandtype)); + "IQK !!!currentband %d\n", rtlhal->current_bandtype); rtl92d_acquire_cckandrw_pagea_ctl(hw, &flag); for (i = 0; i < 3; i++) { if (rtlhal->current_bandtype == BAND_ON_5G) { @@ -2562,10 +2562,9 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[i][6]; regecc = result[i][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); } if (final_candidate != 0xff) { rtlphy->reg_e94 = rege94 = result[final_candidate][0]; @@ -2577,12 +2576,11 @@ void rtl92d_phy_iq_calibrate(struct ieee80211_hw *hw) regec4 = result[final_candidate][6]; regecc = result[final_candidate][7]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: final_candidate is %x\n", final_candidate)); + "IQK: final_candidate is %x\n", final_candidate); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx " - "regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n ", + "IQK: rege94=%lx rege9c=%lx regea4=%lx regeac=%lx regeb4=%lx regebc=%lx regec4=%lx regecc=%lx\n", rege94, rege9c, regea4, regeac, regeb4, regebc, regec4, - regecc)); + regecc); patha_ok = pathb_ok = true; } else { rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; /* X default value */ @@ -2716,8 +2714,8 @@ static void _rtl92d_phy_calc_curvindex(struct ieee80211_hw *hw, } } smallest_abs_val = 0xffffffff; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("curveindex[%d] = %x\n", i, - curveindex[i])); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "curveindex[%d] = %x\n", + i, curveindex[i]); } } @@ -2733,13 +2731,13 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, bool bneed_powerdown_radio = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_LOUD, "path %d\n", erfpath); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("band type = %d\n", - rtlpriv->rtlhal.current_bandtype)); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("channel = %d\n", channel)); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "band type = %d\n", + rtlpriv->rtlhal.current_bandtype); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "channel = %d\n", channel); if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ u4tmp = curveindex_5g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 1) { bneed_powerdown_radio = @@ -2758,7 +2756,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { u4tmp = curveindex_2g[channel-1]; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp)); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp); if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && rtlpriv->rtlhal.interfaceindex == 0) { bneed_powerdown_radio = @@ -2770,8 +2768,8 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw, } rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", - rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800))); + "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", + rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); if (bneed_powerdown_radio) _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); if (rtlpriv->rtlhal.during_mac0init_radiob) @@ -2825,20 +2823,20 @@ static void _rtl92d_phy_lc_calibrate_sw(struct ieee80211_hw *hw, bool is2t) RF_SYN_G6, BRFREGOFFSETMASK); } RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("PHY_LCK finish delay for %d ms=2\n", timecount)); + "PHY_LCK finish delay for %d ms=2\n", timecount); u4tmp = rtl_get_rfreg(hw, index, RF_SYN_G4, BRFREGOFFSETMASK); if (index == 0 && rtlhal->interfaceindex == 0) { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-A / 5G LCK\n")); + "path-A / 5G LCK\n"); } else { RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("path-B / 2.4G LCK\n")); + "path-B / 2.4G LCK\n"); } memset(&curvecount_val[0], 0, CV_CURVE_CNT * 2); /* Set LC calibration off */ rtl_set_rfreg(hw, (enum radio_path)index, RF_CHNLBW, 0x08000, 0x0); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("set RF 0x18[15] = 0\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "set RF 0x18[15] = 0\n"); /* save Curve-counting number */ for (i = 0; i < CV_CURVE_CNT; i++) { u32 readval = 0, readval2 = 0; @@ -2888,7 +2886,7 @@ static void _rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { struct rtl_priv *rtlpriv = rtl_priv(hw); - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("cosa PHY_LCK ver=2\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "cosa PHY_LCK ver=2\n"); _rtl92d_phy_lc_calibrate_sw(hw, is2t); } @@ -2906,8 +2904,8 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) rtlphy->lck_inprogress = true; RTPRINT(rtlpriv, FINIT, INIT_IQK, - ("LCK:Start!!! currentband %x delay %d ms\n", - rtlhal->current_bandtype, timecount)); + "LCK:Start!!! currentband %x delay %d ms\n", + rtlhal->current_bandtype, timecount); if (IS_92D_SINGLEPHY(rtlhal->version)) { _rtl92d_phy_lc_calibrate(hw, true); } else { @@ -2915,7 +2913,7 @@ void rtl92d_phy_lc_calibrate(struct ieee80211_hw *hw) _rtl92d_phy_lc_calibrate(hw, false); } rtlphy->lck_inprogress = false; - RTPRINT(rtlpriv, FINIT, INIT_IQK, ("LCK:Finish!!!\n")); + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Finish!!!\n"); } void rtl92d_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 3bf21c2cf08..2e174f48946 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -127,23 +127,23 @@ void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw, tmpval = tx_agc[RF90_PATH_A] & 0xff; rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, BMASKBYTE1, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_A_CCK1_MCS32)); + "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_A_CCK1_MCS32); tmpval = tx_agc[RF90_PATH_A] >> 8; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] >> 24; rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, BMASKBYTE0, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK11_A_CCK2_11)); + "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK11_A_CCK2_11); tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff; rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", tmpval, - RTXAGC_B_CCK1_55_MCS32)); + "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n", + tmpval, RTXAGC_B_CCK1_55_MCS32); } static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, @@ -165,8 +165,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase0 << 8) | powerbase0; *(ofdmbase + i) = powerbase0; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [OFDM power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(ofdmbase + i))); + " [OFDM power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(ofdmbase + i)); } for (i = 0; i < 2; i++) { @@ -179,8 +179,8 @@ static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw, (powerbase1 << 8) | powerbase1; *(mcsbase + i) = powerbase1; RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - (" [MCS power base index rf(%c) = 0x%x]\n", - ((i == 0) ? 'A' : 'B'), *(mcsbase + i))); + " [MCS power base index rf(%c) = 0x%x]\n", + i == 0 ? 'A' : 'B', *(mcsbase + i)); } } @@ -232,9 +232,9 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better " - "performance, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "RTK better performance, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 1: if (rtlphy->pwrgroup_cnt == 1) @@ -253,33 +253,31 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Realtek regulatory, " - "20MHz, writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), - writeval)); + "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); } break; case 2: writeval = ((index < 2) ? powerbase0[rf] : powerbase1[rf]); - RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, " - "writeval(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + RTPRINT(rtlpriv, FPHY, PHY_TXPWR, + "Better regulatory, writeval(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; case 3: chnlgroup = 0; if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 40MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 40MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht40[rf] - [channel - 1])); + [channel - 1]); } else { RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("customer's limit, 20MHz rf(%c) = " - "0x%x\n", ((rf == 0) ? 'A' : 'B'), + "customer's limit, 20MHz rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', rtlefuse->pwrgroup_ht20[rf] - [channel - 1])); + [channel - 1]); } for (i = 0; i < 4; i++) { pwr_diff_limit[i] = @@ -308,13 +306,13 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (pwr_diff_limit[1] << 8) | (pwr_diff_limit[0]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer's limit rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), customer_limit)); + "Customer's limit rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', customer_limit); writeval = customer_limit + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Customer, writeval rf(%c)= 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "Customer, writeval rf(%c)= 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; default: chnlgroup = 0; @@ -323,9 +321,8 @@ static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw, (rf ? 8 : 0)] + ((index < 2) ? powerbase0[rf] : powerbase1[rf]); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("RTK better performance, writeval " - "rf(%c) = 0x%x\n", - ((rf == 0) ? 'A' : 'B'), writeval)); + "RTK better performance, writeval rf(%c) = 0x%x\n", + rf == 0 ? 'A' : 'B', writeval); break; } *(p_outwriteval + rf) = writeval; @@ -367,7 +364,7 @@ static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw, regoffset = regoffset_b[index]; rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval); RTPRINT(rtlpriv, FPHY, PHY_TXPWR, - ("Set 0x%x = %08x\n", regoffset, writeval)); + "Set 0x%x = %08x\n", regoffset, writeval); if (((get_rf_type(rtlphy) == RF_2T2R) && (regoffset == RTXAGC_A_MCS15_MCS12 || regoffset == RTXAGC_B_MCS15_MCS12)) || diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index dffcafe01a3..acab8781cc7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1704,23 +1704,24 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM CCK Area(%d) = 0x%x\n", rf_path, - i, rtlefuse->eeprom_chnlarea_txpwr_cck - [rf_path][i])); + "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_cck + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_1s - [rf_path][i])); + "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_1s + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) for (i = 0; i < 3; i++) RTPRINT(rtlpriv, FINIT, INIT_EEPROM, - ("RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", - rf_path, i, - rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif - [rf_path][i])); + "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", + rf_path, i, + rtlefuse->eeprom_chnlarea_txpwr_ht40_2sdiif + [rf_path][i]); for (rf_path = 0; rf_path < 2; rf_path++) { @@ -1751,11 +1752,11 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) for (i = 0; i < 14; i++) { RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = " - "[0x%x / 0x%x / 0x%x]\n", rf_path, i, - rtlefuse->txpwrlevel_cck[rf_path][i], - rtlefuse->txpwrlevel_ht40_1s[rf_path][i], - rtlefuse->txpwrlevel_ht40_2s[rf_path][i])); + "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", + rf_path, i, + rtlefuse->txpwrlevel_cck[rf_path][i], + rtlefuse->txpwrlevel_ht40_1s[rf_path][i], + rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); } } @@ -1788,13 +1789,13 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) 0xf0) >> 4); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht20[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht20[rf_path][i])); + "RF-%d pwrgroup_ht20[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht20[rf_path][i]); RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-%d pwrgroup_ht40[%d] = 0x%x\n", - rf_path, i, - rtlefuse->pwrgroup_ht40[rf_path][i])); + "RF-%d pwrgroup_ht40[%d] = 0x%x\n", + rf_path, i, + rtlefuse->pwrgroup_ht40[rf_path][i]); } } @@ -1849,27 +1850,27 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) (hwinfo[EEPROM_REGULATORY] & 0x1); } RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory)); + "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_A][i])); + "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i])); + "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_ht20diff[RF90_PATH_B][i])); + "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); for (i = 0; i < 14; i++) RTPRINT(rtlpriv, FINIT, INIT_TxPower, - ("RF-B Legacy to HT40 Diff[%d] = 0x%x\n", i, - rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i])); + "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", + i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPwrSafetyFlag = %d\n", - rtlefuse->txpwr_safetyflag)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); /* Read RF-indication and Tx Power gain * index diff of legacy to HT OFDM rate. */ @@ -1878,8 +1879,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) rtlefuse->legacy_httxpowerdiff = rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TxPowerDiff = %#x\n", - rtlefuse->eeprom_txpowerdiff)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); /* Get TSSI value for each path. */ usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; @@ -1887,16 +1888,16 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) usvalue = *(u8 *)&hwinfo[EEPROM_TSSI_B]; rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("TSSI_A = 0x%x, TSSI_B = 0x%x\n", - rtlefuse->eeprom_tssi[RF90_PATH_A], - rtlefuse->eeprom_tssi[RF90_PATH_B])); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", + rtlefuse->eeprom_tssi[RF90_PATH_A], + rtlefuse->eeprom_tssi[RF90_PATH_B]); /* Read antenna tx power offset of B/C/D to A from EEPROM */ /* and read ThermalMeter from EEPROM */ tempval = *(u8 *)&hwinfo[EEPROM_THERMALMETER]; rtlefuse->eeprom_thermalmeter = tempval; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("thermalmeter = 0x%x\n", - rtlefuse->eeprom_thermalmeter)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); @@ -1912,8 +1913,8 @@ static void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) /* Version ID, Channel plan */ rtlefuse->eeprom_channelplan = *(u8 *)&hwinfo[EEPROM_CHANNELPLAN]; rtlefuse->txpwr_fromeprom = true; - RTPRINT(rtlpriv, FINIT, INIT_TxPower, ("EEPROM ChannelPlan = 0x%4x\n", - rtlefuse->eeprom_channelplan)); + RTPRINT(rtlpriv, FINIT, INIT_TxPower, + "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); /* Read Customer ID or Board Type!!! */ tempval = *(u8 *)&hwinfo[EEPROM_BOARDTYPE]; -- cgit v1.2.3-70-g09d2 From 9d833ed752e91c71792dd8ebfd0f865e6a568a37 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:43 -0800 Subject: rtlwifi: Convert RT_ASSERT macro to use ##__VA_ARGS__ Consolidate printks to avoid possible message interleaving and reduce the object size. Remove unnecessary RT_ASSERT parentheses. Align arguments. Coalesce formats. Remove unnecessary __func__ use as the macro uses it. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 588901 55333 127216 771450 bc57a drivers/net/wireless/rtlwifi/built-in.o.new 590002 55333 127560 772895 bcb1f drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/core.c | 4 ++-- drivers/net/wireless/rtlwifi/debug.h | 7 +++---- drivers/net/wireless/rtlwifi/pci.c | 15 +++++++-------- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 10 +++++----- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 5 +++-- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 6 +++--- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 13 ++++++------- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 16 ++++++++-------- drivers/net/wireless/rtlwifi/usb.c | 2 +- 21 files changed, 68 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 186c944c143..ab6a4068764 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1026,8 +1026,8 @@ static int rtl_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG, "set pairwise key\n"); if (!sta) { - RT_ASSERT(false, ("pairwise key withnot" - "mac_addr\n")); + RT_ASSERT(false, + "pairwise key without mac_addr\n"); err = -EOPNOTSUPP; goto out_unlock; diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 8b51a828eff..74b6780880f 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,12 +156,11 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; -#define RT_ASSERT(_exp, fmt) \ +#define RT_ASSERT(_exp, fmt, ...) \ do { \ if (!(_exp)) { \ - printk(KERN_DEBUG "%s:%s(): ", \ - KBUILD_MODNAME, __func__); \ - printk fmt; \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s(): " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } while (0) diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index b52fef23575..3c4ae5d9de4 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1746,16 +1746,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_enable_device(pdev); if (err) { - RT_ASSERT(false, - ("%s : Cannot enable new PCI device\n", - pci_name(pdev))); + RT_ASSERT(false, "%s : Cannot enable new PCI device\n", + pci_name(pdev)); return err; } if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { - RT_ASSERT(false, ("Unable to obtain 32bit DMA " - "for consistent allocations\n")); + RT_ASSERT(false, + "Unable to obtain 32bit DMA for consistent allocations\n"); pci_disable_device(pdev); return -ENOMEM; } @@ -1767,7 +1766,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, sizeof(struct rtl_priv), &rtl_ops); if (!hw) { RT_ASSERT(false, - ("%s : ieee80211 alloc failed\n", pci_name(pdev))); + "%s : ieee80211 alloc failed\n", pci_name(pdev)); err = -ENOMEM; goto fail1; } @@ -1797,7 +1796,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, /* MEM map */ err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { - RT_ASSERT(false, ("Can't obtain PCI resources\n")); + RT_ASSERT(false, "Can't obtain PCI resources\n"); return err; } @@ -1810,7 +1809,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, (unsigned long)pci_iomap(pdev, rtlpriv->cfg->bar_id, pmem_len); if (rtlpriv->io.pci_mem_start == 0) { - RT_ASSERT(false, ("Can't map PCI mem\n")); + RT_ASSERT(false, "Can't map PCI mem\n"); goto fail2; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 12c025bf53b..1eae3baae51 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -519,8 +519,8 @@ void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u32 tmp_cmdbuf[2]; if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); + RT_ASSERT(false, + "return H2C cmd because of Fw download fail!!!\n"); return; } @@ -544,7 +544,7 @@ void rtl92c_firmware_selfreset(struct ieee80211_hw *hw) while (u1b_tmp & BIT(2)) { delay--; if (delay == 0) { - RT_ASSERT(false, ("8051 reset fail.\n")); + RT_ASSERT(false, "8051 reset fail\n"); break; } udelay(50); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 8ab93a69f33..25bde968699 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -85,7 +85,7 @@ EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); return 0; } @@ -95,7 +95,7 @@ void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, enum radio_path rfpath, u32 offset, u32 data) { - RT_ASSERT(false, ("deprecated!\n")); + RT_ASSERT(false, "deprecated!\n"); } EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); @@ -776,7 +776,7 @@ u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) if (rtlphy->set_bwmode_inprogress) return 0; RT_ASSERT((rtlphy->current_channel <= 14), - ("WIRELESS_MODE_G but channel>14")); + "WIRELESS_MODE_G but channel>14\n"); rtlphy->sw_chnl_inprogress = true; rtlphy->sw_chnl_stage = 0; rtlphy->sw_chnl_step = 0; @@ -802,7 +802,7 @@ static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -848,7 +848,7 @@ bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 2d01673a208..18f615c4121 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1166,7 +1166,7 @@ void rtl92ce_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index d2a3576fdaa..4a224dbc693 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -404,7 +404,7 @@ static int __init rtl92ce_module_init(void) ret = pci_register_driver(&rtl92ce_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 9f6fac450a4..46892cc1a08 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -836,8 +836,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -856,8 +856,8 @@ void rtl92ce_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -876,8 +876,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -890,8 +890,8 @@ u32 rtl92ce_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index de1542f1485..ae38bc52a71 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1984,8 +1984,9 @@ void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) u4b_ac_param); break; default: - RT_ASSERT(false, ("SetHwReg8185(): invalid" - " aci: %d !\n", e_aci)); + RT_ASSERT(false, + "SetHwReg8185(): invalid aci: %d !\n", + e_aci); break; } if (rtlusb->acm_method != eAcmWay2_SW) diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 9f09844d7d5..943f3d49d1f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -428,7 +428,7 @@ void rtl92c_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, u4b_ac_param); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index b875af75b89..aca0fd5d116 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -244,8 +244,8 @@ u16 rtl8192cu_mq_to_hwq(__le16 fc, u16 mac80211_queue_index) break; default: hw_queue_index = RTL_TXQ_BE; - RT_ASSERT(false, ("QSLT_BE queue, skb_queue:%d\n", - mac80211_queue_index)); + RT_ASSERT(false, "QSLT_BE queue, skb_queue:%d\n", + mac80211_queue_index); break; } out: diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index b84f10d60c0..94f5b7dd06e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -186,7 +186,7 @@ void rtl92d_firmware_selfreset(struct ieee80211_hw *hw) udelay(50); u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); } - RT_ASSERT((delay > 0), ("8051 reset failed!\n")); + RT_ASSERT((delay > 0), "8051 reset failed!\n"); RT_TRACE(rtlpriv, COMP_FW, DBG_DMESG, "=====> 8051 reset success (%d)\n", delay); } @@ -536,8 +536,8 @@ void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u32 tmp_cmdbuf[2]; if (rtlhal->fw_ready == false) { - RT_ASSERT(false, ("return H2C cmd because of Fw " - "download fail!!!\n")); + RT_ASSERT(false, + "return H2C cmd because of Fw download fail!!!\n"); return; } memset(tmp_cmdbuf, 0, 8); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 5eecf403a5c..d94ce371572 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1213,7 +1213,7 @@ void rtl92de_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index c736b933488..f27acc75494 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -2928,7 +2928,7 @@ static bool _rtl92d_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } if (cmdtableidx >= cmdtablesz) @@ -3120,19 +3120,18 @@ u8 rtl92d_phy_sw_chnl(struct ieee80211_hw *hw) * 5G and 2.4G band. */ if (channel <= 14) return 0; - RT_ASSERT((channel > 14), ("5G but channel<=14")); + RT_ASSERT((channel > 14), "5G but channel<=14\n"); break; case BAND_ON_2_4G: /* Get first channel error when change between * 5G and 2.4G band. */ if (channel > 14) return 0; - RT_ASSERT((channel <= 14), ("2G but channel>14")); + RT_ASSERT((channel <= 14), "2G but channel>14\n"); break; default: - RT_ASSERT(false, - ("Invalid WirelessMode(%#x)!!\n", - rtlpriv->mac80211.mode)); + RT_ASSERT(false, "Invalid WirelessMode(%#x)!!\n", + rtlpriv->mac80211.mode); break; } rtlphy->sw_chnl_inprogress = true; @@ -3563,7 +3562,7 @@ void rtl92d_phy_set_poweron(struct ieee80211_hw *hw) } } if (i == 200) - RT_ASSERT(false, ("Another mac power off over time\n")); + RT_ASSERT(false, "Another mac power off over time\n"); } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index db7579684b1..022f0652970 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -424,7 +424,7 @@ static int __init rtl92de_module_init(void) ret = pci_register_driver(&rtl92de_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index f6ec0a12884..e7c985b372f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -793,8 +793,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d" - " not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -813,8 +813,8 @@ void rtl92de_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -833,8 +833,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(p_desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -847,8 +847,8 @@ u32 rtl92de_get_desc(u8 *p_desc, bool istx, u8 desc_name) ret = GET_RX_DESC_PKT_LEN(pdesc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d " - "not process\n", desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index acab8781cc7..b03001b2328 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1200,7 +1200,7 @@ void rtl92se_set_qos(struct ieee80211_hw *hw, int aci) rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); break; default: - RT_ASSERT(false, ("invalid aci: %d !\n", aci)); + RT_ASSERT(false, "invalid aci: %d !\n", aci); break; } } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index ec5520e6847..e24dbb3a9ba 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -335,7 +335,7 @@ static bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, struct swchnlcmd *pcmd; if (cmdtable == NULL) { - RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); + RT_ASSERT(false, "cmdtable cannot be NULL\n"); return false; } @@ -380,7 +380,7 @@ static bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), - ("illegal channel for Zebra: %d\n", channel)); + "invalid channel for Zebra: %d\n", channel); _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index bc4b6fa4fc8..a933aef3d1a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -426,7 +426,7 @@ static int __init rtl92se_module_init(void) ret = pci_register_driver(&rtl92se_driver); if (ret) - RT_ASSERT(false, (": No device found\n")); + RT_ASSERT(false, "No device found\n"); return ret; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 1f266d1d795..216a3e140de 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -823,8 +823,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_TX_DESC_NEXT_DESC_ADDRESS(pdesc, *(u32 *) val); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -843,8 +843,8 @@ void rtl92se_set_desc(u8 *pdesc, bool istx, u8 desc_name, u8 *val) SET_RX_STATUS_DESC_EOR(pdesc, 1); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } @@ -863,8 +863,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_TX_DESC_TX_BUFFER_ADDRESS(desc); break; default: - RT_ASSERT(false, ("ERR txdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR txdesc :%d not process\n", + desc_name); break; } } else { @@ -876,8 +876,8 @@ u32 rtl92se_get_desc(u8 *desc, bool istx, u8 desc_name) ret = GET_RX_STATUS_DESC_PKT_LEN(desc); break; default: - RT_ASSERT(false, ("ERR rxdesc :%d not process\n", - desc_name)); + RT_ASSERT(false, "ERR rxdesc :%d not process\n", + desc_name); break; } } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index d670e6886c1..6ae1b212ad9 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -946,7 +946,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) + sizeof(struct rtl_usb_priv), &rtl_ops); if (!hw) { - RT_ASSERT(false, ("%s : ieee80211 alloc failed\n", __func__)); + RT_ASSERT(false, "ieee80211 alloc failed\n"); return -ENOMEM; } rtlpriv = hw->priv; -- cgit v1.2.3-70-g09d2 From 4cd9f40c66e36c59f3a753d5167a89a312f5aa87 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:44 -0800 Subject: rtlwifi: Remove duplicate __func__ The RT_TRACE macro already prepends it. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index aca0fd5d116..7d5f79991f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -620,7 +620,7 @@ void rtl92cu_tx_fill_desc(struct ieee80211_hw *hw, SET_TX_DESC_BMC(txdesc, 1); _rtl_fill_usb_tx_desc(txdesc); _rtl_tx_desc_checksum(txdesc); - RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, " %s ==>\n", __func__); + RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, "==>\n"); } void rtl92cu_fill_fake_txdesc(struct ieee80211_hw *hw, u8 * pDesc, -- cgit v1.2.3-70-g09d2 From f56e7eb4dd3124d53a5200ff093bc6bcbae671e9 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 4 Jan 2012 19:40:45 -0800 Subject: rtlwifi: Optimize RT_TRACE macro use of KBUILD_MODNAME for size Moving the KBUILD_MODNAME to the format reduces the overall object size a small amount. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.new 588901 55333 127216 771450 bc57a drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/debug.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index 74b6780880f..b024c23b652 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -168,9 +168,9 @@ do { \ do { \ if (unlikely(((comp) & rtlpriv->dbg.global_debugcomponents) && \ ((level) <= rtlpriv->dbg.global_debuglevel))) { \ - printk(KERN_DEBUG "%s:%s():<%lx-%x> " fmt, \ - KBUILD_MODNAME, __func__, \ - in_interrupt(), in_atomic(), ##__VA_ARGS__); \ + printk(KERN_DEBUG KBUILD_MODNAME ":%s():<%lx-%x> " fmt, \ + __func__, in_interrupt(), in_atomic(), \ + ##__VA_ARGS__); \ } \ } while (0) -- cgit v1.2.3-70-g09d2 From 481b9606ec7276401c7f746fe37873855c49d1b8 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 5 Jan 2012 08:29:07 -0800 Subject: rtlwifi: add CONFIG_RTLWIFI_DEBUG to remove all of the debug logging code It does seem odd though to have a DBG_EMERG and not always emit it. What might also be useful for any embedded use is to add CONFIG_RTLWIFI_DEBUG to conditionally remove all of the debug logging code to reduce the largish object size. This reduces the object size by about 1/3 (250KB) when CONFIG_RTLWIFI_DEBUG is not set. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 368722 55333 94224 518279 7e887 drivers/net/wireless/rtlwifi/built-in.o.new 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/Kconfig | 5 +++++ drivers/net/wireless/rtlwifi/debug.h | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/Kconfig b/drivers/net/wireless/rtlwifi/Kconfig index d6c42e69bdb..44b9c0a5770 100644 --- a/drivers/net/wireless/rtlwifi/Kconfig +++ b/drivers/net/wireless/rtlwifi/Kconfig @@ -49,6 +49,11 @@ config RTLWIFI depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE default m +config RTLWIFI_DEBUG + tristate "Additional debugging output" + depends on RTL8192CE || RTL8192CU || RTL8192SE || RTL8192DE + default y + config RTL8192C_COMMON tristate depends on RTL8192CE || RTL8192CU diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index b024c23b652..fd5600c6942 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -156,6 +156,8 @@ enum dbgp_flag_e { DBGP_TYPE_MAX }; +#ifdef CONFIG_RTLWIFI_DEBUG + #define RT_ASSERT(_exp, fmt, ...) \ do { \ if (!(_exp)) { \ @@ -195,5 +197,37 @@ do { \ } \ } while (0) +#else + +struct rtl_priv; + +__printf(2, 3) +static inline void RT_ASSERT(int exp, const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RT_TRACE(struct rtl_priv *rtlpriv, + int comp, int level, + const char *fmt, ...) +{ +} + +__printf(4, 5) +static inline void RTPRINT(struct rtl_priv *rtlpriv, + int dbgtype, int dbgflag, + const char *fmt, ...) +{ +} + +static inline void RT_PRINT_DATA(struct rtl_priv *rtlpriv, + int comp, int level, + const char *titlestring, + const void *hexdata, size_t hexdatalen) +{ +} + +#endif + void rtl_dbgp_flag_init(struct ieee80211_hw *hw); #endif -- cgit v1.2.3-70-g09d2 From d9595ce30bd860a1c5bcafef8430f46faa26d6eb Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Jan 2012 11:31:42 -0800 Subject: rtlwifi: Remove incorrect logging message prefixes pr_fmt() adds them. These are unnecessary and wrong. Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 943f3d49d1f..71c7aca0b43 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -84,7 +84,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) } } rtlhal->version = (enum version_8192c)chip_version; - pr_info("rtl8192cu: Chip version 0x%x\n", chip_version); + pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 022f0652970..364aa402245 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -154,9 +154,9 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index a933aef3d1a..5795a542bdf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -168,9 +168,9 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->psc.swctrl_lps = rtlpriv->cfg->mod_params->swctrl_lps; rtlpriv->psc.fwctrl_lps = rtlpriv->cfg->mod_params->fwctrl_lps; if (!rtlpriv->psc.inactiveps) - pr_info("rtl8192ce: Power Save off (module option)\n"); + pr_info("Power Save off (module option)\n"); if (!rtlpriv->psc.fwctrl_lps) - pr_info("rtl8192ce: FW Power Save off (module option)\n"); + pr_info("FW Power Save off (module option)\n"); rtlpriv->psc.reg_fwctrl_lps = 3; rtlpriv->psc.reg_max_lps_awakeintvl = 5; /* for ASPM, you can close aspm through -- cgit v1.2.3-70-g09d2 From 07839b143a360f9dcf38afb5600cf049f8cbee0e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 6 Jan 2012 11:31:43 -0800 Subject: rtlwifi: Simplify chip version id logging Reduce object size a few KB too. $ size drivers/net/wireless/rtlwifi/built-in.o* text data bss dec hex filename 584493 55333 126800 766626 bb2a2 drivers/net/wireless/rtlwifi/built-in.o.new 586904 55333 127216 769453 bbdad drivers/net/wireless/rtlwifi/built-in.o.old Signed-off-by: Joe Perches Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 19 ++++++------ drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 46 +++++++++++----------------- 2 files changed, 27 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 18f615c4121..971bd29ef9b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -991,6 +991,7 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); enum version_8192c version = VERSION_UNKNOWN; u32 value32; + const char *versionid; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); if (value32 & TRP_VAUX_EN) { @@ -1003,27 +1004,25 @@ static enum version_8192c _rtl92ce_read_chip_version(struct ieee80211_hw *hw) switch (version) { case VERSION_B_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_92C\n"); + versionid = "B_CHIP_92C"; break; case VERSION_B_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_88C\n"); + versionid = "B_CHIP_88C"; break; case VERSION_A_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_A_CHIP_92C\n"); + versionid = "A_CHIP_92C"; break; case VERSION_A_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_A_CHIP_88C\n"); + versionid = "A_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Chip Version ID: Unknown. Bug?\n"); + versionid = "Unknown. Bug?"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + switch (version & 0x3) { case CHIP_88C: rtlphy->rf_type = RF_1T1R; diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 71c7aca0b43..060ed5fec69 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -57,6 +57,7 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) struct rtl_phy *rtlphy = &(rtlpriv->phy); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); enum version_8192c chip_version = VERSION_UNKNOWN; + const char *versionid; u32 value32; value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); @@ -87,62 +88,51 @@ void rtl92c_read_chip_version(struct ieee80211_hw *hw) pr_info("Chip version 0x%x\n", chip_version); switch (rtlhal->version) { case VERSION_NORMAL_TSMC_CHIP_92C_1T2R: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_B_CHIP_92C\n"); + versionid = "NORMAL_B_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_92C\n"); + versionid = "NORMAL_TSMC_CHIP_92C"; break; case VERSION_NORMAL_TSMC_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_TSMC_CHIP_88C\n"); + versionid = "NORMAL_TSMC_CHIP_88C"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_i92C_1T2R_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_i92C_1T2R_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_88C_A_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_1T2R_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_1T2R_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_92C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_92C_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_92C_B_CUT"; break; case VERSION_NORMAL_UMC_CHIP_88C_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMAL_UMC_CHIP_88C_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_88C_B_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_A_CUT\n"); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_A_CUT"; break; case VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_NORMA_UMC_CHIP_8723_1T1R_B_CUT\n"); + versionid = "NORMAL_UMC_CHIP_8723_1T1R_B_CUT"; break; case VERSION_TEST_CHIP_92C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_CHIP_92C\n"); + versionid = "TEST_CHIP_92C"; break; case VERSION_TEST_CHIP_88C: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: VERSION_TEST_CHIP_88C\n"); + versionid = "TEST_CHIP_88C"; break; default: - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Chip Version ID: ???????????????\n"); + versionid = "UNKNOWN"; break; } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "Chip Version ID: %s\n", versionid); + if (IS_92C_SERIAL(rtlhal->version)) rtlphy->rf_type = (IS_92C_1T2R(rtlhal->version)) ? RF_1T2R : RF_2T2R; -- cgit v1.2.3-70-g09d2 From 017664fe8e11ec93dfe3faca5b7ff21071011e6a Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:27 -0800 Subject: iwlwifi: don't process the info from uCode if does not has ownership When enable the testmode from user space and working with uCode, driver does not own the uCode and should not process the notifications or pkts from uCode Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index b22b2976f89..eda95ae88ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1172,20 +1172,22 @@ int iwl_rx_dispatch(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, wake_up_all(&priv->shrd->notif_waitq); } - if (priv->pre_rx_handler) + if (priv->pre_rx_handler && + priv->shrd->ucode_owner == IWL_OWNERSHIP_TM) priv->pre_rx_handler(priv, rxb); - - /* Based on type of command response or notification, - * handle those that need handling via function in - * rx_handlers table. See iwl_setup_rx_handlers() */ - if (priv->rx_handlers[pkt->hdr.cmd]) { - priv->rx_handlers_stats[pkt->hdr.cmd]++; - err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); - } else { - /* No handling needed */ - IWL_DEBUG_RX(priv, - "No handler needed for %s, 0x%02x\n", - get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + else { + /* Based on type of command response or notification, + * handle those that need handling via function in + * rx_handlers table. See iwl_setup_rx_handlers() */ + if (priv->rx_handlers[pkt->hdr.cmd]) { + priv->rx_handlers_stats[pkt->hdr.cmd]++; + err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd); + } else { + /* No handling needed */ + IWL_DEBUG_RX(priv, + "No handler needed for %s, 0x%02x\n", + get_cmd_string(pkt->hdr.cmd), pkt->hdr.cmd); + } } return err; } -- cgit v1.2.3-70-g09d2 From 2da424b0773cea3db47e1e81db71eeebde8269d4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:28 -0800 Subject: iwlwifi: Sanity check for sta_id On my testing, I saw some strange behavior [ 421.739708] iwlwifi 0000:01:00.0: ACTIVATE a non DRIVER active station id 148 addr 00:00:00:00:00:00 [ 421.739719] iwlwifi 0000:01:00.0: iwl_sta_ucode_activate Added STA id 148 addr 00:00:00:00:00:00 to uCode not sure how it happen, but adding the sanity check to prevent memory corruption Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 7353826095f..8d4353a4256 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -35,9 +35,12 @@ #include "iwl-trans.h" /* priv->shrd->sta_lock must be held */ -static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) +static int iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) { - + if (sta_id >= IWLAGN_STATION_COUNT) { + IWL_ERR(priv, "invalid sta_id %u", sta_id); + return -EINVAL; + } if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) IWL_ERR(priv, "ACTIVATE a non DRIVER active station id %u " "addr %pM\n", @@ -53,6 +56,7 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id) IWL_DEBUG_ASSOC(priv, "Added STA id %u addr %pM to uCode\n", sta_id, priv->stations[sta_id].sta.sta.addr); } + return 0; } static int iwl_process_add_sta_resp(struct iwl_priv *priv, @@ -77,8 +81,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, switch (pkt->u.add_sta.status) { case ADD_STA_SUCCESS_MSK: IWL_DEBUG_INFO(priv, "REPLY_ADD_STA PASSED\n"); - iwl_sta_ucode_activate(priv, sta_id); - ret = 0; + ret = iwl_sta_ucode_activate(priv, sta_id); break; case ADD_STA_NO_ROOM_IN_TABLE: IWL_ERR(priv, "Adding station %d failed, no room in table.\n", -- cgit v1.2.3-70-g09d2 From 102f097f1937db41f59674caca0a1e38c963baba Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:29 -0800 Subject: iwlwifi: update testmode command of direct register access In order to make sure the testcommand function of direct register access can be performed even NIC is asleep, replace corresponding handler iwl_read32 and iwl_write32 by using iwl_direct_read32 and iwl_direct_write32. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 4a5cddd2d56..2fc20675dc7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -299,7 +299,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read32(bus(priv), ofs); + val32 = iwl_read_direct32(bus(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -321,7 +321,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write32(bus(priv), ofs, val32); + iwl_write_direct32(bus(priv), ofs, val32); } break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: -- cgit v1.2.3-70-g09d2 From b07f08a56524cdc49001b1467743acc3c5b78962 Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:30 -0800 Subject: iwlwifi: enhance testmode command sram_read This patch enables SRAM read function to support entire target memory. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 7 +++---- drivers/net/wireless/iwlwifi/iwl-testmode.h | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 2fc20675dc7..58575fdc450 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -733,7 +733,7 @@ static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb) static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) { struct iwl_priv *priv = hw->priv; - u32 base, ofs, size, maxsize; + u32 ofs, size, maxsize; if (priv->testmode_sram.sram_readed) return -EBUSY; @@ -765,7 +765,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); return -ENOSYS; } - if ((ofs + size) > maxsize) { + if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) { IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); return -EINVAL; } @@ -776,8 +776,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_DEBUG_INFO(priv, "Error allocating memory\n"); return -ENOMEM; } - base = 0x800000; - _iwl_read_targ_mem_words(bus(priv), base + ofs, + _iwl_read_targ_mem_words(bus(priv), ofs, priv->testmode_sram.buff_addr, priv->testmode_sram.buff_size / 4); priv->testmode_sram.num_chunks = diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 26138f11034..9c6a67ab5c3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -271,4 +271,7 @@ enum iwl_tm_attr_t { /* Maximum data size of each dump it packet */ #define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024) +/* Address offset of data segment in SRAM */ +#define SRAM_DATA_SEG_OFFSET 0x800000 + #endif -- cgit v1.2.3-70-g09d2 From 907781b5c46a1bec51548af2135903017b546924 Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:31 -0800 Subject: iwlwifi: update error dump in testmode command sram_read The error message will be show up by using IWL_ERR insteads of IWl_DEBUG_INFO. Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 58575fdc450..b56cd900805 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -759,21 +759,21 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) maxsize = trans(priv)->ucode_wowlan.data.len; break; case IWL_UCODE_NONE: - IWL_DEBUG_INFO(priv, "Error, uCode does not been loaded\n"); + IWL_ERR(priv, "Error, uCode does not been loaded\n"); return -ENOSYS; default: - IWL_DEBUG_INFO(priv, "Error, unsupported uCode type\n"); + IWL_ERR(priv, "Error, unsupported uCode type\n"); return -ENOSYS; } if ((ofs + size) > (maxsize + SRAM_DATA_SEG_OFFSET)) { - IWL_DEBUG_INFO(priv, "Invalid offset/size: out of range\n"); + IWL_ERR(priv, "Invalid offset/size: out of range\n"); return -EINVAL; } priv->testmode_sram.buff_size = (size / 4) * 4; priv->testmode_sram.buff_addr = kmalloc(priv->testmode_sram.buff_size, GFP_KERNEL); if (priv->testmode_sram.buff_addr == NULL) { - IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + IWL_ERR(priv, "Error allocating memory\n"); return -ENOMEM; } _iwl_read_targ_mem_words(bus(priv), ofs, -- cgit v1.2.3-70-g09d2 From 668bd6a81bd6a3e0c10144201c6f58097de220bf Mon Sep 17 00:00:00 2001 From: Kenny Hsu Date: Fri, 6 Jan 2012 13:16:32 -0800 Subject: iwlwifi: add testmode cmd IWL_TM_CMD_APP2DEV_GET_FW_INFO Add new testmode command IWL_TM_CMD_APP2DEV_GET_FW_INFO for reporting the following information of existing loaded uCode image. + uCode type + Instruction section size + Data section size Signed-off-by: Kenny Hsu Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 41 ++++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-testmode.h | 19 +++++++++++-- 2 files changed, 57 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index b56cd900805..7684c0e2f21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -115,6 +115,9 @@ struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = { [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, }, [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, }, + [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, }, }; /* @@ -422,7 +425,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) struct sk_buff *skb; unsigned char *rsp_data_ptr = NULL; int status = 0, rsp_data_len = 0; - u32 devid; + u32 devid, inst_size = 0, data_size = 0; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_GET_DEVICENAME: @@ -548,6 +551,41 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) "Error sending msg : %d\n", status); break; + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: + skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8); + if (!skb) { + IWL_DEBUG_INFO(priv, "Error allocating memory\n"); + return -ENOMEM; + } + switch (priv->shrd->ucode_type) { + case IWL_UCODE_REGULAR: + inst_size = trans(priv)->ucode_rt.code.len; + data_size = trans(priv)->ucode_rt.data.len; + break; + case IWL_UCODE_INIT: + inst_size = trans(priv)->ucode_init.code.len; + data_size = trans(priv)->ucode_init.data.len; + break; + case IWL_UCODE_WOWLAN: + inst_size = trans(priv)->ucode_wowlan.code.len; + data_size = trans(priv)->ucode_wowlan.data.len; + break; + case IWL_UCODE_NONE: + IWL_DEBUG_INFO(priv, "The uCode has not been loaded\n"); + break; + default: + IWL_DEBUG_INFO(priv, "Unsupported uCode type\n"); + break; + } + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_TYPE, priv->shrd->ucode_type); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size); + NLA_PUT_U32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size); + status = cfg80211_testmode_reply(skb); + if (status < 0) + IWL_DEBUG_INFO(priv, + "Error sending msg : %d\n", status); + break; + default: IWL_DEBUG_INFO(priv, "Unknown testmode driver command ID\n"); return -ENOSYS; @@ -881,6 +919,7 @@ int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len) case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: case IWL_TM_CMD_APP2DEV_GET_FW_VERSION: case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: + case IWL_TM_CMD_APP2DEV_GET_FW_INFO: IWL_DEBUG_INFO(priv, "testmode cmd to driver\n"); result = iwl_testmode_driver(hw, tb); break; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 9c6a67ab5c3..cb0cf35f91b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -120,6 +120,8 @@ * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device + * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: + * retrieve informration of existing loaded uCode image * */ enum iwl_tm_cmd_t { @@ -147,7 +149,8 @@ enum iwl_tm_cmd_t { IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22, IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23, IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24, - IWL_TM_CMD_MAX = 25, + IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25, + IWL_TM_CMD_MAX = 26, }; /* @@ -237,6 +240,15 @@ enum iwl_tm_cmd_t { * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID, * IWL_TM_ATTR_DEVICE_ID for the device ID information * + * @IWL_TM_ATTR_FW_TYPE: + * @IWL_TM_ATTR_FW_INST_SIZE: + * @IWL_TM_ATTR_FW_DATA_SIZE: + * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO, + * The mandatory fields are: + * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...) + * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section + * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section + * */ enum iwl_tm_attr_t { IWL_TM_ATTR_NOT_APPLICABLE = 0, @@ -259,7 +271,10 @@ enum iwl_tm_attr_t { IWL_TM_ATTR_SRAM_DUMP = 17, IWL_TM_ATTR_FW_VERSION = 18, IWL_TM_ATTR_DEVICE_ID = 19, - IWL_TM_ATTR_MAX = 20, + IWL_TM_ATTR_FW_TYPE = 20, + IWL_TM_ATTR_FW_INST_SIZE = 21, + IWL_TM_ATTR_FW_DATA_SIZE = 22, + IWL_TM_ATTR_MAX = 23, }; /* uCode trace buffer */ -- cgit v1.2.3-70-g09d2 From fb4961dbc27d40cdbed297aa9bd74fa4a0e2ba6c Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Fri, 6 Jan 2012 13:16:33 -0800 Subject: iwlwifi: update Copyright Update Copyright to 2012 Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-calib.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-calib.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-hw.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rs.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-rxon.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.h | 2 +- drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-agn.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-bus.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-cfg.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-commands.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-core.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-csr.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-debug.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 2 +- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.c | 2 +- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-eeprom.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-fh.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-io.c | 2 +- drivers/net/wireless/iwlwifi/iwl-io.h | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.h | 2 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-power.h | 2 +- drivers/net/wireless/iwlwifi/iwl-prph.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-scan.c | 2 +- drivers/net/wireless/iwlwifi/iwl-shared.h | 6 +++--- drivers/net/wireless/iwlwifi/iwl-testmode.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-testmode.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-trans.h | 4 ++-- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-wifi.h | 4 ++-- 53 files changed, 75 insertions(+), 75 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 1ef7bfc2ab2..cc04cce1156 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 094693328db..00db092d8cd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index b3a365fea7b..47fd98b3652 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 54b753399e6..ab62c018fcd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c index 50ff849c9f6..6aa00982786 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h index 10275ce92bd..9ed6683314a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h index 123ef5e129d..d0ec0abd3c8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 64cf439035c..a8f7689aaac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 334b5ae8fdd..b9ba404d15c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h index 6675b3c816d..203b1c13c49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index eda95ae88ef..f127f913e5a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portionhelp of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c index 1c665941662..8ca9570ec36 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rxon.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c index 8d4353a4256..d6aab00272b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-sta.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index b0dff7a753a..56c6def015a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h index 7282a23e8f1..86bbf47501c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c index c664c272655..a8c6880af34 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b5c7c5f0a75..7321e7d3140 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index f84fb3c5356..39cbe1a1577 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 940d5038b39..941b9cb2344 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-cfg.h b/drivers/net/wireless/iwlwifi/iwl-cfg.h index e1d78257e4a..957bc00cdaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-cfg.h +++ b/drivers/net/wireless/iwlwifi/iwl-cfg.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 265de39d394..b4779c25a4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7bcfa781e0b..7d6eef96454 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 7bf76ab94dd..63f29111da1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h index fbc3095c7b4..5f96ce105f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-csr.h +++ b/drivers/net/wireless/iwlwifi/iwl-csr.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index f8fc2393dd4..6f7612781e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 04a3343f461..f837f32bb71 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index e54a4d11e58..4579d61da25 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.c b/drivers/net/wireless/iwlwifi/iwl-devtrace.c index 2a2c8de64a0..91f45e71e0a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.c +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9b212a8f30b..4d892211ce4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2009 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index c1eda9724f4..e27d9f55267 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index 9fa937ec35e..13f2d3928ef 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h index 5bede9d7f95..90208094b8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-fh.h +++ b/drivers/net/wireless/iwlwifi/iwl-fh.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index d57ea6484bb..83fdff38115 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index aae2eeb331a..427d065435c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project. * diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 14dcbfcdc0f..eca79087afb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-led.h b/drivers/net/wireless/iwlwifi/iwl-led.h index 2550b3c7dcb..b02a853103d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.h +++ b/drivers/net/wireless/iwlwifi/iwl-led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index f980e574e1f..965d0475aff 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index fb30ea7ca96..03702a2e913 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index 2b188a6025b..c7394ef2e49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h index 5f7b720cf1a..07a19fce5fd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.h +++ b/drivers/net/wireless/iwlwifi/iwl-power.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h index bebdd828f32..a4d11016c3b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-prph.h +++ b/drivers/net/wireless/iwlwifi/iwl-prph.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index a6454726737..2aea20bf0f1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index dc55cc4a810..e406d49f418 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -102,7 +102,7 @@ struct iwl_trans_ops; #define DRV_NAME "iwlwifi" #define IWLWIFI_VERSION "in-tree:" -#define DRV_COPYRIGHT "Copyright(c) 2003-2011 Intel Corporation" +#define DRV_COPYRIGHT "Copyright(c) 2003-2012 Intel Corporation" #define DRV_AUTHOR "" extern struct iwl_mod_params iwlagn_mod_params; diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 7684c0e2f21..a56a77b8f92 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index cb0cf35f91b..185b69ef753 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2010 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2010 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index f6debf91d7b..0ac9b4d3027 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 752493f0040..848c598bfad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index bd29568177e..30814b55705 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2003 - 2012 Intel Corporation. All rights reserved. * * Portions of this file are derived from the ipw3945 project, as well * as portions of the ieee80211 subsystem header files. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 67d6e324e26..5e6af4ba965 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c index 1b20c4fb791..506c062343b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans.c @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index e6bf3f55477..42a9f303f54 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2007 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2007 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 36a1b5b2585..2edf0ef65a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -2,7 +2,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/iwlwifi/iwl-wifi.h b/drivers/net/wireless/iwlwifi/iwl-wifi.h index 18501101a53..7e6eb20823c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-wifi.h +++ b/drivers/net/wireless/iwlwifi/iwl-wifi.h @@ -5,7 +5,7 @@ * * GPL LICENSE SUMMARY * - * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -30,7 +30,7 @@ * * BSD LICENSE * - * Copyright(c) 2005 - 2011 Intel Corporation. All rights reserved. + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without -- cgit v1.2.3-70-g09d2 From 76a92be537f1c8c259e393632301446257ca3ea9 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:40 -0600 Subject: rtlwifi: rtl8192c_common: rtl8192de: Check for allocation failures In https://bugzilla.redhat.com/show_bug.cgi?id=771656, a kernel bug was triggered due to a failed skb allocation that was not checked. This event lead to an audit of all memory allocations in the complete rtlwifi family of drivers. This patch fixes the rest. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 2 ++ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 ++ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 14 +++++++++----- drivers/net/wireless/rtlwifi/usb.c | 12 +++++++----- 4 files changed, 20 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 3c4ae5d9de4..8758b3db072 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -652,6 +652,8 @@ static void _rtl_receive_one(struct ieee80211_hw *hw, struct sk_buff *skb, return; uskb = dev_alloc_skb(skb->len + 128); + if (!uskb) + return; /* exit if allocation failed */ memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, sizeof(rx_status)); pdata = (u8 *)skb_put(uskb, skb->len); memcpy(pdata, skb->data, skb->len); diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 1eae3baae51..e9e9c26d496 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -785,6 +785,8 @@ void rtl92c_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) skb = dev_alloc_skb(totalpacketlen); + if (!skb) + return; memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, totalpacketlen); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index 94f5b7dd06e..da58ca4966c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -756,12 +756,16 @@ void rtl92d_set_fw_rsvdpagepkt(struct ieee80211_hw *hw, bool dl_finished) "rtl92d_set_fw_rsvdpagepkt(): HW_VAR_SET_TX_CMD: ALL", u1RsvdPageLoc, 3); skb = dev_alloc_skb(totalpacketlen); - memcpy((u8 *) skb_put(skb, totalpacketlen), &reserved_page_packet, - totalpacketlen); - rtstatus = _rtl92d_cmd_send_packet(hw, skb); + if (!skb) { + dlok = false; + } else { + memcpy((u8 *) skb_put(skb, totalpacketlen), + &reserved_page_packet, totalpacketlen); + rtstatus = _rtl92d_cmd_send_packet(hw, skb); - if (rtstatus) - dlok = true; + if (rtstatus) + dlok = true; + } if (dlok) { RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Set RSVD page location to Fw\n"); diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 6ae1b212ad9..4db06f6f908 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -520,12 +520,14 @@ static void _rtl_usb_rx_process_noagg(struct ieee80211_hw *hw, u8 *pdata; uskb = dev_alloc_skb(skb->len + 128); - memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, - sizeof(rx_status)); - pdata = (u8 *)skb_put(uskb, skb->len); - memcpy(pdata, skb->data, skb->len); + if (uskb) { /* drop packet on allocation failure */ + memcpy(IEEE80211_SKB_RXCB(uskb), &rx_status, + sizeof(rx_status)); + pdata = (u8 *)skb_put(uskb, skb->len); + memcpy(pdata, skb->data, skb->len); + ieee80211_rx_irqsafe(hw, uskb); + } dev_kfree_skb_any(skb); - ieee80211_rx_irqsafe(hw, uskb); } else { dev_kfree_skb_any(skb); } -- cgit v1.2.3-70-g09d2 From 9ef11f7b34c0896a1d476dd8cb9a18671aaab892 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:41 -0600 Subject: rtl8192cu: Remove dead code never selected The original driver contained some conditional code that was not selected, but was not deleted in case it would be used later. That code can now be removed. Reported-by: Joe Perches Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 170 ---------------------------- 1 file changed, 170 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index ae38bc52a71..b8af2cf4db2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -339,144 +339,8 @@ static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) if (IS_HIGHT_PA(rtlefuse->board_type)) rtlefuse->external_pa = 1; pr_info("Board Type %x\n", rtlefuse->board_type); - -#ifdef CONFIG_ANTENNA_DIVERSITY - /* Antenna Diversity setting. */ - if (registry_par->antdiv_cfg == 2) /* 2: From Efuse */ - rtl_efuse->antenna_cfg = (contents[EEPROM_RF_OPT1]&0x18)>>3; - else - rtl_efuse->antenna_cfg = registry_par->antdiv_cfg; /* 0:OFF, */ - - pr_info("Antenna Config %x\n", rtl_efuse->antenna_cfg); -#endif } -#ifdef CONFIG_BT_COEXIST -static void _update_bt_param(_adapter *padapter) -{ - struct btcoexist_priv *pbtpriv = &(padapter->halpriv.bt_coexist); - struct registry_priv *registry_par = &padapter->registrypriv; - if (2 != registry_par->bt_iso) { - /* 0:Low, 1:High, 2:From Efuse */ - pbtpriv->BT_Ant_isolation = registry_par->bt_iso; - } - if (registry_par->bt_sco == 1) { - /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter, 4.Busy, - * 5.OtherBusy */ - pbtpriv->BT_Service = BT_OtherAction; - } else if (registry_par->bt_sco == 2) { - pbtpriv->BT_Service = BT_SCO; - } else if (registry_par->bt_sco == 4) { - pbtpriv->BT_Service = BT_Busy; - } else if (registry_par->bt_sco == 5) { - pbtpriv->BT_Service = BT_OtherBusy; - } else { - pbtpriv->BT_Service = BT_Idle; - } - pbtpriv->BT_Ampdu = registry_par->bt_ampdu; - pbtpriv->bCOBT = _TRUE; - pbtpriv->BtEdcaUL = 0; - pbtpriv->BtEdcaDL = 0; - pbtpriv->BtRssiState = 0xff; - pbtpriv->bInitSet = _FALSE; - pbtpriv->bBTBusyTraffic = _FALSE; - pbtpriv->bBTTrafficModeSet = _FALSE; - pbtpriv->bBTNonTrafficModeSet = _FALSE; - pbtpriv->CurrentState = 0; - pbtpriv->PreviousState = 0; - pr_info("BT Coexistance = %s\n", - (pbtpriv->BT_Coexist == _TRUE) ? "enable" : "disable"); - if (pbtpriv->BT_Coexist) { - if (pbtpriv->BT_Ant_Num == Ant_x2) - pr_info("BlueTooth BT_Ant_Num = Antx2\n"); - else if (pbtpriv->BT_Ant_Num == Ant_x1) - pr_info("BlueTooth BT_Ant_Num = Antx1\n"); - switch (pbtpriv->BT_CoexistType) { - case BT_2Wire: - pr_info("BlueTooth BT_CoexistType = BT_2Wire\n"); - break; - case BT_ISSC_3Wire: - pr_info("BlueTooth BT_CoexistType = BT_ISSC_3Wire\n"); - break; - case BT_Accel: - pr_info("BlueTooth BT_CoexistType = BT_Accel\n"); - break; - case BT_CSR_BC4: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC4\n"); - break; - case BT_CSR_BC8: - pr_info("BlueTooth BT_CoexistType = BT_CSR_BC8\n"); - break; - case BT_RTL8756: - pr_info("BlueTooth BT_CoexistType = BT_RTL8756\n"); - break; - default: - pr_info("BlueTooth BT_CoexistType = Unknown\n"); - break; - } - pr_info("BlueTooth BT_Ant_isolation = %d\n", - pbtpriv->BT_Ant_isolation); - switch (pbtpriv->BT_Service) { - case BT_OtherAction: - pr_info("BlueTooth BT_Service = BT_OtherAction\n"); - break; - case BT_SCO: - pr_info("BlueTooth BT_Service = BT_SCO\n"); - break; - case BT_Busy: - pr_info("BlueTooth BT_Service = BT_Busy\n"); - break; - case BT_OtherBusy: - pr_info("BlueTooth BT_Service = BT_OtherBusy\n"); - break; - default: - pr_info("BlueTooth BT_Service = BT_Idle\n"); - break; - } - pr_info("BT_RadioSharedType = 0x%x\n", - pbtpriv->BT_RadioSharedType); - } -} - -#define GET_BT_COEXIST(priv) (&priv->bt_coexist) - -static void _rtl92cu_read_bluetooth_coexistInfo(struct ieee80211_hw *hw, - u8 *contents, - bool bautoloadfailed); -{ - HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter); - bool isNormal = IS_NORMAL_CHIP(pHalData->VersionID); - struct btcoexist_priv *pbtpriv = &pHalData->bt_coexist; - u8 rf_opt4; - - _rtw_memset(pbtpriv, 0, sizeof(struct btcoexist_priv)); - if (AutoloadFail) { - pbtpriv->BT_Coexist = _FALSE; - pbtpriv->BT_CoexistType = BT_2Wire; - pbtpriv->BT_Ant_Num = Ant_x2; - pbtpriv->BT_Ant_isolation = 0; - pbtpriv->BT_RadioSharedType = BT_Radio_Shared; - return; - } - if (isNormal) { - if (pHalData->BoardType == BOARD_USB_COMBO) - pbtpriv->BT_Coexist = _TRUE; - else - pbtpriv->BT_Coexist = ((PROMContent[EEPROM_RF_OPT3] & - 0x20) >> 5); /* bit[5] */ - rf_opt4 = PROMContent[EEPROM_RF_OPT4]; - pbtpriv->BT_CoexistType = ((rf_opt4&0xe)>>1); /* bit [3:1] */ - pbtpriv->BT_Ant_Num = (rf_opt4&0x1); /* bit [0] */ - pbtpriv->BT_Ant_isolation = ((rf_opt4&0x10)>>4); /* bit [4] */ - pbtpriv->BT_RadioSharedType = ((rf_opt4&0x20)>>5); /* bit [5] */ - } else { - pbtpriv->BT_Coexist = (PROMContent[EEPROM_RF_OPT4] >> 4) ? - _TRUE : _FALSE; - } - _update_bt_param(Adapter); -} -#endif - static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -552,10 +416,6 @@ static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) } } _rtl92cu_read_board_type(hw, hwinfo); -#ifdef CONFIG_BT_COEXIST - _rtl92cu_read_bluetooth_coexistInfo(hw, hwinfo, - rtlefuse->autoload_failflag); -#endif } static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) @@ -1107,34 +967,6 @@ static void _InitPABias(struct ieee80211_hw *hw) } } -static void _InitAntenna_Selection(struct ieee80211_hw *hw) -{ -#ifdef CONFIG_ANTENNA_DIVERSITY - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (pHalData->AntDivCfg == 0) - return; - - if (rtlphy->rf_type == RF_1T1R) { - rtl_write_dword(rtlpriv, REG_LEDCFG0, - rtl_read_dword(rtlpriv, - REG_LEDCFG0)|BIT(23)); - rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - if (rtl_get_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300) == - Antenna_A) - pHalData->CurAntenna = Antenna_A; - else - pHalData->CurAntenna = Antenna_B; - } -#endif -} - -static void _dump_registers(struct ieee80211_hw *hw) -{ -} - static void _update_mac_setting(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -1205,10 +1037,8 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) } _rtl92cu_hw_configure(hw); _InitPABias(hw); - _InitAntenna_Selection(hw); _update_mac_setting(hw); rtl92c_dm_init(hw); - _dump_registers(hw); return err; } -- cgit v1.2.3-70-g09d2 From a8d760668eebc98915383481cb3d9eaf74c2a615 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:42 -0600 Subject: rtlwifi: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 2 +- drivers/net/wireless/rtlwifi/base.h | 2 +- drivers/net/wireless/rtlwifi/cam.c | 2 +- drivers/net/wireless/rtlwifi/cam.h | 2 +- drivers/net/wireless/rtlwifi/core.c | 2 +- drivers/net/wireless/rtlwifi/core.h | 2 +- drivers/net/wireless/rtlwifi/debug.c | 2 +- drivers/net/wireless/rtlwifi/debug.h | 2 +- drivers/net/wireless/rtlwifi/efuse.c | 2 +- drivers/net/wireless/rtlwifi/efuse.h | 2 +- drivers/net/wireless/rtlwifi/pci.c | 2 +- drivers/net/wireless/rtlwifi/pci.h | 2 +- drivers/net/wireless/rtlwifi/ps.c | 2 +- drivers/net/wireless/rtlwifi/ps.h | 2 +- drivers/net/wireless/rtlwifi/rc.c | 2 +- drivers/net/wireless/rtlwifi/rc.h | 2 +- drivers/net/wireless/rtlwifi/regd.c | 2 +- drivers/net/wireless/rtlwifi/regd.h | 2 +- drivers/net/wireless/rtlwifi/usb.c | 2 +- drivers/net/wireless/rtlwifi/usb.h | 2 +- drivers/net/wireless/rtlwifi/wifi.h | 2 +- 21 files changed, 21 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index fa16b1d708f..6f80142580f 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h index f66b5757f6b..5a23a6d0f49 100644 --- a/drivers/net/wireless/rtlwifi/base.h +++ b/drivers/net/wireless/rtlwifi/base.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index cbf5e3cdb44..8fd820d85ee 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/cam.h b/drivers/net/wireless/rtlwifi/cam.h index c62da4eefc7..35e00086a52 100644 --- a/drivers/net/wireless/rtlwifi/cam.h +++ b/drivers/net/wireless/rtlwifi/cam.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index ab6a4068764..d6e37e6a1d5 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index f02824a3b74..a45c3892e36 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 1b5cb7153a5..67dcbcdfaa7 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h index fd5600c6942..07493d2957f 100644 --- a/drivers/net/wireless/rtlwifi/debug.h +++ b/drivers/net/wireless/rtlwifi/debug.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/efuse.c b/drivers/net/wireless/rtlwifi/efuse.c index a079a31b4ed..b24cbe6e16d 100644 --- a/drivers/net/wireless/rtlwifi/efuse.c +++ b/drivers/net/wireless/rtlwifi/efuse.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * Tmis program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/efuse.h b/drivers/net/wireless/rtlwifi/efuse.h index 164dabaa761..2bdea9a8699 100644 --- a/drivers/net/wireless/rtlwifi/efuse.h +++ b/drivers/net/wireless/rtlwifi/efuse.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 8758b3db072..4326fd1e319 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index ebe0b42c051..99d81ede17b 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index a36dc3d5e04..b151266ef9f 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/ps.h b/drivers/net/wireless/rtlwifi/ps.h index 84628e6041c..1357856998c 100644 --- a/drivers/net/wireless/rtlwifi/ps.h +++ b/drivers/net/wireless/rtlwifi/ps.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rc.c b/drivers/net/wireless/rtlwifi/rc.c index 4f560d6a386..c66f08a0524 100644 --- a/drivers/net/wireless/rtlwifi/rc.c +++ b/drivers/net/wireless/rtlwifi/rc.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rc.h b/drivers/net/wireless/rtlwifi/rc.h index 4afa2c20adc..4d617616061 100644 --- a/drivers/net/wireless/rtlwifi/rc.h +++ b/drivers/net/wireless/rtlwifi/rc.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/regd.c b/drivers/net/wireless/rtlwifi/regd.c index c263df21760..c1608cddc52 100644 --- a/drivers/net/wireless/rtlwifi/regd.c +++ b/drivers/net/wireless/rtlwifi/regd.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/regd.h b/drivers/net/wireless/rtlwifi/regd.h index d23118938fa..70ef2f418a4 100644 --- a/drivers/net/wireless/rtlwifi/regd.h +++ b/drivers/net/wireless/rtlwifi/regd.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 4db06f6f908..78194e30fcd 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index d2a63fb3e1e..cdad7c2507e 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2011 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index cdaf1429fa0..b2d98548500 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From fc6168563aeb26cbc9a9ba9dd168cfdabc6f3778 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:43 -0600 Subject: rtl8192c_common: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/main.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c index bf94cbfb4e3..cb5535cf3ae 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h index b9736d3e9a3..2178e376188 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index e9e9c26d496..75be221fde4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h index cec5a3a1cc5..780ea5b1e24 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c index 605ff191aeb..8ae65b57612 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c index 25bde968699..22e998dd2f3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h index 9a264c0d612..cec10d69649 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 9003a4aba4b040be265ce8ed51f6fe437d369453 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:44 -0600 Subject: rtl8192ce: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192ce/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/trx.h | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h index 9fc804d89d6..04c3aef8a4f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c index 6730e683aba..27b3af880d9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h index 07dd9552e82..26747fa8600 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index 971bd29ef9b..c5aced459cd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h index 07dbe3e340a..52a3aea9b3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c index 09758f48d3e..8283e9b2763 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h index 7dfccea2095..c5761066d38 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 03ee82e05f2..c64daf25566 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h index be2c92adef3..d5e3b704f93 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h index ba5ff0411f0..43806d9d1e1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c index 5ef960499a4..69d720dd9c3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h index 39ff0368598..6c8d56efcea 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 4a224dbc693..7e59b689bff 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h index b7dc3263e43..d2367a5d0cf 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c index ba938b91aa6..752f943a84a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h index 3a6e8b6aeee..8b79161f71b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c index 46892cc1a08..37b13636a77 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h index c8977a50ca3..efb9ab27040 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From c1d6604d1e3357d734d209a04cc1f80af948364b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:45 -0600 Subject: rtl8192cu: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/mac.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192cu/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h index d097efb1e71..f916555e631 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c index c0016f3194e..6fd39eaf361 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h index 7f966c666b5..d947e7d350b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index b8af2cf4db2..edb52987f5e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h index 32f85cba106..f41a3aa4a26 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c index 65fd0442462..75a2deb23af 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h index decaee4d1eb..0f372278b7a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index 060ed5fec69..d028f6f2199 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h index 626d88e88e2..bf53652e4ed 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c index e7ea2bae210..8ac3bcca4d4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h index ff81a61729d..42b06866048 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h index 7f1be614c99..8b81465c629 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c index e132cb30a30..780c0d98a83 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h index 500a2094b6b..090fd33a158 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index dee7aab4faa..aec8cae733a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h index 43b1177924a..a1310abd0d5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c index d57ef5e88a9..966be519edb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h index c3d5cd826cf..4b020e9e30b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c index 7d5f79991f8..21bc827c5fa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h index 53de5f66e24..332b06e78b0 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2009-2012 Realtek Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 6a57b08e222f4e054a7e7160ef7426c5614c0cc0 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:46 -0600 Subject: rtl8192de: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192de/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/fw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192de/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/def.h b/drivers/net/wireless/rtlwifi/rtl8192de/def.h index 94630477174..eafdf76ed64 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c index 32537c4faf9..181ed6fc90e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h index 69354657f0f..91030ec8ac3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index da58ca4966c..b59de75a364 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h index 0c4d489eaa4..1ffacdda734 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index d94ce371572..695bccb4375 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h index ad44ffa520e..7c9f7a2f1e4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.c b/drivers/net/wireless/rtlwifi/rtl8192de/led.c index f2358f20b9c..76a57ae4af3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/led.h b/drivers/net/wireless/rtlwifi/rtl8192de/led.h index 57f4a3c583d..a29df30c302 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c index f27acc75494..9581a19c254 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h index a52c824b41e..f074952bf25 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h index 131acc306fc..9bc46233107 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c index 2e174f48946..ff34d2dd39b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h index 74b9cfc39a8..0fe1a48593e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index 364aa402245..b8d7fe39e5a 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h index c95e47de134..0e6035b8fd8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.c b/drivers/net/wireless/rtlwifi/rtl8192de/table.c index bad7f9449ec..8ea6f528dfa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/table.h b/drivers/net/wireless/rtlwifi/rtl8192de/table.h index 93f30ca62d8..8b724a86117 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/table.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c index e7c985b372f..a7f6126e2f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h index 4d55d0b6816..0dc736c2723 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192de/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From ca742cd9766ff519b0e927a9296e29541ee13c7b Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sat, 7 Jan 2012 20:46:47 -0600 Subject: rtl8192se: Update copyright dates Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192se/def.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/dm.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/fw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/led.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/phy.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/reg.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/rf.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/table.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/table.h | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/trx.h | 2 +- 20 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/def.h b/drivers/net/wireless/rtlwifi/rtl8192se/def.h index c6c044816d3..d1b0a1e1497 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/def.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/def.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c index 4a5e3a952a4..fbabae17259 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h index 9051a556acc..e1b19a64176 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/dm.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/dm.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 2a9699feee3..595ecd22ffa 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h index 74cc503efe8..babe85d4b69 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index b03001b2328..625c9eb0a11 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h index 6160a9bfe98..1886c2644a2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index 1a6b0caf084..ef4211bca58 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.h b/drivers/net/wireless/rtlwifi/rtl8192se/led.h index 8cce3870af3..2182dbeb5f3 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index e24dbb3a9ba..adfac569b67 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h index 37e504af644..ac038777063 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h index 11f125c030c..84d1181795b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/reg.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/reg.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 8966b731f7e..46be4cc8ba9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h index 3843baa1a87..8a29eb94ab1 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 5795a542bdf..3bc0128deea 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h index fc4eb285a0a..2eb88862ebe 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.c b/drivers/net/wireless/rtlwifi/rtl8192se/table.c index 154185b3969..f1a73f75127 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/table.h b/drivers/net/wireless/rtlwifi/rtl8192se/table.h index b4ed6d951eb..2feb73b71a4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/table.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/table.h @@ -1,5 +1,5 @@ /****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * Copyright(c) 2008 - 2012 Realtek Corporation. All rights reserved. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 216a3e140de..2fd3d13b7ce 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h index 05862c51b86..011e7b0695f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.h +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright(c) 2009-2010 Realtek Corporation. + * Copyright(c) 2009-2012 Realtek Corporation. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as -- cgit v1.2.3-70-g09d2 From 75ac9a28a0c6b818ba1aba874b6b3ae17241552c Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Mon, 9 Jan 2012 10:40:50 +0100 Subject: drivers/net/wireless/mwifiex/scan.c: convert GFP_KERNEL to GFP_ATOMIC The function is called with locks held and thus should not use GFP_KERNEL. The semantic patch that makes this report is available in scripts/coccinelle/locks/call_kern.cocci. More information about semantic patching is available at http://coccinelle.lip6.fr/ Signed-off-by: Julia Lawall Acked-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 6396d3318ea..98f1ca9cd6d 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -2001,7 +2001,7 @@ mwifiex_save_curr_bcn(struct mwifiex_private *priv) kfree(priv->curr_bcn_buf); priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size, - GFP_KERNEL); + GFP_ATOMIC); if (!priv->curr_bcn_buf) { dev_err(priv->adapter->dev, "failed to alloc curr_bcn_buf\n"); -- cgit v1.2.3-70-g09d2 From e2d75c136f8df4a4e28ece75c475a65b9292729a Mon Sep 17 00:00:00 2001 From: Nicolas Cavallari Date: Wed, 11 Jan 2012 16:44:50 +0100 Subject: carl9170: claim to support IBSS RSN. On carl9170, HW encryption is disabled on IBSS; the mac80211 software-based encryption is used instead. As mac80211 supports IBSS RSN (per-STA GTK), claim its support in the carl9170 PHY. Signed-off-by: Nicolas Cavallari Acked-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index db774212161..4dfb0290b43 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1796,6 +1796,9 @@ void *carl9170_alloc(size_t priv_size) ar->noise[i] = -95; /* ATH_DEFAULT_NOISE_FLOOR */ hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + + /* As IBSS Encryption is software-based, IBSS RSN is supported. */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; return ar; err_nomem: -- cgit v1.2.3-70-g09d2 From cebcab9e18725d8249f607af787ee92107a665b7 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 11 Jan 2012 14:39:32 -0600 Subject: bcma: Enable logging of SPROM offset The SPROM location has been relocated again for some devices. This patch will log the offset when CONFIG_BCMA_DEBUG has been selected. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/bcma/sprom.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c index cb835f026d9..e35134f724f 100644 --- a/drivers/bcma/sprom.c +++ b/drivers/bcma/sprom.c @@ -271,6 +271,7 @@ int bcma_sprom_get(struct bcma_bus *bus) * TODO: understand this condition and use it */ offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : BCMA_CC_SPROM_PCIE6; + pr_debug("SPROM offset 0x%x\n", offset); bcma_sprom_read(bus, offset, sprom); if (bus->chipinfo.id == 0x4331) -- cgit v1.2.3-70-g09d2 From 9da9a3b29ba6a9a98e437f24576f13cbe259997b Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 11 Jan 2012 20:06:11 -0800 Subject: mwifiex: use bss_type and bss_num to retrieve priv Current implementation, for retrieving priv from adapter, uses bss_index. In multi interface environment supporting different types, bss_index may not be unique. Use bss_type along with bss_num to retrieve the priv. bss_index is removed with this change. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Kiran Divekar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/11n_aggr.c | 3 ++- drivers/net/wireless/mwifiex/cfg80211.c | 1 - drivers/net/wireless/mwifiex/cmdevt.c | 3 ++- drivers/net/wireless/mwifiex/decl.h | 6 ++++-- drivers/net/wireless/mwifiex/init.c | 5 +++-- drivers/net/wireless/mwifiex/main.c | 23 ++++++----------------- drivers/net/wireless/mwifiex/main.h | 3 --- drivers/net/wireless/mwifiex/sta_rx.c | 6 ++++-- drivers/net/wireless/mwifiex/sta_tx.c | 3 ++- drivers/net/wireless/mwifiex/txrx.c | 6 ++++-- drivers/net/wireless/mwifiex/util.c | 3 ++- drivers/net/wireless/mwifiex/wmm.c | 3 ++- 12 files changed, 31 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c index 079e5532e68..ea6832dc667 100644 --- a/drivers/net/wireless/mwifiex/11n_aggr.c +++ b/drivers/net/wireless/mwifiex/11n_aggr.c @@ -182,7 +182,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv, skb_reserve(skb_aggr, headroom + sizeof(struct txpd)); tx_info_aggr = MWIFIEX_SKB_TXCB(skb_aggr); - tx_info_aggr->bss_index = tx_info_src->bss_index; + tx_info_aggr->bss_type = tx_info_src->bss_type; + tx_info_aggr->bss_num = tx_info_src->bss_num; skb_aggr->priority = skb_src->priority; do { diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index c3b6c4652cd..36f67da8fa4 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -1217,7 +1217,6 @@ struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy, priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II; priv->bss_priority = 0; priv->bss_role = MWIFIEX_BSS_ROLE_STA; - priv->bss_index = 0; priv->bss_num = 0; break; diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 6e0a3eaecf7..6623db69e15 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -391,7 +391,8 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) if (skb) { rx_info = MWIFIEX_SKB_RXCB(skb); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; } if (eventcause != EVENT_PS_SLEEP && eventcause != EVENT_PS_AWAKE) { diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h index ae17ce02a3d..3735c775495 100644 --- a/drivers/net/wireless/mwifiex/decl.h +++ b/drivers/net/wireless/mwifiex/decl.h @@ -102,7 +102,8 @@ struct mwifiex_wait_queue { }; struct mwifiex_rxinfo { - u8 bss_index; + u8 bss_num; + u8 bss_type; struct sk_buff *parent; u8 use_count; }; @@ -110,7 +111,8 @@ struct mwifiex_rxinfo { struct mwifiex_txinfo { u32 status_code; u8 flags; - u8 bss_index; + u8 bss_num; + u8 bss_type; }; enum mwifiex_wmm_ac_e { diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e05b417a3fa..e13b6d99171 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -526,8 +526,9 @@ static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv) cur = &adapter->bss_prio_tbl[i].bss_prio_cur; lock = &adapter->bss_prio_tbl[i].bss_prio_lock; dev_dbg(adapter->dev, "info: delete BSS priority table," - " index = %d, i = %d, head = %p, cur = %p\n", - priv->bss_index, i, head, *cur); + " bss_type = %d, bss_num = %d, i = %d," + " head = %p, cur = %p\n", + priv->bss_type, priv->bss_num, i, head, *cur); if (*cur) { spin_lock_irqsave(lock, flags); if (list_empty(head)) { diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 84be196188c..1a0775d19ad 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -424,8 +424,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) struct sk_buff *new_skb; struct mwifiex_txinfo *tx_info; - dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n", - jiffies, priv->bss_index); + dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n", + jiffies, priv->bss_type, priv->bss_num); if (priv->adapter->surprise_removed) { kfree_skb(skb); @@ -458,7 +458,8 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) } tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; mwifiex_fill_buffer(skb); mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); @@ -531,8 +532,8 @@ mwifiex_tx_timeout(struct net_device *dev) { struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); - dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n", - jiffies, priv->bss_index); + dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n", + jiffies, priv->bss_type, priv->bss_num); mwifiex_set_trans_start(dev); priv->num_tx_timeout++; } @@ -604,18 +605,6 @@ int is_command_pending(struct mwifiex_adapter *adapter) return !is_cmd_pend_q_empty; } -/* - * This function returns the correct private structure pointer based - * upon the BSS number. - */ -struct mwifiex_private * -mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index) -{ - if (!adapter || (bss_index >= adapter->priv_num)) - return NULL; - return adapter->priv[bss_index]; -} - /* * This is the main work queue function. * diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 3186aa437f4..6712ea89ef7 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -352,7 +352,6 @@ struct mwifiex_private; struct mwifiex_private { struct mwifiex_adapter *adapter; - u8 bss_index; u8 bss_type; u8 bss_role; u8 bss_priority; @@ -884,8 +883,6 @@ mwifiex_netdev_get_priv(struct net_device *dev) return (struct mwifiex_private *) (*(unsigned long *) netdev_priv(dev)); } -struct mwifiex_private *mwifiex_bss_index_to_priv(struct mwifiex_adapter - *adapter, u8 bss_index); int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, u32 func_init_shutdown); int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); diff --git a/drivers/net/wireless/mwifiex/sta_rx.c b/drivers/net/wireless/mwifiex/sta_rx.c index 5e1ef7e5da4..d7a5d7616f2 100644 --- a/drivers/net/wireless/mwifiex/sta_rx.c +++ b/drivers/net/wireless/mwifiex/sta_rx.c @@ -43,7 +43,8 @@ int mwifiex_process_rx_packet(struct mwifiex_adapter *adapter, { int ret; struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb); - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + rx_info->bss_num, rx_info->bss_type); struct rx_packet_hdr *rx_pkt_hdr; struct rxpd *local_rx_pd; int hdr_chop; @@ -124,7 +125,8 @@ int mwifiex_process_sta_rx_packet(struct mwifiex_adapter *adapter, struct rx_packet_hdr *rx_pkt_hdr; u8 ta[ETH_ALEN]; u16 rx_pkt_type; - struct mwifiex_private *priv = adapter->priv[rx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + rx_info->bss_num, rx_info->bss_type); if (!priv) return -1; diff --git a/drivers/net/wireless/mwifiex/sta_tx.c b/drivers/net/wireless/mwifiex/sta_tx.c index d97facd70e8..94d31a94620 100644 --- a/drivers/net/wireless/mwifiex/sta_tx.c +++ b/drivers/net/wireless/mwifiex/sta_tx.c @@ -136,7 +136,8 @@ int mwifiex_send_null_packet(struct mwifiex_private *priv, u8 flags) return -1; tx_info = MWIFIEX_SKB_TXCB(skb); - tx_info->bss_index = priv->bss_index; + tx_info->bss_num = priv->bss_num; + tx_info->bss_type = priv->bss_type; skb_reserve(skb, sizeof(struct txpd) + INTF_HEADER_LEN); skb_push(skb, sizeof(struct txpd)); diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c index d9274a1b77a..9a6eacc9d6f 100644 --- a/drivers/net/wireless/mwifiex/txrx.c +++ b/drivers/net/wireless/mwifiex/txrx.c @@ -48,7 +48,8 @@ int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter, if (!priv) priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY); - rx_info->bss_index = priv->bss_index; + rx_info->bss_num = priv->bss_num; + rx_info->bss_type = priv->bss_type; return mwifiex_process_sta_rx_packet(adapter, skb); } @@ -130,7 +131,8 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter, return 0; tx_info = MWIFIEX_SKB_TXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, tx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num, + tx_info->bss_type); if (!priv) goto done; diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c index 06976f517f6..9c48f37069f 100644 --- a/drivers/net/wireless/mwifiex/util.c +++ b/drivers/net/wireless/mwifiex/util.c @@ -159,7 +159,8 @@ int mwifiex_recv_packet(struct mwifiex_adapter *adapter, struct sk_buff *skb) return -1; rx_info = MWIFIEX_SKB_RXCB(skb); - priv = mwifiex_bss_index_to_priv(adapter, rx_info->bss_index); + priv = mwifiex_get_priv_by_id(adapter, rx_info->bss_num, + rx_info->bss_type); if (!priv) return -1; diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index 6c239c3c824..e6a2cb127d2 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -603,7 +603,8 @@ mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, struct sk_buff *skb) { struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - struct mwifiex_private *priv = adapter->priv[tx_info->bss_index]; + struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, + tx_info->bss_num, tx_info->bss_type); u32 tid; struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; -- cgit v1.2.3-70-g09d2 From f540f9f34b35d3c8a1d4b8d47ad5f00da951bfe7 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Wed, 11 Jan 2012 20:06:12 -0800 Subject: mwifiex: derive priv from net_device instead of wiphy Currently mwifiex_private pointers are derived from wiphy structures. This will always work as long as there is only one net_device associated with one wiphy. In scenarios where there are multiple net_devices associated with single wiphy, one should use net_device to derive the priv. Signed-off-by: Yogesh Ashok Powar Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 36f67da8fa4..00f10059ecb 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -79,7 +79,7 @@ static int mwifiex_cfg80211_del_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, NULL, 0, key_index, 1)) { wiphy_err(wiphy, "deleting the crypto keys\n"); @@ -122,7 +122,7 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, int timeout) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); u32 ps_mode; if (timeout) @@ -143,7 +143,7 @@ mwifiex_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool unicast, bool multicast) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); /* Return if WEP key not configured */ if (priv->sec_info.wep_status == MWIFIEX_802_11_WEP_DISABLED) @@ -165,7 +165,7 @@ mwifiex_cfg80211_add_key(struct wiphy *wiphy, struct net_device *netdev, u8 key_index, bool pairwise, const u8 *mac_addr, struct key_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(netdev); if (mwifiex_set_encode(priv, params->key, params->key_len, key_index, 0)) { @@ -376,7 +376,7 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); if (priv->media_connected) { wiphy_err(wiphy, "This setting is valid only when station " @@ -1004,7 +1004,7 @@ static int mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_ibss_params *params) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); int ret = 0; if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { @@ -1042,7 +1042,7 @@ done: static int mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", priv->cfg_bssid); @@ -1280,10 +1280,7 @@ EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf); */ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) { - struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); - - if (!priv || !dev) - return 0; + struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); #ifdef CONFIG_DEBUG_FS mwifiex_dev_debugfs_remove(priv); -- cgit v1.2.3-70-g09d2 From 6ae4bb6612c675d4132bd4fcc7cac4eef46f9624 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Fri, 13 Jan 2012 16:35:05 +0100 Subject: carl9170: remove eeprom data injection option In the early days, this was a quite useful software feature for testing different regdomains and chain configurations without adding debugfs cruft into the driver. Nowadays, the driver's phy code seems to be stable and there's no need for it anymore. Therefore I decided to removed altogether. Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 - drivers/net/wireless/ath/carl9170/fw.c | 33 ---------------------------- drivers/net/wireless/ath/carl9170/main.c | 4 ---- 3 files changed, 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 6cfbb419e2f..f0f44c30b2f 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -593,7 +593,6 @@ int carl9170_get_noisefloor(struct ar9170 *ar); /* FW */ int carl9170_parse_firmware(struct ar9170 *ar); -int carl9170_fw_fix_eeprom(struct ar9170 *ar); extern struct ieee80211_rate __carl9170_ratetable[]; extern int modparam_noht; diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index 3de61adacd3..cffde8d9a52 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c @@ -389,39 +389,6 @@ carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len) return (void *)&fw_data[scan - found]; } -int carl9170_fw_fix_eeprom(struct ar9170 *ar) -{ - const struct carl9170fw_fix_desc *fix_desc = NULL; - unsigned int i, n, off; - u32 *data = (void *)&ar->eeprom; - - fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC, - sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER); - - if (!fix_desc) - return 0; - - n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) / - sizeof(struct carl9170fw_fix_entry); - - for (i = 0; i < n; i++) { - off = le32_to_cpu(fix_desc->data[i].address) - - AR9170_EEPROM_START; - - if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) { - dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i); - continue; - } - - data[off / sizeof(*data)] &= - le32_to_cpu(fix_desc->data[i].mask); - data[off / sizeof(*data)] |= - le32_to_cpu(fix_desc->data[i].value); - } - - return 0; -} - int carl9170_parse_firmware(struct ar9170 *ar) { const struct carl9170fw_desc_head *fw_desc = NULL; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 4dfb0290b43..6ee7c55f75a 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1934,10 +1934,6 @@ int carl9170_register(struct ar9170 *ar) if (err) return err; - err = carl9170_fw_fix_eeprom(ar); - if (err) - return err; - err = carl9170_parse_eeprom(ar); if (err) return err; -- cgit v1.2.3-70-g09d2 From f99725777e0f57e71f37191eee5f10071ed7b423 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Sat, 14 Jan 2012 11:42:43 +0100 Subject: ath5k: claim support for IBSS RSN Disable group keys programming when using IBSS RSN. Keys will be managed using software. In this way IBSS RSN can correctly work. Signed-off-by: Antonio Quartulli Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 3 +++ drivers/net/wireless/ath/ath5k/mac80211-ops.c | 8 ++++++++ 2 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index d366dadcf86..4ab835f08a4 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2442,6 +2442,9 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_MESH_POINT); + /* SW support for IBSS_RSN is provided by mac80211 */ + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 6ed4c0717e3..af4c7ecb4b3 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -483,6 +483,14 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; + if (vif->type == NL80211_IFTYPE_ADHOC && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* don't program group keys when using IBSS_RSN */ + return -EOPNOTSUPP; + } + switch (key->cipher) { case WLAN_CIPHER_SUITE_WEP40: case WLAN_CIPHER_SUITE_WEP104: -- cgit v1.2.3-70-g09d2 From 8ae746543c8370fd04c28aaf8f185c1687b0e694 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:38 -0800 Subject: brcm80211: Use normal DEBUG define Current CONFIG_BRCMDBG flag when enabled does not necessarily enable proper pr_debug output when DEBUG is not also enabled. Remove BCMDBG define and just use DEBUG instead. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/Makefile | 2 +- drivers/net/wireless/brcm80211/brcmfmac/dhd.h | 4 +- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 10 +-- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 6 +- .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 86 +++++++++++----------- .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 6 +- drivers/net/wireless/brcm80211/brcmsmac/aiutils.c | 4 +- drivers/net/wireless/brcm80211/brcmsmac/ampdu.c | 2 +- drivers/net/wireless/brcm80211/brcmsmac/dma.c | 8 +- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 18 ++--- .../net/wireless/brcm80211/brcmsmac/mac80211_if.h | 2 +- drivers/net/wireless/brcm80211/brcmsmac/main.c | 42 +++++------ drivers/net/wireless/brcm80211/brcmsmac/main.h | 2 +- drivers/net/wireless/brcm80211/brcmutil/utils.c | 4 +- .../net/wireless/brcm80211/include/brcmu_utils.h | 4 +- 16 files changed, 102 insertions(+), 102 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/Makefile b/drivers/net/wireless/brcm80211/Makefile index f41c047eca8..b987920e982 100644 --- a/drivers/net/wireless/brcm80211/Makefile +++ b/drivers/net/wireless/brcm80211/Makefile @@ -16,7 +16,7 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # common flags -subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG +subdir-ccflags-$(CONFIG_BRCMDBG) += -DDEBUG obj-$(CONFIG_BRCMUTIL) += brcmutil/ obj-$(CONFIG_BRCMFMAC) += brcmfmac/ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h index e58ea40a75b..07686a748d3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h @@ -644,9 +644,9 @@ extern char *brcmf_ifname(struct brcmf_pub *drvr, int idx); extern int brcmf_proto_cdc_query_dcmd(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf, uint len); -#ifdef BCMDBG +#ifdef DEBUG extern int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size); -#endif /* BCMDBG */ +#endif /* DEBUG */ extern int brcmf_ifname2idx(struct brcmf_pub *drvr, char *name); extern int brcmf_c_host_event(struct brcmf_pub *drvr, int *idx, diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index a51d8f5d36f..9385c84646e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -38,7 +38,7 @@ #define BRCMF_PKT_FILTER_PATTERN_FIXED_LEN \ offsetof(struct brcmf_pkt_filter_pattern_le, mask_and_pattern) -#ifdef BCMDBG +#ifdef DEBUG static const char brcmf_version[] = "Dongle Host Driver, version " BRCMF_VERSION_STR "\nCompiled on " __DATE__ " at " __TIME__; @@ -133,7 +133,7 @@ bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, return p != NULL; } -#ifdef BCMDBG +#ifdef DEBUG static void brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) { @@ -430,7 +430,7 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) brcmf_dbg(EVENT, "\n"); } } -#endif /* BCMDBG */ +#endif /* DEBUG */ int brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, @@ -518,9 +518,9 @@ brcmf_c_host_event(struct brcmf_pub *drvr, int *ifidx, void *pktdata, break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_c_show_host_event(event, event_data); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index bb26ee36bc6..8b2060b578d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -32,7 +32,7 @@ #define BRCMF_BTA_VAL 0x1000 #define BRCMF_ISCAN_VAL 0x2000 -#if defined(BCMDBG) +#if defined(DEBUG) #define brcmf_dbg(level, fmt, ...) \ do { \ @@ -56,7 +56,7 @@ do { \ #define BRCMF_BYTES_ON() (brcmf_msg_level & BRCMF_BYTES_VAL) #define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL) -#else /* (defined BCMDBG) || (defined BCMDBG) */ +#else /* (defined DEBUG) || (defined DEBUG) */ #define brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) @@ -66,7 +66,7 @@ do { \ #define BRCMF_BYTES_ON() 0 #define BRCMF_GLOM_ON() 0 -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ extern int brcmf_msg_level; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index c3980c50a99..16fd1ab3540 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -1146,7 +1146,7 @@ int brcmf_netdev_wait_pend8021x(struct net_device *ndev) return pend; } -#ifdef BCMDBG +#ifdef DEBUG int brcmf_write_to_file(struct brcmf_pub *drvr, const u8 *buf, int size) { int ret = 0; @@ -1180,4 +1180,4 @@ exit: return ret; } -#endif /* BCMDBG */ +#endif /* DEBUG */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index f7eeee1dcdb..7157a60c94b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -40,7 +40,7 @@ #define DCMD_RESP_TIMEOUT 2000 /* In milli second */ -#ifdef BCMDBG +#ifdef DEBUG #define BRCMF_TRAP_INFO_SIZE 80 @@ -84,7 +84,7 @@ struct rte_console { char cbuf[CBUF_LEN]; }; -#endif /* BCMDBG */ +#endif /* DEBUG */ #include #include "dhd_bus.h" @@ -416,7 +416,7 @@ struct sdpcmd_regs { u16 PAD[0x80]; }; -#ifdef BCMDBG +#ifdef DEBUG /* Device console log buffer state */ struct brcmf_console { uint count; /* Poll interval msec counter */ @@ -426,7 +426,7 @@ struct brcmf_console { u8 *buf; /* Log buffer (host copy) */ uint last; /* Last buffer read index */ }; -#endif /* BCMDBG */ +#endif /* DEBUG */ struct sdpcm_shared { u32 flags; @@ -507,11 +507,11 @@ struct brcmf_sdio { uint polltick; /* Tick counter */ uint pollcnt; /* Count of active polls */ -#ifdef BCMDBG +#ifdef DEBUG uint console_interval; struct brcmf_console console; /* Console output polling support */ uint console_addr; /* Console address from shared struct */ -#endif /* BCMDBG */ +#endif /* DEBUG */ uint regfails; /* Count of R_REG failures */ @@ -587,10 +587,10 @@ struct brcmf_sdio { #define CLK_PENDING 2 /* Not used yet */ #define CLK_AVAIL 3 -#ifdef BCMDBG +#ifdef DEBUG static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ #define SDIO_DRIVE_STRENGTH 6 /* in milliamps */ @@ -764,12 +764,12 @@ static int brcmf_sdbrcm_htclk(struct brcmf_sdio *bus, bool on, bool pendok) bus->clkstate = CLK_AVAIL; brcmf_dbg(INFO, "CLKCTL: turned ON\n"); -#if defined(BCMDBG) +#if defined(DEBUG) if (bus->alp_only != true) { if (SBSDIO_ALPONLY(clkctl)) brcmf_dbg(ERROR, "HT Clock should be on\n"); } -#endif /* defined (BCMDBG) */ +#endif /* defined (DEBUG) */ bus->activity = true; } else { @@ -814,9 +814,9 @@ static int brcmf_sdbrcm_sdclk(struct brcmf_sdio *bus, bool on) /* Transition SD and backplane clock readiness */ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) { -#ifdef BCMDBG +#ifdef DEBUG uint oldstate = bus->clkstate; -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TRACE, "Enter\n"); @@ -861,9 +861,9 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_sdio *bus, uint target, bool pendok) brcmf_sdbrcm_wd_timer(bus, 0); break; } -#ifdef BCMDBG +#ifdef DEBUG brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate); -#endif /* BCMDBG */ +#endif /* DEBUG */ return 0; } @@ -1279,7 +1279,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } return 0; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "SUPERFRAME:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1362,7 +1362,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "subframe:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1433,7 +1433,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } rxseq++; -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Subframe Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1457,7 +1457,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) continue; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", bus->glom.qlen, pfirst, pfirst->data, @@ -1467,7 +1467,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) pfirst->data, min_t(int, pfirst->len, 32)); } -#endif /* BCMDBG */ +#endif /* DEBUG */ } /* sent any remaining packets up */ if (bus->glom.qlen) { @@ -1584,7 +1584,7 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) gotpkt: -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "RxCtrl:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); @@ -1818,7 +1818,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) } bus->tx_max = txmax; -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -1865,7 +1865,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { printk(KERN_DEBUG "RxHdr:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -2024,7 +2024,7 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) skb_push(pkt, BRCMF_FIRSTREAD); memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { printk(KERN_DEBUG "Rx Data:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -2038,7 +2038,7 @@ deliver: if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", len); -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "Glom Data:\n"); print_hex_dump_bytes("", @@ -2078,13 +2078,13 @@ deliver: down(&bus->sdsem); } rxcount = maxframes - rxleft; -#ifdef BCMDBG +#ifdef DEBUG /* Message if we hit the limit */ if (!rxleft) brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes); else -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) @@ -2176,7 +2176,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, put_unaligned_le32(swheader, frame + SDPCM_FRAMETAG_LEN); put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); -#ifdef BCMDBG +#ifdef DEBUG tx_packets[pkt->priority]++; if (BRCMF_BYTES_ON() && (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || @@ -2410,7 +2410,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) int err; u8 clkctl, devctl = 0; -#ifdef BCMDBG +#ifdef DEBUG /* Check for inconsistent device control */ devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); @@ -2418,7 +2418,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN; } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, @@ -2701,7 +2701,7 @@ static int brcmf_sdbrcm_bus_txdata(struct device *dev, struct sk_buff *pkt) brcmf_txflowcontrol(bus->sdiodev->dev, 0, ON); } -#ifdef BCMDBG +#ifdef DEBUG if (pktq_plen(&bus->txq, prec) > qcount[prec]) qcount[prec] = pktq_plen(&bus->txq, prec); #endif @@ -2774,7 +2774,7 @@ xfer_done: return bcmerror; } -#ifdef BCMDBG +#ifdef DEBUG #define CONSOLE_LINE_MAX 192 static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) @@ -2852,7 +2852,7 @@ break2: return 0; } -#endif /* BCMDBG */ +#endif /* DEBUG */ static int brcmf_tx_frame(struct brcmf_sdio *bus, u8 *frame, u16 len) { @@ -2982,7 +2982,7 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } if (ret == -1) { -#ifdef BCMDBG +#ifdef DEBUG if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { printk(KERN_DEBUG "Tx Frame:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, @@ -3096,9 +3096,9 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) u8 *vbuffer; u32 varsizew; __le32 varsizew_le; -#ifdef BCMDBG +#ifdef DEBUG char *nvram_ularray; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Even if there are no vars are to be written, we still need to set the ramsize. */ @@ -3115,7 +3115,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) /* Write the vars list */ bcmerror = brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); -#ifdef BCMDBG +#ifdef DEBUG /* Verify NVRAM bytes */ brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); @@ -3142,7 +3142,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_sdio *bus) brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); -#endif /* BCMDBG */ +#endif /* DEBUG */ kfree(vbuffer); } @@ -3569,9 +3569,9 @@ void brcmf_sdbrcm_isr(void *arg) static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) { -#ifdef BCMDBG +#ifdef DEBUG struct brcmf_bus *bus_if = dev_get_drvdata(bus->sdiodev->dev); -#endif /* BCMDBG */ +#endif /* DEBUG */ brcmf_dbg(TIMER, "Enter\n"); @@ -3616,7 +3616,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) /* Update interrupt tracking */ bus->lastintrs = bus->intrcount; } -#ifdef BCMDBG +#ifdef DEBUG /* Poll for console output periodically */ if (bus_if->state == BRCMF_BUS_DATA && bus->console_interval != 0) { @@ -3630,7 +3630,7 @@ static bool brcmf_sdbrcm_bus_watchdog(struct brcmf_sdio *bus) bus->console_interval = 0; } } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* On idle timeout clear activity flag and/or turn off clock */ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { @@ -3721,11 +3721,11 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); -#ifdef BCMDBG +#ifdef DEBUG printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); -#endif /* BCMDBG */ +#endif /* DEBUG */ /* * Force PLL off until brcmf_sdio_chip_attach() diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index a613b49cb13..69a48729a72 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -42,7 +42,7 @@ do { \ } \ } while (0) -#if (defined BCMDBG) +#if (defined DEBUG) #define WL_INFO(fmt, args...) \ do { \ if (brcmf_dbg_level & WL_DBG_INFO) { \ @@ -83,12 +83,12 @@ do { \ } \ } while (0) -#else /* (defined BCMDBG) */ +#else /* (defined DEBUG) */ #define WL_INFO(fmt, args...) #define WL_TRACE(fmt, args...) #define WL_SCAN(fmt, args...) #define WL_CONN(fmt, args...) -#endif /* (defined BCMDBG) */ +#endif /* (defined DEBUG) */ #define WL_NUM_SCAN_MAX 1 #define WL_NUM_PMKIDS_MAX MAXPMKID /* will be used diff --git a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c index ab9bb11abfb..c93ea35bcee 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/aiutils.c @@ -326,11 +326,11 @@ #define PCI_FORCEHT(sih) (PCIE(sih) && (ai_get_chip_id(sih) == BCM4716_CHIP_ID)) -#ifdef BCMDBG +#ifdef DEBUG #define SI_MSG(fmt, ...) pr_debug(fmt, ##__VA_ARGS__) #else #define SI_MSG(fmt, ...) no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define GOODCOREADDR(x, b) \ (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c index 90911eec0cf..d89dcb14cb6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/ampdu.c @@ -915,7 +915,7 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); struct wiphy *wiphy = wlc->wiphy; -#ifdef BCMDBG +#ifdef DEBUG u8 hole[AMPDU_MAX_MPDU]; memset(hole, 0, sizeof(hole)); #endif diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c index 2e90a9a16ed..11054ae9d4f 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c @@ -177,7 +177,7 @@ #define BCMEXTRAHDROOM 172 /* debug/trace */ -#ifdef BCMDBG +#ifdef DEBUG #define DMA_ERROR(fmt, ...) \ do { \ if (*di->msg_level & 1) \ @@ -193,7 +193,7 @@ do { \ no_printk(fmt, ##__VA_ARGS__) #define DMA_TRACE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) -#endif /* BCMDBG */ +#endif /* DEBUG */ #define DMA_NONE(fmt, ...) \ no_printk(fmt, ##__VA_ARGS__) @@ -968,7 +968,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) pktcnt++; } -#ifdef BCMDBG +#ifdef DEBUG if (resid > 0) { uint cur; cur = @@ -979,7 +979,7 @@ int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) DMA_ERROR("rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur); } -#endif /* BCMDBG */ +#endif /* DEBUG */ if ((di->dma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR("%s: bad frame length (%d)\n", diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 448ab9c4eb4..04ba9a878f4 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -96,10 +96,10 @@ static struct bcma_device_id brcms_coreid_table[] = { }; MODULE_DEVICE_TABLE(bcma, brcms_coreid_table); -#ifdef BCMDBG +#ifdef DEBUG static int msglevel = 0xdeadbeef; module_param(msglevel, int, 0); -#endif /* BCMDBG */ +#endif /* DEBUG */ static struct ieee80211_channel brcms_2ghz_chantable[] = { CHAN2GHZ(1, 2412, IEEE80211_CHAN_NO_HT40MINUS), @@ -857,7 +857,7 @@ static void brcms_free(struct brcms_info *wl) /* free timers */ for (t = wl->timers; t; t = next) { next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1177,10 +1177,10 @@ static int __init brcms_module_init(void) { int error = -ENODEV; -#ifdef BCMDBG +#ifdef DEBUG if (msglevel != 0xdeadbeef) brcm_msg_level = msglevel; -#endif /* BCMDBG */ +#endif /* DEBUG */ error = bcma_driver_register(&brcms_bcma_driver); printk(KERN_ERR "%s: register returned %d\n", __func__, error); @@ -1367,7 +1367,7 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, t->next = wl->timers; wl->timers = t; -#ifdef BCMDBG +#ifdef DEBUG t->name = kmalloc(strlen(name) + 1, GFP_ATOMIC); if (t->name) strcpy(t->name, name); @@ -1386,7 +1386,7 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic) { struct ieee80211_hw *hw = t->wl->pub->ieee_hw; -#ifdef BCMDBG +#ifdef DEBUG if (t->set) wiphy_err(hw->wiphy, "%s: Already set. Name: %s, per %d\n", __func__, t->name, periodic); @@ -1431,7 +1431,7 @@ void brcms_free_timer(struct brcms_timer *t) if (wl->timers == t) { wl->timers = wl->timers->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); @@ -1443,7 +1443,7 @@ void brcms_free_timer(struct brcms_timer *t) while (tmp) { if (tmp->next == t) { tmp->next = t->next; -#ifdef BCMDBG +#ifdef DEBUG kfree(t->name); #endif kfree(t); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h index 8f60419c37b..9358bd5ebd3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.h @@ -40,7 +40,7 @@ struct brcms_timer { bool periodic; bool set; /* indicates if timer is active */ struct brcms_timer *next; /* for freeing on unload */ -#ifdef BCMDBG +#ifdef DEBUG char *name; /* Description of the timer */ #endif }; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index f7ed34034f8..3ae07bb9cc6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -293,11 +293,11 @@ const u8 prio2fifo[NUMPRIO] = { /* debug/trace */ uint brcm_msg_level = -#if defined(BCMDBG) +#if defined(DEBUG) LOG_ERROR_VAL; #else 0; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* TX FIFO number to WME/802.1E Access Category */ static const u8 wme_fifo2ac[] = { @@ -342,14 +342,14 @@ static const u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, }; -#ifdef BCMDBG +#ifdef DEBUG static const char * const fifo_names[] = { "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; #else static const char fifo_names[6][0]; #endif -#ifdef BCMDBG +#ifdef DEBUG /* pointer to most recently allocated wl/wlc */ static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); #endif @@ -3075,30 +3075,30 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) { int i; struct macstat macstats; -#ifdef BCMDBG +#ifdef DEBUG u16 delta; u16 rxf0ovfl; u16 txfunfl[NFIFO]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* if driver down, make no sense to update stats */ if (!wlc->pub->up) return; -#ifdef BCMDBG +#ifdef DEBUG /* save last rx fifo 0 overflow count */ rxf0ovfl = wlc->core->macstat_snapshot->rxf0ovfl; /* save last tx fifo underflow count */ for (i = 0; i < NFIFO; i++) txfunfl[i] = wlc->core->macstat_snapshot->txfunfl[i]; -#endif /* BCMDBG */ +#endif /* DEBUG */ /* Read mac stats from contiguous shared memory */ brcms_b_copyfrom_objmem(wlc->hw, M_UCODE_MACSTAT, &macstats, sizeof(struct macstat), OBJADDR_SHM_SEL); -#ifdef BCMDBG +#ifdef DEBUG /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) @@ -3114,7 +3114,7 @@ static void brcms_c_statsupd(struct brcms_c_info *wlc) wiphy_err(wlc->wiphy, "wl%d: %u tx fifo %d underflows!" "\n", wlc->pub->unit, delta, i); } -#endif /* BCMDBG */ +#endif /* DEBUG */ /* merge counters from dma module */ for (i = 0; i < NFIFO; i++) { @@ -5765,7 +5765,7 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } -#ifdef BCMDBG +#ifdef DEBUG static const char * const supr_reason[] = { "None", "PMQ Entry", "Flush request", "Previous frag failure", "Channel mismatch", @@ -5790,11 +5790,11 @@ static void brcms_c_print_txs_status(u16 s) printk(KERN_DEBUG " [1] %d acked\n", ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); } -#endif /* BCMDBG */ +#endif /* DEBUG */ void brcms_c_print_txstatus(struct tx_status *txs) { -#if defined(BCMDBG) +#if defined(DEBUG) u16 s = txs->status; u16 ackphyrxsh = txs->ackphyrxsh; @@ -5814,7 +5814,7 @@ void brcms_c_print_txstatus(struct tx_status *txs) printk(KERN_DEBUG "RxAckSQ: %04x", (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); printk(KERN_DEBUG "\n"); -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ } bool brcms_c_chipmatch(u16 vendor, u16 device) @@ -5837,7 +5837,7 @@ bool brcms_c_chipmatch(u16 vendor, u16 device) return false; } -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_txdesc(struct d11txh *txh) { u16 mtcl = le16_to_cpu(txh->MacTxControlLow); @@ -5919,9 +5919,9 @@ void brcms_c_print_txdesc(struct d11txh *txh) (u8 *)&rts, sizeof(txh->rts_frame)); printk(KERN_DEBUG "\n"); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) static int brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, int len) @@ -5975,9 +5975,9 @@ brcms_c_format_flags(const struct brcms_c_bit_desc *bd, u32 flags, char *buf, return (int)(p - buf); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ -#if defined(BCMDBG) +#if defined(DEBUG) void brcms_c_print_rxh(struct d11rxhdr *rxh) { u16 len = rxh->RxFrameSize; @@ -6016,7 +6016,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) (macstatus2 & RXS_AGGTYPE_MASK)); printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); } -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) { @@ -8346,7 +8346,7 @@ brcms_c_attach(struct brcms_info *wl, struct bcma_device *core, uint unit, wlc->wiphy = wl->wiphy; pub = wlc->pub; -#if defined(BCMDBG) +#if defined(DEBUG) wlc_info_dbg = wlc; #endif diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index adb136ec1f0..84a2a0d9dd3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -648,7 +648,7 @@ extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, uint *blocks); -#if defined(BCMDBG) +#if defined(DEBUG) extern void brcms_c_print_txdesc(struct d11txh *txh); #else #define brcms_c_print_txdesc(a) diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index b7537f70a79..e25fb2da8e6 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -240,7 +240,7 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, } EXPORT_SYMBOL(brcmu_pktq_mdeq); -#if defined(BCMDBG) +#if defined(DEBUG) /* pretty hex print a pkt buffer chain */ void brcmu_prpkt(const char *msg, struct sk_buff *p0) { @@ -253,4 +253,4 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } EXPORT_SYMBOL(brcmu_prpkt); -#endif /* defined(BCMDBG) */ +#endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index ad249a0b473..0cde38aa63f 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -176,10 +176,10 @@ struct ipv4_addr; /* externs */ /* format/print */ -#ifdef BCMDBG +#ifdef DEBUG extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #else #define brcmu_prpkt(a, b) -#endif /* BCMDBG */ +#endif /* DEBUG */ #endif /* _BRCMU_UTILS_H_ */ -- cgit v1.2.3-70-g09d2 From d6400c29abcd218bcc9be5d09f76e0770e25face Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:39 -0800 Subject: brcmfmac: Convert printk(KERN_DEBUG to pr_debug Allow dynamic debugging. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index 8b2060b578d..f5ca9fc526e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -39,13 +39,13 @@ do { \ if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ if (net_ratelimit()) \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } else { \ if (brcmf_msg_level & BRCMF_##level##_VAL) { \ - printk(KERN_DEBUG "%s: " fmt, \ - __func__, ##__VA_ARGS__); \ + pr_debug("%s: " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -- cgit v1.2.3-70-g09d2 From 1e02382979dd422e3b1bdb45545a0699497e3692 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:40 -0800 Subject: brcm80211: Add and use brcmX_dbg_dump_hex Reduce the number of #ifdef DEBUG uses by adding a dbg_hex_dump routine which has the appropriate #ifdef DEBUG test. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h | 6 + drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 141 +++++++-------------- drivers/net/wireless/brcm80211/brcmutil/utils.c | 18 +++ .../net/wireless/brcm80211/include/brcmu_utils.h | 11 ++ 4 files changed, 84 insertions(+), 92 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h index f5ca9fc526e..a2c4576cf9f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_dbg.h @@ -68,6 +68,12 @@ do { \ #endif /* defined(DEBUG) */ +#define brcmf_dbg_hex_dump(test, data, len, fmt, ...) \ +do { \ + if (test) \ + brcmu_dbg_hex_dump(data, len, fmt, ##__VA_ARGS__); \ +} while (0) + extern int brcmf_msg_level; #endif /* _BRCMF_DBG_H_ */ diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 7157a60c94b..4ab1023352a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -1279,13 +1279,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } return 0; } -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "SUPERFRAME:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, min_t(int, pfirst->len, 48)); - } -#endif + + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, min_t(int, pfirst->len, 48), + "SUPERFRAME:\n"); /* Validate the superframe header */ dptr = (u8 *) (pfirst->data); @@ -1362,13 +1359,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) check = get_unaligned_le16(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "subframe:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, 32); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + dptr, 32, "subframe:\n"); if ((u16)~(sublen ^ check)) { brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", @@ -1433,13 +1425,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) } rxseq++; -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Subframe Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - dptr, dlen); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + dptr, dlen, "Rx Subframe Data:\n"); __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); @@ -1457,17 +1444,13 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_sdio *bus, u8 rxseq) continue; } -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", - bus->glom.qlen, pfirst, pfirst->data, - pfirst->len, pfirst->next, - pfirst->prev); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pfirst->data, - min_t(int, pfirst->len, 32)); - } -#endif /* DEBUG */ + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pfirst->data, + min_t(int, pfirst->len, 32), + "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", + bus->glom.qlen, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev); } /* sent any remaining packets up */ if (bus->glom.qlen) { @@ -1584,12 +1567,8 @@ brcmf_sdbrcm_read_control(struct brcmf_sdio *bus, u8 *hdr, uint len, uint doff) gotpkt: -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "RxCtrl:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, bus->rxctl, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + bus->rxctl, len, "RxCtrl:\n"); /* Point to valid data and indicate its length */ bus->rxctl += doff; @@ -1818,17 +1797,13 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) } bus->tx_max = txmax; -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - rxbuf, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + rxbuf, len, "Rx Data:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + BRCMF_DATA_ON()) && + BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, + "RxHdr:\n"); if (chan == SDPCM_CONTROL_CHANNEL) { brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n", @@ -1865,13 +1840,9 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) brcmf_sdbrcm_rxfail(bus, true, true); continue; } -#ifdef DEBUG - if (BRCMF_BYTES_ON() || BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "RxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - bus->rxhdr, SDPCM_HDRLEN); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() || BRCMF_HDRS_ON(), + bus->rxhdr, SDPCM_HDRLEN, "RxHdr:\n"); + /* Extract hardware header fields */ len = get_unaligned_le16(bus->rxhdr); @@ -2024,13 +1995,8 @@ brcmf_sdbrcm_readframes(struct brcmf_sdio *bus, uint maxframes, bool *finished) skb_push(pkt, BRCMF_FIRSTREAD); memcpy(pkt->data, bus->rxhdr, BRCMF_FIRSTREAD); -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - printk(KERN_DEBUG "Rx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_DATA_ON(), + pkt->data, len, "Rx Data:\n"); deliver: /* Save superframe descriptor and allocate packet frame */ @@ -2038,14 +2004,9 @@ deliver: if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", len); -#ifdef DEBUG - if (BRCMF_GLOM_ON()) { - printk(KERN_DEBUG "Glom Data:\n"); - print_hex_dump_bytes("", - DUMP_PREFIX_OFFSET, - pkt->data, len); - } -#endif + brcmf_dbg_hex_dump(BRCMF_GLOM_ON(), + pkt->data, len, + "Glom Data:\n"); __skb_trim(pkt, len); skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; @@ -2178,16 +2139,18 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, #ifdef DEBUG tx_packets[pkt->priority]++; - if (BRCMF_BYTES_ON() && - (((BRCMF_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || - (BRCMF_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } + + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && chan != SDPCM_CONTROL_CHANNEL)), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && + ((BRCMF_CTL_ON() && + chan == SDPCM_CONTROL_CHANNEL) || + (BRCMF_DATA_ON() && + chan != SDPCM_CONTROL_CHANNEL))) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); #endif /* Raise len to next SDIO block to eliminate tail command */ @@ -2982,17 +2945,11 @@ brcmf_sdbrcm_bus_txctl(struct device *dev, unsigned char *msg, uint msglen) } if (ret == -1) { -#ifdef DEBUG - if (BRCMF_BYTES_ON() && BRCMF_CTL_ON()) { - printk(KERN_DEBUG "Tx Frame:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, len); - } else if (BRCMF_HDRS_ON()) { - printk(KERN_DEBUG "TxHdr:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - frame, min_t(u16, len, 16)); - } -#endif + brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && BRCMF_CTL_ON(), + frame, len, "Tx Frame:\n"); + brcmf_dbg_hex_dump(!(BRCMF_BYTES_ON() && BRCMF_CTL_ON()) && + BRCMF_HDRS_ON(), + frame, min_t(u16, len, 16), "TxHdr:\n"); do { ret = brcmf_tx_frame(bus, frame, len); diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index e25fb2da8e6..2207eaa34f8 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -253,4 +253,22 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); } EXPORT_SYMBOL(brcmu_prpkt); + +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ + struct va_format vaf; + va_list args; + + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; + + pr_debug("%pV", &vaf); + + va_end(args); + + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, size); +} +EXPORT_SYMBOL(brcmu_dbg_hex_dump); #endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/include/brcmu_utils.h b/drivers/net/wireless/brcm80211/include/brcmu_utils.h index 0cde38aa63f..477b92ad3d6 100644 --- a/drivers/net/wireless/brcm80211/include/brcmu_utils.h +++ b/drivers/net/wireless/brcm80211/include/brcmu_utils.h @@ -182,4 +182,15 @@ extern void brcmu_prpkt(const char *msg, struct sk_buff *p0); #define brcmu_prpkt(a, b) #endif /* DEBUG */ +#ifdef DEBUG +extern __printf(3, 4) +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...); +#else +__printf(3, 4) +static inline +void brcmu_dbg_hex_dump(const void *data, size_t size, const char *fmt, ...) +{ +} +#endif + #endif /* _BRCMU_UTILS_H_ */ -- cgit v1.2.3-70-g09d2 From 8fb1eb8b221f1cf81128b7f681b5a5112bfcd3a2 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:41 -0800 Subject: brcmfmac: Remove useless #ifdef DEBUG This doesn't do anything anymore. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4ab1023352a..79230e7edb3 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2039,13 +2039,11 @@ deliver: down(&bus->sdsem); } rxcount = maxframes - rxleft; -#ifdef DEBUG /* Message if we hit the limit */ if (!rxleft) brcmf_dbg(DATA, "hit rx limit of %d frames\n", maxframes); else -#endif /* DEBUG */ brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) -- cgit v1.2.3-70-g09d2 From 18aad4f8e11530fd7e41d0faea0752c3a0ce799c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:42 -0800 Subject: brcm80211: Convert printk(KERN_DEBUG to pr_debug Use pr_debug to allow dynamic debugging to work. Move an #endif to allow brcmf_dbg_hex_dump to be outside the #if/#endif block. Move a const char* declaration to be inside a pr_debug so the function doesn't need a #if/#endif block. Don't use temporaries in debugging functions so the code can be optimized away. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 4 +- drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 11 +- drivers/net/wireless/brcm80211/brcmsmac/main.c | 147 ++++++++++----------- drivers/net/wireless/brcm80211/brcmsmac/main.h | 4 +- .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 3 +- drivers/net/wireless/brcm80211/brcmutil/utils.c | 2 +- 6 files changed, 78 insertions(+), 93 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 9385c84646e..1c75ea887ac 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -399,10 +399,10 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) p = (char *)&buf[sizeof(struct msgtrace_hdr)]; while ((s = strstr(p, "\n")) != NULL) { *s = '\0'; - printk(KERN_DEBUG"%s\n", p); + pr_debug("%s\n", p); p = s + 1; } - printk(KERN_DEBUG "%s\n", p); + pr_debug("%s\n", p); /* Reset datalen to avoid display below */ datalen = 0; diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 79230e7edb3..91ec0235047 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -2137,6 +2137,7 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, #ifdef DEBUG tx_packets[pkt->priority]++; +#endif brcmf_dbg_hex_dump(BRCMF_BYTES_ON() && ((BRCMF_CTL_ON() && chan == SDPCM_CONTROL_CHANNEL) || @@ -2149,7 +2150,6 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_sdio *bus, struct sk_buff *pkt, chan != SDPCM_CONTROL_CHANNEL))) && BRCMF_HDRS_ON(), frame, min_t(u16, len, 16), "TxHdr:\n"); -#endif /* Raise len to next SDIO block to eliminate tail command */ if (bus->roundup && bus->blocksize && (len > bus->blocksize)) { @@ -2806,7 +2806,7 @@ static int brcmf_sdbrcm_readconsole(struct brcmf_sdio *bus) if (line[n - 1] == '\r') n--; line[n] = 0; - printk(KERN_DEBUG "CONSOLE: %s\n", line); + pr_debug("CONSOLE: %s\n", line); } } break2: @@ -3676,11 +3676,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_sdio *bus, u32 regsva) if (brcmf_sdcard_set_sbaddr_window(bus->sdiodev, SI_ENUM_BASE)) brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); -#ifdef DEBUG - printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", - brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); - -#endif /* DEBUG */ + pr_debug("F1 signature read @0x18000000=0x%4x\n", + brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); /* * Force PLL off until brcmf_sdio_chip_attach() diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 3ae07bb9cc6..14ab606de74 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -5765,56 +5765,43 @@ int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, return -ENODATA; } -#ifdef DEBUG -static const char * const supr_reason[] = { - "None", "PMQ Entry", "Flush request", - "Previous frag failure", "Channel mismatch", - "Lifetime Expiry", "Underflow" -}; - -static void brcms_c_print_txs_status(u16 s) -{ - printk(KERN_DEBUG "[15:12] %d frame attempts\n", - (s & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT); - printk(KERN_DEBUG " [11:8] %d rts attempts\n", - (s & TX_STATUS_RTS_RTX_MASK) >> TX_STATUS_RTS_RTX_SHIFT); - printk(KERN_DEBUG " [7] %d PM mode indicated\n", - ((s & TX_STATUS_PMINDCTD) ? 1 : 0)); - printk(KERN_DEBUG " [6] %d intermediate status\n", - ((s & TX_STATUS_INTERMEDIATE) ? 1 : 0)); - printk(KERN_DEBUG " [5] %d AMPDU\n", - (s & TX_STATUS_AMPDU) ? 1 : 0); - printk(KERN_DEBUG " [4:2] %d Frame Suppressed Reason (%s)\n", - ((s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT), - supr_reason[(s & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT]); - printk(KERN_DEBUG " [1] %d acked\n", - ((s & TX_STATUS_ACK_RCV) ? 1 : 0)); -} -#endif /* DEBUG */ - void brcms_c_print_txstatus(struct tx_status *txs) { -#if defined(DEBUG) - u16 s = txs->status; - u16 ackphyrxsh = txs->ackphyrxsh; - - printk(KERN_DEBUG "\ntxpkt (MPDU) Complete\n"); - - printk(KERN_DEBUG "FrameID: %04x ", txs->frameid); - printk(KERN_DEBUG "TxStatus: %04x", s); - printk(KERN_DEBUG "\n"); - - brcms_c_print_txs_status(s); - - printk(KERN_DEBUG "LastTxTime: %04x ", txs->lasttxtime); - printk(KERN_DEBUG "Seq: %04x ", txs->sequence); - printk(KERN_DEBUG "PHYTxStatus: %04x ", txs->phyerr); - printk(KERN_DEBUG "RxAckRSSI: %04x ", - (ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT); - printk(KERN_DEBUG "RxAckSQ: %04x", - (ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); - printk(KERN_DEBUG "\n"); -#endif /* defined(DEBUG) */ + pr_debug("\ntxpkt (MPDU) Complete\n"); + + pr_debug("FrameID: %04x TxStatus: %04x\n", txs->frameid, txs->status); + + pr_debug("[15:12] %d frame attempts\n", + (txs->status & TX_STATUS_FRM_RTX_MASK) >> + TX_STATUS_FRM_RTX_SHIFT); + pr_debug(" [11:8] %d rts attempts\n", + (txs->status & TX_STATUS_RTS_RTX_MASK) >> + TX_STATUS_RTS_RTX_SHIFT); + pr_debug(" [7] %d PM mode indicated\n", + txs->status & TX_STATUS_PMINDCTD ? 1 : 0); + pr_debug(" [6] %d intermediate status\n", + txs->status & TX_STATUS_INTERMEDIATE ? 1 : 0); + pr_debug(" [5] %d AMPDU\n", + txs->status & TX_STATUS_AMPDU ? 1 : 0); + pr_debug(" [4:2] %d Frame Suppressed Reason (%s)\n", + (txs->status & TX_STATUS_SUPR_MASK) >> TX_STATUS_SUPR_SHIFT, + (const char *[]) { + "None", + "PMQ Entry", + "Flush request", + "Previous frag failure", + "Channel mismatch", + "Lifetime Expiry", + "Underflow" + } [(txs->status & TX_STATUS_SUPR_MASK) >> + TX_STATUS_SUPR_SHIFT]); + pr_debug(" [1] %d acked\n", + txs->status & TX_STATUS_ACK_RCV ? 1 : 0); + + pr_debug("LastTxTime: %04x Seq: %04x PHYTxStatus: %04x RxAckRSSI: %04x RxAckSQ: %04x\n", + txs->lasttxtime, txs->sequence, txs->phyerr, + (txs->ackphyrxsh & PRXS1_JSSI_MASK) >> PRXS1_JSSI_SHIFT, + (txs->ackphyrxsh & PRXS1_SQ_MASK) >> PRXS1_SQ_SHIFT); } bool brcms_c_chipmatch(u16 vendor, u16 device) @@ -5871,53 +5858,53 @@ void brcms_c_print_txdesc(struct d11txh *txh) struct ieee80211_rts rts = txh->rts_frame; /* add plcp header along with txh descriptor */ - printk(KERN_DEBUG "Raw TxDesc + plcp header:\n"); + pr_debug("Raw TxDesc + plcp header:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, txh, sizeof(struct d11txh) + 48); - printk(KERN_DEBUG "TxCtlLow: %04x ", mtcl); - printk(KERN_DEBUG "TxCtlHigh: %04x ", mtch); - printk(KERN_DEBUG "FC: %04x ", mfc); - printk(KERN_DEBUG "FES Time: %04x\n", tfest); - printk(KERN_DEBUG "PhyCtl: %04x%s ", ptcw, + pr_debug("TxCtlLow: %04x ", mtcl); + pr_debug("TxCtlHigh: %04x ", mtch); + pr_debug("FC: %04x ", mfc); + pr_debug("FES Time: %04x\n", tfest); + pr_debug("PhyCtl: %04x%s ", ptcw, (ptcw & PHY_TXC_SHORT_HDR) ? " short" : ""); - printk(KERN_DEBUG "PhyCtl_1: %04x ", ptcw_1); - printk(KERN_DEBUG "PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); - printk(KERN_DEBUG "PhyCtl_1_Rts: %04x ", ptcw_1_Rts); - printk(KERN_DEBUG "PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); - printk(KERN_DEBUG "MainRates: %04x ", mainrates); - printk(KERN_DEBUG "XtraFrameTypes: %04x ", xtraft); - printk(KERN_DEBUG "\n"); + pr_debug("PhyCtl_1: %04x ", ptcw_1); + pr_debug("PhyCtl_1_Fbr: %04x\n", ptcw_1_Fbr); + pr_debug("PhyCtl_1_Rts: %04x ", ptcw_1_Rts); + pr_debug("PhyCtl_1_Fbr_Rts: %04x\n", ptcw_1_FbrRts); + pr_debug("MainRates: %04x ", mainrates); + pr_debug("XtraFrameTypes: %04x ", xtraft); + pr_debug("\n"); print_hex_dump_bytes("SecIV:", DUMP_PREFIX_OFFSET, iv, sizeof(txh->IV)); print_hex_dump_bytes("RA:", DUMP_PREFIX_OFFSET, ra, sizeof(txh->TxFrameRA)); - printk(KERN_DEBUG "Fb FES Time: %04x ", tfestfb); + pr_debug("Fb FES Time: %04x ", tfestfb); print_hex_dump_bytes("Fb RTS PLCP:", DUMP_PREFIX_OFFSET, rtspfb, sizeof(txh->RTSPLCPFallback)); - printk(KERN_DEBUG "RTS DUR: %04x ", rtsdfb); + pr_debug("RTS DUR: %04x ", rtsdfb); print_hex_dump_bytes("PLCP:", DUMP_PREFIX_OFFSET, fragpfb, sizeof(txh->FragPLCPFallback)); - printk(KERN_DEBUG "DUR: %04x", fragdfb); - printk(KERN_DEBUG "\n"); + pr_debug("DUR: %04x", fragdfb); + pr_debug("\n"); - printk(KERN_DEBUG "MModeLen: %04x ", mmodelen); - printk(KERN_DEBUG "MModeFbrLen: %04x\n", mmodefbrlen); + pr_debug("MModeLen: %04x ", mmodelen); + pr_debug("MModeFbrLen: %04x\n", mmodefbrlen); - printk(KERN_DEBUG "FrameID: %04x\n", tfid); - printk(KERN_DEBUG "TxStatus: %04x\n", txs); + pr_debug("FrameID: %04x\n", tfid); + pr_debug("TxStatus: %04x\n", txs); - printk(KERN_DEBUG "MaxNumMpdu: %04x\n", mnmpdu); - printk(KERN_DEBUG "MaxAggbyte: %04x\n", mabyte); - printk(KERN_DEBUG "MaxAggbyte_fb: %04x\n", mabyte_f); - printk(KERN_DEBUG "MinByte: %04x\n", mmbyte); + pr_debug("MaxNumMpdu: %04x\n", mnmpdu); + pr_debug("MaxAggbyte: %04x\n", mabyte); + pr_debug("MaxAggbyte_fb: %04x\n", mabyte_f); + pr_debug("MinByte: %04x\n", mmbyte); print_hex_dump_bytes("RTS PLCP:", DUMP_PREFIX_OFFSET, rtsph, sizeof(txh->RTSPhyHeader)); print_hex_dump_bytes("RTS Frame:", DUMP_PREFIX_OFFSET, (u8 *)&rts, sizeof(txh->rts_frame)); - printk(KERN_DEBUG "\n"); + pr_debug("\n"); } #endif /* defined(DEBUG) */ @@ -5999,7 +5986,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) {0, NULL} }; - printk(KERN_DEBUG "Raw RxDesc:\n"); + pr_debug("Raw RxDesc:\n"); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, sizeof(struct d11rxhdr)); @@ -6007,14 +5994,14 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) snprintf(lenbuf, sizeof(lenbuf), "0x%x", len); - printk(KERN_DEBUG "RxFrameSize: %6s (%d)%s\n", lenbuf, len, + pr_debug("RxFrameSize: %6s (%d)%s\n", lenbuf, len, (rxh->PhyRxStatus_0 & PRXS0_SHORTH) ? " short preamble" : ""); - printk(KERN_DEBUG "RxPHYStatus: %04x %04x %04x %04x\n", + pr_debug("RxPHYStatus: %04x %04x %04x %04x\n", phystatus_0, phystatus_1, phystatus_2, phystatus_3); - printk(KERN_DEBUG "RxMACStatus: %x %s\n", macstatus1, flagstr); - printk(KERN_DEBUG "RXMACaggtype: %x\n", + pr_debug("RxMACStatus: %x %s\n", macstatus1, flagstr); + pr_debug("RXMACaggtype: %x\n", (macstatus2 & RXS_AGGTYPE_MASK)); - printk(KERN_DEBUG "RxTSFTime: %04x\n", rxh->RxTSFTime); + pr_debug("RxTSFTime: %04x\n", rxh->RxTSFTime); } #endif /* defined(DEBUG) */ diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h index 84a2a0d9dd3..8debc74c54e 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.h +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h @@ -651,7 +651,9 @@ extern int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, #if defined(DEBUG) extern void brcms_c_print_txdesc(struct d11txh *txh); #else -#define brcms_c_print_txdesc(a) +static inline void brcms_c_print_txdesc(struct d11txh *txh) +{ +} #endif extern int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config); diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index a16f1ab292f..a0909be6ef3 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -26434,8 +26434,7 @@ cal_try: } if (bcmerror != 0) { - printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__, - cal_retry); + pr_debug("%s: Failed, cnt = %d\n", __func__, cal_retry); if (cal_retry < CAL_RETRY_CNT) { cal_retry++; diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index 2207eaa34f8..49086606485 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -247,7 +247,7 @@ void brcmu_prpkt(const char *msg, struct sk_buff *p0) struct sk_buff *p; if (msg && (msg[0] != '\0')) - printk(KERN_DEBUG "%s:\n", msg); + pr_debug("%s:\n", msg); for (p = p0; p; p = p->next) print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p->data, p->len); -- cgit v1.2.3-70-g09d2 From c2e6d5abab73df316d2ae7caa6d902c143b2d52d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:43 -0800 Subject: brcm80211: Use brcmu_dbg_hex_dump Convert a couple of pr_debug/print_hex_dump to the standard utility. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmsmac/main.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 14ab606de74..72701a4bf89 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -5858,9 +5858,8 @@ void brcms_c_print_txdesc(struct d11txh *txh) struct ieee80211_rts rts = txh->rts_frame; /* add plcp header along with txh descriptor */ - pr_debug("Raw TxDesc + plcp header:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, - txh, sizeof(struct d11txh) + 48); + brcmu_dbg_hex_dump(txh, sizeof(struct d11txh) + 48, + "Raw TxDesc + plcp header:\n"); pr_debug("TxCtlLow: %04x ", mtcl); pr_debug("TxCtlHigh: %04x ", mtch); @@ -5986,9 +5985,7 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) {0, NULL} }; - pr_debug("Raw RxDesc:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, rxh, - sizeof(struct d11rxhdr)); + brcmu_dbg_hex_dump(rxh, sizeof(struct d11rxhdr), "Raw RxDesc:\n"); brcms_c_format_flags(macstat_flags, macstatus1, flagstr, 64); -- cgit v1.2.3-70-g09d2 From 02f77195db6ce252d5488b6d48d8edc1c5e2aa30 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:44 -0800 Subject: brcm80211: Use pr_fmt and pr_ Convert printks to pr_ Prefix logging with pr_fmt. Use ##__VA_ARGS__ in some WL_ logging macros. Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 3 +++ drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/dhd_common.c | 3 +++ .../net/wireless/brcm80211/brcmfmac/dhd_linux.c | 2 ++ drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 8 +++--- .../net/wireless/brcm80211/brcmfmac/sdio_chip.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 2 ++ .../net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 30 +++++++++++----------- .../net/wireless/brcm80211/brcmsmac/mac80211_if.c | 6 ++--- drivers/net/wireless/brcm80211/brcmsmac/main.c | 6 +++-- .../net/wireless/brcm80211/brcmsmac/phy/phy_n.c | 2 ++ drivers/net/wireless/brcm80211/brcmutil/utils.c | 2 ++ 13 files changed, 46 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c index 4bc8d251acf..e925290b432 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c @@ -15,6 +15,8 @@ */ /* ****************** SDIO CARD Interface Functions **************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 9b8c0ed833d..ac71adeece5 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c index ac8d1f43788..b3e3b7f25d8 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_cdc.c @@ -19,6 +19,8 @@ * For certain dcmd codes, the dongle interprets string data from the host. ******************************************************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c index 1c75ea887ac..4187435220f 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c @@ -13,6 +13,9 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c index 16fd1ab3540..db2df1f1e6b 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 91ec0235047..6e4b5e85a09 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -3896,8 +3898,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->watchdog_tsk = kthread_run(brcmf_sdbrcm_watchdog_thread, bus, "brcmf_watchdog"); if (IS_ERR(bus->watchdog_tsk)) { - printk(KERN_WARNING - "brcmf_watchdog thread failed to start\n"); + pr_warn("brcmf_watchdog thread failed to start\n"); bus->watchdog_tsk = NULL; } /* Initialize DPC thread */ @@ -3905,8 +3906,7 @@ void *brcmf_sdbrcm_probe(u32 regsva, struct brcmf_sdio_dev *sdiodev) bus->dpc_tsk = kthread_run(brcmf_sdbrcm_dpc_thread, bus, "brcmf_dpc"); if (IS_ERR(bus->dpc_tsk)) { - printk(KERN_WARNING - "brcmf_dpc thread failed to start\n"); + pr_warn("brcmf_dpc thread failed to start\n"); bus->dpc_tsk = NULL; } diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 11b2d7c97ba..1534efc2163 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c @@ -15,6 +15,8 @@ */ /* ***** SDIO interface chip backplane handle functions ***** */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index bf11850a20f..886b0ccbc5c 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,6 +16,8 @@ /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h index 69a48729a72..b5d9b36df3d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h @@ -32,53 +32,53 @@ struct brcmf_cfg80211_ibss; #define WL_DBG_MASK ((WL_DBG_INFO | WL_DBG_ERR | WL_DBG_TRACE) | \ (WL_DBG_SCAN) | (WL_DBG_CONN)) -#define WL_ERR(fmt, args...) \ +#define WL_ERR(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_ERR) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "ERROR @%s : " fmt, \ - __func__, ##args); \ + pr_err("ERROR @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) #if (defined DEBUG) -#define WL_INFO(fmt, args...) \ +#define WL_INFO(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_INFO) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "INFO @%s : " fmt, \ - __func__, ##args); \ + pr_err("INFO @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_TRACE(fmt, args...) \ +#define WL_TRACE(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_TRACE) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "TRACE @%s : " fmt, \ - __func__, ##args); \ + pr_err("TRACE @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_SCAN(fmt, args...) \ +#define WL_SCAN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_SCAN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "SCAN @%s : " fmt, \ - __func__, ##args); \ + pr_err("SCAN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) -#define WL_CONN(fmt, args...) \ +#define WL_CONN(fmt, ...) \ do { \ if (brcmf_dbg_level & WL_DBG_CONN) { \ if (net_ratelimit()) { \ - printk(KERN_ERR "CONN @%s : " fmt, \ - __func__, ##args); \ + pr_err("CONN @%s : " fmt, \ + __func__, ##__VA_ARGS__); \ } \ } \ } while (0) diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c index 04ba9a878f4..c8427978d09 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c @@ -15,6 +15,7 @@ */ #define __UNDEF_NO_VERSION__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -1121,8 +1122,7 @@ static int __devinit brcms_bcma_probe(struct bcma_device *pdev) wl = brcms_attach(pdev); if (!wl) { - pr_err("%s: %s: brcms_attach failed!\n", KBUILD_MODNAME, - __func__); + pr_err("%s: brcms_attach failed!\n", __func__); return -ENODEV; } return 0; @@ -1183,7 +1183,7 @@ static int __init brcms_module_init(void) #endif /* DEBUG */ error = bcma_driver_register(&brcms_bcma_driver); - printk(KERN_ERR "%s: register returned %d\n", __func__, error); + pr_err("%s: register returned %d\n", __func__, error); if (!error) return 0; diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c index 72701a4bf89..976a53183f6 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/main.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -5807,7 +5809,7 @@ void brcms_c_print_txstatus(struct tx_status *txs) bool brcms_c_chipmatch(u16 vendor, u16 device) { if (vendor != PCI_VENDOR_ID_BROADCOM) { - pr_err("chipmatch: unknown vendor id %04x\n", vendor); + pr_err("unknown vendor id %04x\n", vendor); return false; } @@ -5820,7 +5822,7 @@ bool brcms_c_chipmatch(u16 vendor, u16 device) if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - pr_err("chipmatch: unknown device id %04x\n", device); + pr_err("unknown device id %04x\n", device); return false; } diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c index a0909be6ef3..ec7450d2fbd 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include diff --git a/drivers/net/wireless/brcm80211/brcmutil/utils.c b/drivers/net/wireless/brcm80211/brcmutil/utils.c index 49086606485..b45ab34cdfd 100644 --- a/drivers/net/wireless/brcm80211/brcmutil/utils.c +++ b/drivers/net/wireless/brcm80211/brcmutil/utils.c @@ -14,6 +14,8 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include -- cgit v1.2.3-70-g09d2 From bfeb4dbc5cb36ae774fabe7b0e0d559e621a2ccd Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 15 Jan 2012 00:38:45 -0800 Subject: brcmfmac: Trivial typo of "couldn" to "could" fix Signed-off-by: Joe Perches Signed-off-by: John W. Linville --- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c index 886b0ccbc5c..74c95a59795 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c @@ -2785,7 +2785,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_priv) + sizeof_iface); if (!wdev->wiphy) { - WL_ERR("Couldn not allocate wiphy device\n"); + WL_ERR("Could not allocate wiphy device\n"); err = -ENOMEM; goto wiphy_new_out; } @@ -2811,7 +2811,7 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, */ err = wiphy_register(wdev->wiphy); if (err < 0) { - WL_ERR("Couldn not register wiphy device (%d)\n", err); + WL_ERR("Could not register wiphy device (%d)\n", err); goto wiphy_register_out; } return wdev; -- cgit v1.2.3-70-g09d2 From 3ed1326d2e693d555e62241c2e2209f01506214e Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:31 +0200 Subject: NFC: Add endian annotations to nfcwilink driver Add endian annotations to TI nfcwilink driver. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index 06c3642e5bd..ee60d084433 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -28,6 +28,7 @@ */ #include #include +#include #include #include #include @@ -42,9 +43,9 @@ #define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ struct nfcwilink_hdr { - u8 chnl; - u8 opcode; - u16 len; + __u8 chnl; + __u8 opcode; + __le16 len; } __packed; struct nfcwilink { @@ -212,7 +213,7 @@ static int nfcwilink_send(struct sk_buff *skb) return -EBUSY; /* add the ST hdr to the start of the buffer */ - hdr.len = skb->len; + hdr.len = cpu_to_le16(skb->len); memcpy(skb_push(skb, NFCWILINK_HDR_LEN), &hdr, NFCWILINK_HDR_LEN); /* Insert skb to shared transport layer's transmit queue. @@ -239,7 +240,7 @@ static int nfcwilink_probe(struct platform_device *pdev) { static struct nfcwilink *drv; int rc; - u32 protocols; + __u32 protocols; nfc_dev_dbg(&pdev->dev, "probe entry"); -- cgit v1.2.3-70-g09d2 From 1195d89b2defd92829ed54938e60312e62dc8747 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:32 +0200 Subject: NFC: Download TI NFC init script Download TI NFC init script during nfcwilink open operation, after the NFC channel is registered with TI shared transport. TI NFC init script is written in BTS format. First, read the chip version via a special vendor specific command. Second, we request the relevant BTS file from the user space, and then send the BTS commands to the chip. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 284 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index ee60d084433..90af28d611f 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,17 @@ #define NFCWILINK_OFFSET_LEN_IN_HDR 1 #define NFCWILINK_LEN_SIZE 2 #define NFCWILINK_REGISTER_TIMEOUT 8000 /* 8 sec */ +#define NFCWILINK_CMD_TIMEOUT 5000 /* 5 sec */ + +#define BTS_FILE_NAME_MAX_SIZE 40 +#define BTS_FILE_HDR_MAGIC 0x42535442 +#define BTS_FILE_CMD_MAX_LEN 0xff +#define BTS_FILE_ACTION_TYPE_SEND_CMD 1 + +#define NCI_VS_NFCC_INFO_CMD_GID 0x2f +#define NCI_VS_NFCC_INFO_CMD_OID 0x12 +#define NCI_VS_NFCC_INFO_RSP_GID 0x4f +#define NCI_VS_NFCC_INFO_RSP_OID 0x12 struct nfcwilink_hdr { __u8 chnl; @@ -48,6 +60,36 @@ struct nfcwilink_hdr { __le16 len; } __packed; +struct nci_vs_nfcc_info_cmd { + __u8 gid; + __u8 oid; + __u8 plen; +} __packed; + +struct nci_vs_nfcc_info_rsp { + __u8 gid; + __u8 oid; + __u8 plen; + __u8 status; + __u8 hw_id; + __u8 sw_ver_x; + __u8 sw_ver_z; + __u8 patch_id; +} __packed; + +struct bts_file_hdr { + __le32 magic; + __le32 ver; + __u8 rfu[24]; + __u8 actions[0]; +} __packed; + +struct bts_file_action { + __le16 type; + __le16 len; + __u8 data[0]; +} __packed; + struct nfcwilink { struct platform_device *pdev; struct nci_dev *ndev; @@ -55,14 +97,241 @@ struct nfcwilink { char st_register_cb_status; long (*st_write) (struct sk_buff *); - struct completion st_register_completed; + + struct completion completed; + + struct nci_vs_nfcc_info_rsp nfcc_info; }; /* NFCWILINK driver flags */ enum { NFCWILINK_RUNNING, + NFCWILINK_FW_DOWNLOAD, }; +static int nfcwilink_send(struct sk_buff *skb); + +static inline struct sk_buff *nfcwilink_skb_alloc(unsigned int len, gfp_t how) +{ + struct sk_buff *skb; + + skb = alloc_skb(len + NFCWILINK_HDR_LEN, how); + if (skb) + skb_reserve(skb, NFCWILINK_HDR_LEN); + + return skb; +} + +static void nfcwilink_fw_download_receive(struct nfcwilink *drv, + struct sk_buff *skb) +{ + struct nci_vs_nfcc_info_rsp *rsp = (void *)skb->data; + + /* Detect NCI_VS_NFCC_INFO_RSP and store the result */ + if ((skb->len > 3) && (rsp->gid == NCI_VS_NFCC_INFO_RSP_GID) && + (rsp->oid == NCI_VS_NFCC_INFO_RSP_OID)) { + memcpy(&drv->nfcc_info, rsp, + sizeof(struct nci_vs_nfcc_info_rsp)); + } + + kfree_skb(skb); + + complete(&drv->completed); +} + +static int nfcwilink_get_bts_file_name(struct nfcwilink *drv, char *file_name) +{ + struct nci_vs_nfcc_info_cmd *cmd; + struct sk_buff *skb; + unsigned long comp_ret; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "get_bts_file_name entry"); + + skb = nfcwilink_skb_alloc(sizeof(struct nci_vs_nfcc_info_cmd), + GFP_KERNEL); + if (!skb) { + nfc_dev_err(&drv->pdev->dev, + "no memory for nci_vs_nfcc_info_cmd"); + return -ENOMEM; + } + + skb->dev = (void *)drv->ndev; + + cmd = (struct nci_vs_nfcc_info_cmd *) + skb_put(skb, sizeof(struct nci_vs_nfcc_info_cmd)); + cmd->gid = NCI_VS_NFCC_INFO_CMD_GID; + cmd->oid = NCI_VS_NFCC_INFO_CMD_OID; + cmd->plen = 0; + + drv->nfcc_info.plen = 0; + + rc = nfcwilink_send(skb); + if (rc) + return rc; + + comp_ret = wait_for_completion_timeout(&drv->completed, + msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); + nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", + comp_ret); + if (comp_ret == 0) { + nfc_dev_err(&drv->pdev->dev, + "timeout on wait_for_completion_timeout"); + return -ETIMEDOUT; + } + + nfc_dev_dbg(&drv->pdev->dev, "nci_vs_nfcc_info_rsp: plen %d, status %d", + drv->nfcc_info.plen, + drv->nfcc_info.status); + + if ((drv->nfcc_info.plen != 5) || (drv->nfcc_info.status != 0)) { + nfc_dev_err(&drv->pdev->dev, + "invalid nci_vs_nfcc_info_rsp"); + return -EINVAL; + } + + snprintf(file_name, BTS_FILE_NAME_MAX_SIZE, + "TINfcInit_%d.%d.%d.%d.bts", + drv->nfcc_info.hw_id, + drv->nfcc_info.sw_ver_x, + drv->nfcc_info.sw_ver_z, + drv->nfcc_info.patch_id); + + nfc_dev_info(&drv->pdev->dev, "nfcwilink FW file name: %s", file_name); + + return 0; +} + +static int nfcwilink_send_bts_cmd(struct nfcwilink *drv, __u8 *data, int len) +{ + struct nfcwilink_hdr *hdr = (struct nfcwilink_hdr *)data; + struct sk_buff *skb; + unsigned long comp_ret; + int rc; + + nfc_dev_dbg(&drv->pdev->dev, "send_bts_cmd entry"); + + /* verify valid cmd for the NFC channel */ + if ((len <= sizeof(struct nfcwilink_hdr)) || + (len > BTS_FILE_CMD_MAX_LEN) || + (hdr->chnl != NFCWILINK_CHNL) || + (hdr->opcode != NFCWILINK_OPCODE)) { + nfc_dev_err(&drv->pdev->dev, + "ignoring invalid bts cmd, len %d, chnl %d, opcode %d", + len, hdr->chnl, hdr->opcode); + return 0; + } + + /* remove the ST header */ + len -= sizeof(struct nfcwilink_hdr); + data += sizeof(struct nfcwilink_hdr); + + skb = nfcwilink_skb_alloc(len, GFP_KERNEL); + if (!skb) { + nfc_dev_err(&drv->pdev->dev, "no memory for bts cmd"); + return -ENOMEM; + } + + skb->dev = (void *)drv->ndev; + + memcpy(skb_put(skb, len), data, len); + + rc = nfcwilink_send(skb); + if (rc) + return rc; + + comp_ret = wait_for_completion_timeout(&drv->completed, + msecs_to_jiffies(NFCWILINK_CMD_TIMEOUT)); + nfc_dev_dbg(&drv->pdev->dev, "wait_for_completion_timeout returned %ld", + comp_ret); + if (comp_ret == 0) { + nfc_dev_err(&drv->pdev->dev, + "timeout on wait_for_completion_timeout"); + return -ETIMEDOUT; + } + + return 0; +} + +static int nfcwilink_download_fw(struct nfcwilink *drv) +{ + unsigned char file_name[BTS_FILE_NAME_MAX_SIZE]; + const struct firmware *fw; + __u16 action_type, action_len; + __u8 *ptr; + int len, rc; + + nfc_dev_dbg(&drv->pdev->dev, "download_fw entry"); + + set_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); + + rc = nfcwilink_get_bts_file_name(drv, file_name); + if (rc) + goto exit; + + rc = request_firmware(&fw, file_name, &drv->pdev->dev); + if (rc) { + nfc_dev_err(&drv->pdev->dev, "request_firmware failed %d", rc); + + /* if the file is not found, don't exit with failure */ + if (rc == -ENOENT) + rc = 0; + + goto exit; + } + + len = fw->size; + ptr = (__u8 *)fw->data; + + if ((len == 0) || (ptr == NULL)) { + nfc_dev_dbg(&drv->pdev->dev, + "request_firmware returned size %d", len); + goto release_fw; + } + + if (__le32_to_cpu(((struct bts_file_hdr *)ptr)->magic) != + BTS_FILE_HDR_MAGIC) { + nfc_dev_err(&drv->pdev->dev, "wrong bts magic number"); + rc = -EINVAL; + goto release_fw; + } + + /* remove the BTS header */ + len -= sizeof(struct bts_file_hdr); + ptr += sizeof(struct bts_file_hdr); + + while (len > 0) { + action_type = + __le16_to_cpu(((struct bts_file_action *)ptr)->type); + action_len = + __le16_to_cpu(((struct bts_file_action *)ptr)->len); + + nfc_dev_dbg(&drv->pdev->dev, "bts_file_action type %d, len %d", + action_type, action_len); + + switch (action_type) { + case BTS_FILE_ACTION_TYPE_SEND_CMD: + rc = nfcwilink_send_bts_cmd(drv, + ((struct bts_file_action *)ptr)->data, + action_len); + if (rc) + goto release_fw; + break; + } + + /* advance to the next action */ + len -= (sizeof(struct bts_file_action) + action_len); + ptr += (sizeof(struct bts_file_action) + action_len); + } + +release_fw: + release_firmware(fw); + +exit: + clear_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags); + return rc; +} + /* Called by ST when registration is complete */ static void nfcwilink_register_complete(void *priv_data, char data) { @@ -74,7 +343,7 @@ static void nfcwilink_register_complete(void *priv_data, char data) drv->st_register_cb_status = data; /* complete the wait in nfc_st_open() */ - complete(&drv->st_register_completed); + complete(&drv->completed); } /* Called by ST when receive data is available */ @@ -97,6 +366,11 @@ static long nfcwilink_receive(void *priv_data, struct sk_buff *skb) (apart for the chnl byte, which is not received in the hdr) */ skb_pull(skb, (NFCWILINK_HDR_LEN-1)); + if (test_bit(NFCWILINK_FW_DOWNLOAD, &drv->flags)) { + nfcwilink_fw_download_receive(drv, skb); + return 0; + } + skb->dev = (void *) drv->ndev; /* Forward skb to NCI core layer */ @@ -137,14 +411,14 @@ static int nfcwilink_open(struct nci_dev *ndev) nfcwilink_proto.priv_data = drv; - init_completion(&drv->st_register_completed); + init_completion(&drv->completed); drv->st_register_cb_status = -EINPROGRESS; rc = st_register(&nfcwilink_proto); if (rc < 0) { if (rc == -EINPROGRESS) { comp_ret = wait_for_completion_timeout( - &drv->st_register_completed, + &drv->completed, msecs_to_jiffies(NFCWILINK_REGISTER_TIMEOUT)); nfc_dev_dbg(&drv->pdev->dev, @@ -172,6 +446,12 @@ static int nfcwilink_open(struct nci_dev *ndev) BUG_ON(nfcwilink_proto.write == NULL); drv->st_write = nfcwilink_proto.write; + if (nfcwilink_download_fw(drv)) { + nfc_dev_err(&drv->pdev->dev, "nfcwilink_download_fw failed %d", + rc); + /* open should succeed, even if the FW download failed */ + } + goto exit; clear_exit: -- cgit v1.2.3-70-g09d2 From ea9917d6f9e355646258b8d08ac69108908618a2 Mon Sep 17 00:00:00 2001 From: Ilan Elias Date: Tue, 17 Jan 2012 14:11:33 +0200 Subject: NFC: Free sk_buff if nfcwilink_send fails Free sk_buff if nfcwilink_send fails. Signed-off-by: Ilan Elias Acked-by: Samuel Ortiz Signed-off-by: John W. Linville --- drivers/nfc/nfcwilink.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/nfc/nfcwilink.c b/drivers/nfc/nfcwilink.c index 90af28d611f..1f74a77d040 100644 --- a/drivers/nfc/nfcwilink.c +++ b/drivers/nfc/nfcwilink.c @@ -489,8 +489,10 @@ static int nfcwilink_send(struct sk_buff *skb) nfc_dev_dbg(&drv->pdev->dev, "send entry, len %d", skb->len); - if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) - return -EBUSY; + if (!test_bit(NFCWILINK_RUNNING, &drv->flags)) { + kfree_skb(skb); + return -EINVAL; + } /* add the ST hdr to the start of the buffer */ hdr.len = cpu_to_le16(skb->len); -- cgit v1.2.3-70-g09d2 From d7d312cab41b2c973951fcc7f752411cbaaf8338 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Tue, 17 Jan 2012 23:13:30 +0100 Subject: ath9k_htc: claim support for IBSS RSN Skip group keys configuration in hardware in order to make IBSS RSN work. Keys will be managed using software. Signed-off-by: Antonio Quartulli Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 ++ drivers/net/wireless/ath/ath9k/htc_drv_main.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 9be10a2da1c..fc7519c9339 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -741,6 +741,8 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; + hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->queues = 4; hw->channel_change_time = 5000; hw->max_listen_interval = 10; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ef4c6066129..06101b6bdea 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -1409,6 +1409,21 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, if (htc_modparam_nohwcrypt) return -ENOSPC; + if ((vif->type == NL80211_IFTYPE_ADHOC || + vif->type == NL80211_IFTYPE_MESH_POINT) && + (key->cipher == WLAN_CIPHER_SUITE_TKIP || + key->cipher == WLAN_CIPHER_SUITE_CCMP) && + !(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { + /* + * For now, disable hw crypto for the RSN IBSS group keys. This + * could be optimized in the future to use a modified key cache + * design to support per-STA RX GTK, but until that gets + * implemented, use of software crypto for group addressed + * frames is a acceptable to allow RSN IBSS to be used. + */ + return -EOPNOTSUPP; + } + mutex_lock(&priv->mutex); ath_dbg(common, CONFIG, "Set HW Key\n"); ath9k_htc_ps_wakeup(priv); -- cgit v1.2.3-70-g09d2 From 11deb53328a06ad4edbf774f5c3b61c6dbb9104c Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 24 Jan 2012 14:58:47 -0500 Subject: ath5k: use bool type for no_hw_rfkill_switch module parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids this: CC [M] drivers/net/wireless/ath/ath5k/base.o drivers/net/wireless/ath/ath5k/base.c: In function ‘__check_no_hw_rfkill_switch’: drivers/net/wireless/ath/ath5k/base.c:85:1: warning: return from incompatible pointer type Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath5k/base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 4ab835f08a4..a339693fbe2 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -80,7 +80,7 @@ static bool modparam_fastchanswitch; module_param_named(fastchanswitch, modparam_fastchanswitch, bool, S_IRUGO); MODULE_PARM_DESC(fastchanswitch, "Enable fast channel switching for AR2413/AR5413 radios."); -static int ath5k_modparam_no_hw_rfkill_switch; +static bool ath5k_modparam_no_hw_rfkill_switch; module_param_named(no_hw_rfkill_switch, ath5k_modparam_no_hw_rfkill_switch, bool, S_IRUGO); MODULE_PARM_DESC(no_hw_rfkill_switch, "Ignore the GPIO RFKill switch state"); -- cgit v1.2.3-70-g09d2 From e371ceb89f531280d30cadbdb8371656468705b1 Mon Sep 17 00:00:00 2001 From: Karol Lewandowski Date: Tue, 24 Jan 2012 12:31:11 +0100 Subject: regulator: max8997: Avoid spaces in regulator names max8997-pmic instantiated from device tree uses names, not numerical ids to distinguish between outputs. Replace spaces with underscores in said names to make it possible to describe these outputs as regulators in DTS. Signed-off-by: Karol Lewandowski Signed-off-by: Kyungmin Park Signed-off-by: Mark Brown --- drivers/regulator/max8997.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index d26e8646277..bb7cd9df948 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c @@ -908,13 +908,13 @@ static struct regulator_desc regulators[] = { }, regulator_desc_buck(7), { - .name = "EN32KHz AP", + .name = "EN32KHz_AP", .id = MAX8997_EN32KHZ_AP, .ops = &max8997_fixedvolt_ops, .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, { - .name = "EN32KHz CP", + .name = "EN32KHz_CP", .id = MAX8997_EN32KHZ_CP, .ops = &max8997_fixedvolt_ops, .type = REGULATOR_VOLTAGE, @@ -938,7 +938,7 @@ static struct regulator_desc regulators[] = { .type = REGULATOR_VOLTAGE, .owner = THIS_MODULE, }, { - .name = "CHARGER CV", + .name = "CHARGER_CV", .id = MAX8997_CHARGER_CV, .ops = &max8997_fixedstate_ops, .type = REGULATOR_VOLTAGE, @@ -950,7 +950,7 @@ static struct regulator_desc regulators[] = { .type = REGULATOR_CURRENT, .owner = THIS_MODULE, }, { - .name = "CHARGER TOPOFF", + .name = "CHARGER_TOPOFF", .id = MAX8997_CHARGER_TOPOFF, .ops = &max8997_charger_fixedstate_ops, .type = REGULATOR_CURRENT, -- cgit v1.2.3-70-g09d2 From 47d505ccc7535c825f6b28aaaf105d4b75f25196 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Tue, 24 Jan 2012 15:03:04 -0500 Subject: orinoco_usb: remove version definition MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoids this: CC [M] drivers/net/wireless/orinoco/orinoco_usb.o drivers/net/wireless/orinoco/orinoco_usb.c:1759:13: warning: ‘version’ defined but not used Signed-off-by: John W. Linville --- drivers/net/wireless/orinoco/orinoco_usb.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c index ae8ce56670b..f634d4582bf 100644 --- a/drivers/net/wireless/orinoco/orinoco_usb.c +++ b/drivers/net/wireless/orinoco/orinoco_usb.c @@ -1754,11 +1754,6 @@ static struct usb_driver orinoco_driver = { .id_table = ezusb_table, }; -/* Can't be declared "const" or the whole __initdata section will - * become const */ -static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION - " (Manuel Estrada Sainz)"; - module_usb_driver(orinoco_driver); MODULE_AUTHOR("Manuel Estrada Sainz"); -- cgit v1.2.3-70-g09d2 From 2343933921efd553dea888fc844abb653824c4c8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 24 Jan 2012 18:37:16 -0200 Subject: regulator: mc13xxx-regulator-core: Fix the build when driver is selected as module Fix the following build error when mc138xxx driver is built as module: ERROR: "mc13xxx_parse_regulators_dt" [drivers/regulator/mc13892-regulator.ko] undefined! ERROR: "mc13xxx_get_num_regulators_dt" [drivers/regulator/mc13892-regulator.ko] undefined! Reported-by: Randy Dunlap Signed-off-by: Fabio Estevam Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx-regulator-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 80ecafef1bc..62dcd0a432b 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) return num; } +EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt); struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, @@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( return data; } +EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt); #endif MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 2897a563a55442379e5e59ec68c229a7f27fb7c6 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Sun, 8 Jan 2012 10:12:18 -0800 Subject: drivers: hv: Get rid of some unnecessary code The current code unnecessarily limits the number of offers we handle. Get rid of this limitation. As part of this cleanup, also get rid of an unused define - MAX_MSG_TYPES. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/channel_mgmt.c | 87 ----------------------------------------------- 1 file changed, 87 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c index 36484db36ba..9ffbfc575a0 100644 --- a/drivers/hv/channel_mgmt.c +++ b/drivers/hv/channel_mgmt.c @@ -37,81 +37,6 @@ struct vmbus_channel_message_table_entry { void (*message_handler)(struct vmbus_channel_message_header *msg); }; -#define MAX_MSG_TYPES 4 -#define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 - -static const uuid_le - supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { - /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ - /* Storage - SCSI */ - { - .b = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } - }, - - /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ - /* Network */ - { - .b = { - 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E - } - }, - - /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ - /* Input */ - { - .b = { - 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A - } - }, - - /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ - /* IDE */ - { - .b = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } - }, - /* 0E0B6031-5213-4934-818B-38D90CED39DB */ - /* Shutdown */ - { - .b = { - 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, - 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB - } - }, - /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ - /* TimeSync */ - { - .b = { - 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, - 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf - } - }, - /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ - /* Heartbeat */ - { - .b = { - 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, - 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d - } - }, - /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ - /* KVP */ - { - .b = { - 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, - 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 - } - }, - -}; - /** * vmbus_prep_negotiate_resp() - Create default response for Hyper-V Negotiate message @@ -321,20 +246,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) struct vmbus_channel *newchannel; uuid_le *guidtype; uuid_le *guidinstance; - int i; - int fsupported = 0; offer = (struct vmbus_channel_offer_channel *)hdr; - for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (!uuid_le_cmp(offer->offer.if_type, - supported_device_classes[i])) { - fsupported = 1; - break; - } - } - - if (!fsupported) - return; guidtype = &offer->offer.if_type; guidinstance = &offer->offer.if_instance; -- cgit v1.2.3-70-g09d2 From 593a27c4b212e2afdf772a1f8dcb894e91bda0fa Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 5 Jan 2012 13:04:21 +0400 Subject: tty: cleanup prohibition of direct opening for unix98 pty master cleanup hack added in v2.6.27-3203-g15582d3 comment from that patch: : pty: If the administrator creates a device for a ptmx slave we should not error : : The open path for ptmx slaves is via the ptmx device. Opening them any : other way is not allowed. Vegard Nossum found that previously this was not : the case and mknod foo c 128 42; cat foo would produce nasty diagnostics : : Signed-off-by: Alan Cox : Signed-off-by: Linus Torvalds devpts_get_tty() returns non-null only for inodes on devpts, but there is no inodes for master-devices, /dev/ptmx (/dev/pts/ptmx) is the only way to open them. Thus we can completely forbid lookup for master-devices and eliminate that hack in tty_init_dev() because tty_open() will get EIO from tty_driver_lookup_tty(). Signed-off-by: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 8 +++----- drivers/tty/tty_io.c | 12 ++---------- include/linux/tty.h | 3 +-- 3 files changed, 6 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d8653ab6f49..03147fa31d4 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -515,10 +515,8 @@ static int pty_unix98_ioctl(struct tty_struct *tty, static struct tty_struct *ptm_unix98_lookup(struct tty_driver *driver, struct inode *ptm_inode, int idx) { - struct tty_struct *tty = devpts_get_tty(ptm_inode, idx); - if (tty) - tty = tty->link; - return tty; + /* Master must be open via /dev/ptmx */ + return ERR_PTR(-EIO); } /** @@ -677,7 +675,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) mutex_lock(&tty_mutex); tty_lock(); - tty = tty_init_dev(ptm_driver, index, 1); + tty = tty_init_dev(ptm_driver, index); mutex_unlock(&tty_mutex); if (IS_ERR(tty)) { diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index e41b9bbc107..fbcc1406380 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1365,7 +1365,6 @@ static int tty_reopen(struct tty_struct *tty) * @driver: tty driver we are opening a device on * @idx: device index * @ret_tty: returned tty structure - * @first_ok: ok to open a new device (used by ptmx) * * Prepare a tty device. This may not be a "new" clean device but * could also be an active device. The pty drivers require special @@ -1385,18 +1384,11 @@ static int tty_reopen(struct tty_struct *tty) * relaxed for the (most common) case of reopening a tty. */ -struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, - int first_ok) +struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) { struct tty_struct *tty; int retval; - /* Check if pty master is being opened multiple times */ - if (driver->subtype == PTY_TYPE_MASTER && - (driver->flags & TTY_DRIVER_DEVPTS_MEM) && !first_ok) { - return ERR_PTR(-EIO); - } - /* * First time open is complex, especially for PTY devices. * This code guarantees that either everything succeeds and the @@ -1950,7 +1942,7 @@ retry_open: if (retval) tty = ERR_PTR(retval); } else - tty = tty_init_dev(driver, index, 0); + tty = tty_init_dev(driver, index); mutex_unlock(&tty_mutex); if (driver) diff --git a/include/linux/tty.h b/include/linux/tty.h index 5dbb3cb05a8..d3ebd765b54 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -480,8 +480,7 @@ extern void free_tty_struct(struct tty_struct *tty); extern void initialize_tty_struct(struct tty_struct *tty, struct tty_driver *driver, int idx); extern void deinitialize_tty_struct(struct tty_struct *tty); -extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx, - int first_ok); +extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); extern int tty_init_termios(struct tty_struct *tty); -- cgit v1.2.3-70-g09d2 From a4834c102f4a46808630cad1a545cb0706b3b0a2 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Thu, 5 Jan 2012 13:06:02 +0400 Subject: tty: move pty count limiting into devpts Let's move this stuff to the better place, where we can account pty right in tty-indexes managing code. Signed-off-by: Konstantin Khlebnikov Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 51 --------------------------------------------------- fs/devpts/inode.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index 03147fa31d4..d505837b347 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -439,55 +438,9 @@ static inline void legacy_pty_init(void) { } /* Unix98 devices */ #ifdef CONFIG_UNIX98_PTYS -/* - * sysctl support for setting limits on the number of Unix98 ptys allocated. - * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. - */ -int pty_limit = NR_UNIX98_PTY_DEFAULT; -static int pty_limit_min; -static int pty_limit_max = NR_UNIX98_PTY_MAX; -static int pty_count; static struct cdev ptmx_cdev; -static struct ctl_table pty_table[] = { - { - .procname = "max", - .maxlen = sizeof(int), - .mode = 0644, - .data = &pty_limit, - .proc_handler = proc_dointvec_minmax, - .extra1 = &pty_limit_min, - .extra2 = &pty_limit_max, - }, { - .procname = "nr", - .maxlen = sizeof(int), - .mode = 0444, - .data = &pty_count, - .proc_handler = proc_dointvec, - }, - {} -}; - -static struct ctl_table pty_kern_table[] = { - { - .procname = "pty", - .mode = 0555, - .child = pty_table, - }, - {} -}; - -static struct ctl_table pty_root_table[] = { - { - .procname = "kernel", - .mode = 0555, - .child = pty_kern_table, - }, - {} -}; - - static int pty_unix98_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { @@ -587,7 +540,6 @@ static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty) */ tty_driver_kref_get(driver); tty->count++; - pty_count++; return 0; err_free_mem: deinitialize_tty_struct(o_tty); @@ -601,7 +553,6 @@ err_free_tty: static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) { - pty_count--; } static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty) @@ -760,8 +711,6 @@ static void __init unix98_pty_init(void) if (tty_register_driver(pts_driver)) panic("Couldn't register Unix98 pts driver"); - register_sysctl_table(pty_root_table); - /* Now create the /dev/ptmx special device */ tty_default_fops(&ptmx_fops); ptmx_fops.open = ptmx_open; diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index c4e2a58a2e8..c2c7317d568 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -36,7 +36,52 @@ #define DEVPTS_DEFAULT_PTMX_MODE 0000 #define PTMX_MINOR 2 -extern int pty_limit; /* Config limit on Unix98 ptys */ +/* + * sysctl support for setting limits on the number of Unix98 ptys allocated. + * Otherwise one can eat up all kernel memory by opening /dev/ptmx repeatedly. + */ +static int pty_limit = NR_UNIX98_PTY_DEFAULT; +static int pty_limit_min; +static int pty_limit_max = NR_UNIX98_PTY_MAX; +static int pty_count; + +static struct ctl_table pty_table[] = { + { + .procname = "max", + .maxlen = sizeof(int), + .mode = 0644, + .data = &pty_limit, + .proc_handler = proc_dointvec_minmax, + .extra1 = &pty_limit_min, + .extra2 = &pty_limit_max, + }, { + .procname = "nr", + .maxlen = sizeof(int), + .mode = 0444, + .data = &pty_count, + .proc_handler = proc_dointvec, + }, + {} +}; + +static struct ctl_table pty_kern_table[] = { + { + .procname = "pty", + .mode = 0555, + .child = pty_table, + }, + {} +}; + +static struct ctl_table pty_root_table[] = { + { + .procname = "kernel", + .mode = 0555, + .child = pty_kern_table, + }, + {} +}; + static DEFINE_MUTEX(allocated_ptys_lock); static struct vfsmount *devpts_mnt; @@ -451,6 +496,7 @@ retry: mutex_unlock(&allocated_ptys_lock); return -EIO; } + pty_count++; mutex_unlock(&allocated_ptys_lock); return index; } @@ -462,6 +508,7 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx) mutex_lock(&allocated_ptys_lock); ida_remove(&fsi->allocated_ptys, idx); + pty_count--; mutex_unlock(&allocated_ptys_lock); } @@ -558,11 +605,15 @@ void devpts_pty_kill(struct tty_struct *tty) static int __init init_devpts_fs(void) { int err = register_filesystem(&devpts_fs_type); + struct ctl_table_header *table; + if (!err) { + table = register_sysctl_table(pty_root_table); devpts_mnt = kern_mount(&devpts_fs_type); if (IS_ERR(devpts_mnt)) { err = PTR_ERR(devpts_mnt); unregister_filesystem(&devpts_fs_type); + unregister_sysctl_table(table); } } return err; -- cgit v1.2.3-70-g09d2 From 1493138af1463112e42eebcdab5db61452821e97 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 5 Jan 2012 15:39:57 +0100 Subject: USB: code cleanup in suspend/resume path (3rd try) Do the cleanup to avoid behaviorial parameters Linus requested. Signed-off-by: Oliver Neukum Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 93 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 63 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d40ff956881..b7dfdecc7fd 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -958,13 +958,8 @@ void usb_rebind_intf(struct usb_interface *intf) int rc; /* Delayed unbind of an existing driver */ - if (intf->dev.driver) { - struct usb_driver *driver = - to_usb_driver(intf->dev.driver); - - dev_dbg(&intf->dev, "forced unbind\n"); - usb_driver_release_interface(driver, intf); - } + if (intf->dev.driver) + usb_forced_unbind_intf(intf); /* Try to rebind the interface */ if (!intf->dev.power.is_prepared) { @@ -977,15 +972,13 @@ void usb_rebind_intf(struct usb_interface *intf) #ifdef CONFIG_PM -#define DO_UNBIND 0 -#define DO_REBIND 1 - -/* Unbind drivers for @udev's interfaces that don't support suspend/resume, - * or rebind interfaces that have been unbound, according to @action. +/* Unbind drivers for @udev's interfaces that don't support suspend/resume + * There is no check for reset_resume here because it can be determined + * only during resume whether reset_resume is needed. * * The caller must hold @udev's device lock. */ -static void do_unbind_rebind(struct usb_device *udev, int action) +static void unbind_no_pm_drivers_interfaces(struct usb_device *udev) { struct usb_host_config *config; int i; @@ -996,23 +989,53 @@ static void do_unbind_rebind(struct usb_device *udev, int action) if (config) { for (i = 0; i < config->desc.bNumInterfaces; ++i) { intf = config->interface[i]; - switch (action) { - case DO_UNBIND: - if (intf->dev.driver) { - drv = to_usb_driver(intf->dev.driver); - if (!drv->suspend || !drv->resume) - usb_forced_unbind_intf(intf); - } - break; - case DO_REBIND: - if (intf->needs_binding) - usb_rebind_intf(intf); - break; + + if (intf->dev.driver) { + drv = to_usb_driver(intf->dev.driver); + if (!drv->suspend || !drv->resume) + usb_forced_unbind_intf(intf); } } } } +/* Unbind drivers for @udev's interfaces that failed to support reset-resume. + * These interfaces have the needs_binding flag set by usb_resume_interface(). + * + * The caller must hold @udev's device lock. + */ +static void unbind_no_reset_resume_drivers_interfaces(struct usb_device *udev) +{ + struct usb_host_config *config; + int i; + struct usb_interface *intf; + + config = udev->actconfig; + if (config) { + for (i = 0; i < config->desc.bNumInterfaces; ++i) { + intf = config->interface[i]; + if (intf->dev.driver && intf->needs_binding) + usb_forced_unbind_intf(intf); + } + } +} + +static void do_rebind_interfaces(struct usb_device *udev) +{ + struct usb_host_config *config; + int i; + struct usb_interface *intf; + + config = udev->actconfig; + if (config) { + for (i = 0; i < config->desc.bNumInterfaces; ++i) { + intf = config->interface[i]; + if (intf->needs_binding) + usb_rebind_intf(intf); + } + } +} + static int usb_suspend_device(struct usb_device *udev, pm_message_t msg) { struct usb_device_driver *udriver; @@ -1302,7 +1325,12 @@ int usb_suspend(struct device *dev, pm_message_t msg) { struct usb_device *udev = to_usb_device(dev); - do_unbind_rebind(udev, DO_UNBIND); + unbind_no_pm_drivers_interfaces(udev); + + /* From now on we are sure all drivers support suspend/resume + * but not necessarily reset_resume() + * so we may still need to unbind and rebind upon resume + */ choose_wakeup(udev, msg); return usb_suspend_both(udev, msg); } @@ -1313,15 +1341,20 @@ int usb_resume(struct device *dev, pm_message_t msg) struct usb_device *udev = to_usb_device(dev); int status; - /* For PM complete calls, all we do is rebind interfaces */ + /* For PM complete calls, all we do is rebind interfaces + * whose needs_binding flag is set + */ if (msg.event == PM_EVENT_ON) { if (udev->state != USB_STATE_NOTATTACHED) - do_unbind_rebind(udev, DO_REBIND); + do_rebind_interfaces(udev); status = 0; /* For all other calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. - * Unbind the interfaces that will need rebinding later. + * Unbind the interfaces that will need rebinding later, + * because they fail to support reset_resume. + * (This can't be done in usb_resume_interface() + * above because it doesn't own the right set of locks.) */ } else { status = usb_resume_both(udev, msg); @@ -1329,7 +1362,7 @@ int usb_resume(struct device *dev, pm_message_t msg) pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); - do_unbind_rebind(udev, DO_REBIND); + unbind_no_reset_resume_drivers_interfaces(udev); } } -- cgit v1.2.3-70-g09d2 From 98d9a82e5f753a2483d7b4638802d60e94e5d2e4 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 11 Jan 2012 08:38:35 +0100 Subject: USB: cleanup the handling of the PM complete call This eliminates the last instance of a function's behavior controlled by a parameter as Linus hates such things. Signed-off-by: Oliver Neukum Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 37 ++++++++++++++++++++----------------- drivers/usb/core/usb.c | 2 +- drivers/usb/core/usb.h | 1 + 3 files changed, 22 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index b7dfdecc7fd..d77daf3683d 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1336,34 +1336,37 @@ int usb_suspend(struct device *dev, pm_message_t msg) } /* The device lock is held by the PM core */ -int usb_resume(struct device *dev, pm_message_t msg) +int usb_resume_complete(struct device *dev) { - struct usb_device *udev = to_usb_device(dev); - int status; + struct usb_device *udev = to_usb_device(dev); /* For PM complete calls, all we do is rebind interfaces * whose needs_binding flag is set */ - if (msg.event == PM_EVENT_ON) { - if (udev->state != USB_STATE_NOTATTACHED) - do_rebind_interfaces(udev); - status = 0; + if (udev->state != USB_STATE_NOTATTACHED) + do_rebind_interfaces(udev); + return 0; +} - /* For all other calls, take the device back to full power and +/* The device lock is held by the PM core */ +int usb_resume(struct device *dev, pm_message_t msg) +{ + struct usb_device *udev = to_usb_device(dev); + int status; + + /* For all calls, take the device back to full power and * tell the PM core in case it was autosuspended previously. * Unbind the interfaces that will need rebinding later, * because they fail to support reset_resume. * (This can't be done in usb_resume_interface() - * above because it doesn't own the right set of locks.) + * above because it doesn't own the right set of locks.) */ - } else { - status = usb_resume_both(udev, msg); - if (status == 0) { - pm_runtime_disable(dev); - pm_runtime_set_active(dev); - pm_runtime_enable(dev); - unbind_no_reset_resume_drivers_interfaces(udev); - } + status = usb_resume_both(udev, msg); + if (status == 0) { + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + unbind_no_reset_resume_drivers_interfaces(udev); } /* Avoid PM error messages for devices disconnected while suspended diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 8ca9f994a28..c74ba7bbc74 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -274,7 +274,7 @@ static int usb_dev_prepare(struct device *dev) static void usb_dev_complete(struct device *dev) { /* Currently used only for rebinding interfaces */ - usb_resume(dev, PMSG_ON); /* FIXME: change to PMSG_COMPLETE */ + usb_resume_complete(dev); } static int usb_dev_suspend(struct device *dev) diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 45e8479c377..71648dcbe43 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -56,6 +56,7 @@ extern void usb_major_cleanup(void); extern int usb_suspend(struct device *dev, pm_message_t msg); extern int usb_resume(struct device *dev, pm_message_t msg); +extern int usb_resume_complete(struct device *dev); extern int usb_port_suspend(struct usb_device *dev, pm_message_t msg); extern int usb_port_resume(struct usb_device *dev, pm_message_t msg); -- cgit v1.2.3-70-g09d2 From 2851784f4d820bc697a8cc608509f9e3975c80e5 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Fri, 13 Jan 2012 19:04:17 +0100 Subject: usb/uhci: initialize sg_table properly Commit 689d6eac ("USB: UHCI: add native scatter-gather support(v1)) added sg support to uhci but forgot to set the sg_table so this feature remained unused. Cc: Ming Lei Signed-off-by: Sebastian Andrzej Siewior Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/uhci-hcd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 6b5eb1017e2..e37dea87bb5 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -565,6 +565,9 @@ static int uhci_start(struct usb_hcd *hcd) struct dentry __maybe_unused *dentry; hcd->uses_new_polling = 1; + /* Accept arbitrarily long scatter-gather lists */ + if (!(hcd->driver->flags & HCD_LOCAL_MEM)) + hcd->self.sg_tablesize = ~0; spin_lock_init(&uhci->lock); setup_timer(&uhci->fsbr_timer, uhci_fsbr_timeout, -- cgit v1.2.3-70-g09d2 From e73b2db6c9bc5bd9a3c080f286964e594351991a Mon Sep 17 00:00:00 2001 From: Huajun Li Date: Sat, 14 Jan 2012 10:15:21 +0800 Subject: usb: Disable dynamic id of USB storage subdrivers Storage subdrivers, like alauda, datafab and others, don't support dynamic id currently, and it needs lots of work but with very little gain to enable the feature, so disable them in the patch. Signed-off-by: Huajun Li Acked-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/alauda.c | 1 + drivers/usb/storage/cypress_atacb.c | 1 + drivers/usb/storage/datafab.c | 1 + drivers/usb/storage/ene_ub6250.c | 1 + drivers/usb/storage/freecom.c | 1 + drivers/usb/storage/isd200.c | 1 + drivers/usb/storage/jumpshot.c | 1 + drivers/usb/storage/karma.c | 1 + drivers/usb/storage/onetouch.c | 1 + drivers/usb/storage/realtek_cr.c | 1 + drivers/usb/storage/sddr09.c | 1 + drivers/usb/storage/sddr55.c | 1 + drivers/usb/storage/shuttle_usbat.c | 1 + 13 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 51af2fee2ef..bab8c8fe829 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -1276,6 +1276,7 @@ static struct usb_driver alauda_driver = { .post_reset = usb_stor_post_reset, .id_table = alauda_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(alauda_driver); diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 387cbd47acc..5fe451d16e6 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -272,6 +272,7 @@ static struct usb_driver cypress_driver = { .post_reset = usb_stor_post_reset, .id_table = cypress_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(cypress_driver); diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 15d41f2b3d6..35e9c51e669 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -751,6 +751,7 @@ static struct usb_driver datafab_driver = { .post_reset = usb_stor_post_reset, .id_table = datafab_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(datafab_driver); diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index a6ade4071a9..30532d93eec 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -2407,6 +2407,7 @@ static struct usb_driver ene_ub6250_driver = { .post_reset = usb_stor_post_reset, .id_table = ene_ub6250_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(ene_ub6250_driver); diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index fa161574847..042cf9ef315 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -553,6 +553,7 @@ static struct usb_driver freecom_driver = { .post_reset = usb_stor_post_reset, .id_table = freecom_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(freecom_driver); diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index bd550270083..31fa24e7e68 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -1566,6 +1566,7 @@ static struct usb_driver isd200_driver = { .post_reset = usb_stor_post_reset, .id_table = isd200_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(isd200_driver); diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index a19211b5c26..e3b97383186 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -677,6 +677,7 @@ static struct usb_driver jumpshot_driver = { .post_reset = usb_stor_post_reset, .id_table = jumpshot_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(jumpshot_driver); diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index e720f8ebdf9..a8708eae978 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -230,6 +230,7 @@ static struct usb_driver karma_driver = { .post_reset = usb_stor_post_reset, .id_table = karma_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(karma_driver); diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index d75155c3820..886567a3806 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -312,6 +312,7 @@ static struct usb_driver onetouch_driver = { .post_reset = usb_stor_post_reset, .id_table = onetouch_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(onetouch_driver); diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 1f62723ef1a..ccf271d2f67 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -1100,6 +1100,7 @@ static struct usb_driver realtek_cr_driver = { .id_table = realtek_cr_ids, .soft_unbind = 1, .supports_autosuspend = 1, + .no_dynamic_id = 1, }; module_usb_driver(realtek_cr_driver); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 425df7df2e5..3252a62b31b 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -1787,6 +1787,7 @@ static struct usb_driver sddr09_driver = { .post_reset = usb_stor_post_reset, .id_table = sddr09_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(sddr09_driver); diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index e4ca5fcb7cc..c144078065a 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -1006,6 +1006,7 @@ static struct usb_driver sddr55_driver = { .post_reset = usb_stor_post_reset, .id_table = sddr55_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(sddr55_driver); diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 1369d259061..fa1ceebc465 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1863,6 +1863,7 @@ static struct usb_driver usbat_driver = { .post_reset = usb_stor_post_reset, .id_table = usbat_usb_ids, .soft_unbind = 1, + .no_dynamic_id = 1, }; module_usb_driver(usbat_driver); -- cgit v1.2.3-70-g09d2 From fd7ff36d6a3f6413f838a2037b957b0e33ba9056 Mon Sep 17 00:00:00 2001 From: Huajun Li Date: Sat, 14 Jan 2012 10:16:40 +0800 Subject: usb: Re-enable usb-storage support dynamic id Enable usb-storage support dynamic id again by using a fixed id entry that describes a device using the Bulk-Only transport with the Transparent SCSI protocol. Signed-off-by: Huajun Li Reviewed-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3dd7da9fd50..58f56775ecd 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -125,6 +125,9 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { } /* Terminating entry */ }; +static struct us_unusual_dev for_dynamic_ids = + USUAL_DEV(USB_SC_SCSI, USB_PR_BULK, 0); + #undef UNUSUAL_DEV #undef COMPLIANT_DEV #undef USUAL_DEV @@ -1027,8 +1030,10 @@ EXPORT_SYMBOL_GPL(usb_stor_disconnect); static int storage_probe(struct usb_interface *intf, const struct usb_device_id *id) { + struct us_unusual_dev *unusual_dev; struct us_data *us; int result; + int size; /* * If libusual is configured, let it decide whether a standard @@ -1047,8 +1052,19 @@ static int storage_probe(struct usb_interface *intf, * table, so we use the index of the id entry to find the * corresponding unusual_devs entry. */ - result = usb_stor_probe1(&us, intf, id, - (id - usb_storage_usb_ids) + us_unusual_dev_list); + + size = ARRAY_SIZE(us_unusual_dev_list); + if (id >= usb_storage_usb_ids && id < usb_storage_usb_ids + size) { + unusual_dev = (id - usb_storage_usb_ids) + us_unusual_dev_list; + } else { + unusual_dev = &for_dynamic_ids; + + US_DEBUGP("%s %s 0x%04x 0x%04x\n", "Use Bulk-Only transport", + "with the Transparent SCSI protocol for dynamic id:", + id->idVendor, id->idProduct); + } + + result = usb_stor_probe1(&us, intf, id, unusual_dev); if (result) return result; @@ -1074,7 +1090,6 @@ static struct usb_driver usb_storage_driver = { .id_table = usb_storage_usb_ids, .supports_autosuspend = 1, .soft_unbind = 1, - .no_dynamic_id = 1, }; static int __init usb_stor_init(void) -- cgit v1.2.3-70-g09d2 From 0b238583ac8db66762bba021de1b7c60b6bc29ad Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Mon, 16 Jan 2012 00:36:47 +0100 Subject: USB: cp210x: fix debug output Remove superfluous newlines from debug statements. Remove unnecessary line breaks. Signed-off-by: Johan Hovold Cc: Preston Fick Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index fba1147ed91..92aadd889a6 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -279,7 +279,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, if (result != size) { dbg("%s - Unable to send config request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -333,7 +333,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, if ((size > 2 && result != size) || result < 0) { dbg("%s - Unable to send request, " - "request=0x%x size=%d result=%d\n", + "request=0x%x size=%d result=%d", __func__, request, size, result); if (result > 0) result = -EPROTO; @@ -636,13 +636,13 @@ static void cp210x_set_termios(struct tty_struct *tty, default: dbg("cp210x driver does not " "support the number of bits requested," - " using 8 bit mode\n"); + " using 8 bit mode"); bits |= BITS_DATA_8; break; } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of data bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & (PARENB|PARODD|CMSPAR)) != @@ -669,8 +669,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) - dbg("Parity mode not supported " - "by device\n"); + dbg("Parity mode not supported by device"); } if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { @@ -685,7 +684,7 @@ static void cp210x_set_termios(struct tty_struct *tty, } if (cp210x_set_config(port, CP210X_SET_LINE_CTL, &bits, 2)) dbg("Number of stop bits requested " - "not supported by device\n"); + "not supported by device"); } if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { -- cgit v1.2.3-70-g09d2 From 19b85b3b87fd1388df1f4a35969823521d35d243 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:11:58 +0100 Subject: USB: cdc-wdm: no need to fill the in request URB every time it's submitted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Filling the same URB with the exact same data is pointless. It can be filled once and resubmitted. And not doing buffer allocation and URB filling at the same place only serves to hide size mismatch bugs Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 1c50baff772..9734863a3a4 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -159,11 +159,9 @@ static void wdm_int_callback(struct urb *urb) int rv = 0; int status = urb->status; struct wdm_device *desc; - struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; - req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { @@ -210,24 +208,6 @@ static void wdm_int_callback(struct urb *urb) goto exit; } - req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); - req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; - req->wValue = 0; - req->wIndex = desc->inum; - req->wLength = cpu_to_le16(desc->wMaxCommand); - - usb_fill_control_urb( - desc->response, - interface_to_usbdev(desc->intf), - /* using common endpoint 0 */ - usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), - (unsigned char *)req, - desc->inbuf, - desc->wMaxCommand, - wdm_in_callback, - desc - ); - desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); @@ -734,6 +714,25 @@ next_desc: ); desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); + desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; + desc->irq->wValue = 0; + desc->irq->wIndex = desc->inum; + desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); + + usb_fill_control_urb( + desc->response, + interface_to_usbdev(desc->intf), + /* using common endpoint 0 */ + usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), + (unsigned char *)desc->irq, + desc->inbuf, + desc->wMaxCommand, + wdm_in_callback, + desc + ); + desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) -- cgit v1.2.3-70-g09d2 From cafbe85fb0d00d32988905c4978df433ca9b6512 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:11:59 +0100 Subject: USB: cdc-wdm: better allocate a buffer that is at least as big as we tell the USB core MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As it turns out, there was a mismatch between the allocated inbuf size (desc->bMaxPacketSize0, typically something like 64) and the length we specified in the URB (desc->wMaxCommand, typically something like 2048) Signed-off-by: Bjørn Mork Cc: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 9734863a3a4..846dfa60344 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -696,7 +696,7 @@ next_desc: goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->bMaxPacketSize0, + desc->wMaxCommand, GFP_KERNEL, &desc->response->transfer_dma); if (!desc->inbuf) -- cgit v1.2.3-70-g09d2 From 8457d99cab81e91724b43363f7fccd851d766187 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:12:00 +0100 Subject: USB: cdc-wdm: no need to use usb_alloc_coherent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As Documentation/usb/dma.txt states: Most drivers should *NOT* be using these primitives; they don't need to use this type of memory (dma-coherent), and memory returned from kmalloc() will work just fine. This driver handle only very low bandwith transfers. It is not an obvious candidate for usb_alloc_coherent(). Using these calls only serves to complicate the code for no gain, as has been shown by multiple bugs related to this allocation path. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 39 +++++++++------------------------------ 1 file changed, 9 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 846dfa60344..8909058b1bb 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -256,14 +256,8 @@ static void free_urbs(struct wdm_device *desc) static void cleanup(struct wdm_device *desc) { - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->wMaxPacketSize, - desc->sbuf, - desc->validity->transfer_dma); - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->bMaxPacketSize0, - desc->inbuf, - desc->response->transfer_dma); + kfree(desc->sbuf); + kfree(desc->inbuf); kfree(desc->orq); kfree(desc->irq); kfree(desc->ubuf); @@ -688,19 +682,13 @@ next_desc: if (!desc->ubuf) goto err; - desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxPacketSize, - GFP_KERNEL, - &desc->validity->transfer_dma); + desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL); if (!desc->sbuf) goto err; - desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), - desc->wMaxCommand, - GFP_KERNEL, - &desc->response->transfer_dma); + desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); if (!desc->inbuf) - goto err2; + goto err; usb_fill_int_urb( desc->validity, @@ -712,7 +700,6 @@ next_desc: desc, ep->bInterval ); - desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; @@ -731,30 +718,22 @@ next_desc: wdm_in_callback, desc ); - desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) - goto err3; + goto err2; else dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", intf->minor - WDM_MINOR_BASE); out: return rv; -err3: - usb_set_intfdata(intf, NULL); - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->bMaxPacketSize0, - desc->inbuf, - desc->response->transfer_dma); err2: - usb_free_coherent(interface_to_usbdev(desc->intf), - desc->wMaxPacketSize, - desc->sbuf, - desc->validity->transfer_dma); + usb_set_intfdata(intf, NULL); err: free_urbs(desc); + kfree(desc->inbuf); + kfree(desc->sbuf); kfree(desc->ubuf); kfree(desc->orq); kfree(desc->irq); -- cgit v1.2.3-70-g09d2 From 8143a8963c374116f84aba15dcaeaf02370c8098 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 16 Jan 2012 15:12:01 +0100 Subject: USB: cdc-wdm: kill the now unnecessary bMaxPacketSize0 field and udev variable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We don't need bMaxPacketSize0, and keeping all these different size fields around will only cause us to use the wrong one. Seems the udev variable was only used for getting bMaxPacketSize0. We could have used it for the usb_fill_*_urb() calls, but as it wasn't before - why start now? Instead make the interface_to_usbdev() calls consistent. Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 8909058b1bb..bb8208a13a5 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -80,7 +80,6 @@ struct wdm_device { u16 bufsize; u16 wMaxCommand; u16 wMaxPacketSize; - u16 bMaxPacketSize0; __le16 inum; int reslength; int length; @@ -597,7 +596,6 @@ static void wdm_rxwork(struct work_struct *work) static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) { int rv = -EINVAL; - struct usb_device *udev = interface_to_usbdev(intf); struct wdm_device *desc; struct usb_host_interface *iface; struct usb_endpoint_descriptor *ep; @@ -657,7 +655,6 @@ next_desc: goto err; desc->wMaxPacketSize = usb_endpoint_maxp(ep); - desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) @@ -709,7 +706,7 @@ next_desc: usb_fill_control_urb( desc->response, - interface_to_usbdev(desc->intf), + interface_to_usbdev(intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)desc->irq, -- cgit v1.2.3-70-g09d2 From 7e3054a005537f28544ab2870c375458362f7473 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 20 Jan 2012 01:49:57 +0100 Subject: USB: cdc-wdm: Avoid hanging on interface with no USB_CDC_DMM_TYPE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The probe does not strictly require the USB_CDC_DMM_TYPE descriptor, which is a good thing as it makes the driver usable on non-conforming interfaces. A user could e.g. bind to it to a CDC ECM interface by using the new_id and bind sysfs files. But this would fail with a 0 buffer length due to the missing descriptor. Fix by defining a reasonable fallback size: The minimum device receive buffer size required by the CDC WMC standard, revision 1.1 Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index bb8208a13a5..c0197af22fd 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -57,6 +57,8 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_MAX 16 +/* CDC-WMC r1.1 requires wMaxCommand to be "at least 256 decimal (0x100)" */ +#define WDM_DEFAULT_BUFSIZE 256 static DEFINE_MUTEX(wdm_mutex); @@ -602,7 +604,7 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) struct usb_cdc_dmm_desc *dmhd; u8 *buffer = intf->altsetting->extra; int buflen = intf->altsetting->extralen; - u16 maxcom = 0; + u16 maxcom = WDM_DEFAULT_BUFSIZE; if (!buffer) goto out; -- cgit v1.2.3-70-g09d2 From 820c629a595ad8d8f2694641e494738b18d29e7b Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Fri, 20 Jan 2012 04:17:25 +0100 Subject: USB: cdc-wdm: avoid printing odd-looking "cdc-wdm-176" names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit usb_register_dev() will change our .minor_base to 0 if CONFIG_USB_DYNAMIC_MINORS is set. And it usually is, of course. Use dev_name() to print the proper interface name instead Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c0197af22fd..c154d4f1d67 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -723,8 +723,7 @@ next_desc: if (rv < 0) goto err2; else - dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", - intf->minor - WDM_MINOR_BASE); + dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); out: return rv; err2: -- cgit v1.2.3-70-g09d2 From 761bbcb74e4611414937ea480ba60bb970648755 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Tue, 24 Jan 2012 22:17:38 +0100 Subject: usb: ehci-fsl: set INCR8 mode for system bus interface on MPC512x Use INCR8 mode for system bus interface of the USB controller on MPC512x. This is a work-around for the AHB bus lock up problem observed on MPC512x when there is heavy simultaneous PATA write or network (FEC) activity. See also "12.4 The USB controller can issue transactions that lock up the AHB bus under certain conditions" in MPC5121e (M36P) Errata. Signed-off-by: Anatolij Gustschin Tested-by: Matthias Fuchs Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 14 ++++++++++++++ drivers/usb/host/ehci-fsl.h | 2 ++ 2 files changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index e90344a1763..42414cd7357 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -316,7 +316,9 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) struct ehci_hcd *ehci = hcd_to_ehci(hcd); int retval; struct fsl_usb2_platform_data *pdata; + struct device *dev; + dev = hcd->self.controller; pdata = hcd->self.controller->platform_data; ehci->big_endian_desc = pdata->big_endian_desc; ehci->big_endian_mmio = pdata->big_endian_mmio; @@ -346,6 +348,16 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) ehci_reset(ehci); + if (of_device_is_compatible(dev->parent->of_node, + "fsl,mpc5121-usb2-dr")) { + /* + * set SBUSCFG:AHBBRST so that control msgs don't + * fail when doing heavy PATA writes. + */ + ehci_writel(ehci, SBUSCFG_INCR8, + hcd->regs + FSL_SOC_USB_SBUSCFG); + } + retval = ehci_fsl_reinit(ehci); return retval; } @@ -469,6 +481,8 @@ static int ehci_fsl_mpc512x_drv_resume(struct device *dev) ehci_writel(ehci, ISIPHYCTRL_PXE | ISIPHYCTRL_PHYE, hcd->regs + FSL_SOC_USB_ISIPHYCTRL); + ehci_writel(ehci, SBUSCFG_INCR8, hcd->regs + FSL_SOC_USB_SBUSCFG); + /* restore EHCI registers */ ehci_writel(ehci, pdata->pm_command, &ehci->regs->command); ehci_writel(ehci, pdata->pm_intr_enable, &ehci->regs->intr_enable); diff --git a/drivers/usb/host/ehci-fsl.h b/drivers/usb/host/ehci-fsl.h index 49180622116..0855be8b5b4 100644 --- a/drivers/usb/host/ehci-fsl.h +++ b/drivers/usb/host/ehci-fsl.h @@ -19,6 +19,8 @@ #define _EHCI_FSL_H /* offsets for the non-ehci registers in the FSL SOC USB controller */ +#define FSL_SOC_USB_SBUSCFG 0x90 +#define SBUSCFG_INCR8 0x02 /* INCR8, specified */ #define FSL_SOC_USB_ULPIVP 0x170 #define FSL_SOC_USB_PORTSC1 0x184 #define PORT_PTS_MSK (3<<30) -- cgit v1.2.3-70-g09d2 From f30cdbcb2e6a7b9cdebe2117a7b623a5b3832a75 Mon Sep 17 00:00:00 2001 From: Kelvin Cheung Date: Wed, 18 Jan 2012 14:41:16 +0800 Subject: USB: Add EHCI bus glue for Loongson1x SoCs (UPDATED) Use ehci_setup() in ehci_ls1x_reset(). The Loongson1x SoCs have a built-in EHCI controller. This patch adds the necessary glue code to make the generic EHCI driver usable for them. Signed-off-by: Kelvin Cheung Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + drivers/usb/host/ehci-hcd.c | 5 ++ drivers/usb/host/ehci-ls1x.c | 159 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 drivers/usb/host/ehci-ls1x.c (limited to 'drivers') diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 75823a1abeb..0b0afc81a54 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -76,6 +76,7 @@ config USB_ARCH_HAS_EHCI default y if MICROBLAZE default y if SPARC_LEON default y if ARCH_MMP + default y if MACH_LOONGSON1 default PCI # some non-PCI HCDs implement xHCI diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index a007a9fe0f8..4918b0c59af 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1376,6 +1376,11 @@ MODULE_LICENSE ("GPL"); #define PLATFORM_DRIVER ehci_mv_driver #endif +#ifdef CONFIG_MACH_LOONGSON1 +#include "ehci-ls1x.c" +#define PLATFORM_DRIVER ehci_ls1x_driver +#endif + #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \ !defined(XILINX_OF_PLATFORM_DRIVER) diff --git a/drivers/usb/host/ehci-ls1x.c b/drivers/usb/host/ehci-ls1x.c new file mode 100644 index 00000000000..a283e59709d --- /dev/null +++ b/drivers/usb/host/ehci-ls1x.c @@ -0,0 +1,159 @@ +/* + * Bus Glue for Loongson LS1X built-in EHCI controller. + * + * Copyright (c) 2012 Zhang, Keguang + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation. + */ + + +#include + +static int ehci_ls1x_reset(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int ret; + + ehci->caps = hcd->regs; + + ret = ehci_setup(hcd); + if (ret) + return ret; + + ehci_port_power(ehci, 0); + + return 0; +} + +static const struct hc_driver ehci_ls1x_hc_driver = { + .description = hcd_name, + .product_desc = "LOONGSON1 EHCI", + .hcd_priv_size = sizeof(struct ehci_hcd), + + /* + * generic hardware linkage + */ + .irq = ehci_irq, + .flags = HCD_MEMORY | HCD_USB2, + + /* + * basic lifecycle operations + */ + .reset = ehci_ls1x_reset, + .start = ehci_run, + .stop = ehci_stop, + .shutdown = ehci_shutdown, + + /* + * managing i/o requests and associated device resources + */ + .urb_enqueue = ehci_urb_enqueue, + .urb_dequeue = ehci_urb_dequeue, + .endpoint_disable = ehci_endpoint_disable, + .endpoint_reset = ehci_endpoint_reset, + + /* + * scheduling support + */ + .get_frame_number = ehci_get_frame, + + /* + * root hub support + */ + .hub_status_data = ehci_hub_status_data, + .hub_control = ehci_hub_control, + .relinquish_port = ehci_relinquish_port, + .port_handed_over = ehci_port_handed_over, + + .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, +}; + +static int ehci_hcd_ls1x_probe(struct platform_device *pdev) +{ + struct usb_hcd *hcd; + struct resource *res; + int irq; + int ret; + + pr_debug("initializing loongson1 ehci USB Controller\n"); + + if (usb_disabled()) + return -ENODEV; + + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no IRQ. Check %s setup!\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + irq = res->start; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, + "Found HC with no register addr. Check %s setup!\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + hcd = usb_create_hcd(&ehci_ls1x_hc_driver, &pdev->dev, + dev_name(&pdev->dev)); + if (!hcd) + return -ENOMEM; + hcd->rsrc_start = res->start; + hcd->rsrc_len = resource_size(res); + + if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { + dev_dbg(&pdev->dev, "controller already in use\n"); + ret = -EBUSY; + goto err_put_hcd; + } + + hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); + if (hcd->regs == NULL) { + dev_dbg(&pdev->dev, "error mapping memory\n"); + ret = -EFAULT; + goto err_release_region; + } + + ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED); + if (ret) + goto err_iounmap; + + return ret; + +err_iounmap: + iounmap(hcd->regs); +err_release_region: + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); +err_put_hcd: + usb_put_hcd(hcd); + return ret; +} + +static int ehci_hcd_ls1x_remove(struct platform_device *pdev) +{ + struct usb_hcd *hcd = platform_get_drvdata(pdev); + + usb_remove_hcd(hcd); + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); + + return 0; +} + +static struct platform_driver ehci_ls1x_driver = { + .probe = ehci_hcd_ls1x_probe, + .remove = ehci_hcd_ls1x_remove, + .shutdown = usb_hcd_platform_shutdown, + .driver = { + .name = "ls1x-ehci", + .owner = THIS_MODULE, + }, +}; + +MODULE_ALIAS(PLATFORM_MODULE_PREFIX "ls1x-ehci"); -- cgit v1.2.3-70-g09d2 From 2b31594a9523449b168946725689d039c80204de Mon Sep 17 00:00:00 2001 From: Jonghwan Choi Date: Sat, 14 Jan 2012 11:06:03 +0900 Subject: driver-core: Fix possible null reference in subsys_interface_unregister Check if the sif is not NULL before de-referencing it Signed-off-by: Jonghwan Choi Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 99dc5921e1d..4ddb38b696f 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -1193,13 +1193,15 @@ EXPORT_SYMBOL_GPL(subsys_interface_register); void subsys_interface_unregister(struct subsys_interface *sif) { - struct bus_type *subsys = sif->subsys; + struct bus_type *subsys; struct subsys_dev_iter iter; struct device *dev; - if (!sif) + if (!sif || !sif->subsys) return; + subsys = sif->subsys; + mutex_lock(&subsys->p->mutex); list_del_init(&sif->node); if (sif->remove_dev) { -- cgit v1.2.3-70-g09d2 From fde25a9b63b9a3dc91365c394a426ebe64cfc2da Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:34:24 -0500 Subject: Driver core: driver_find() drops reference before returning As part of the removal of get_driver()/put_driver(), this patch (as1510) changes driver_find(); it now drops the reference it acquires before returning. The patch also adjusts all the callers of driver_find() to remove the now unnecessary calls to put_driver(). In addition, the patch adds a warning to driver_find(): Callers must make sure the driver they are searching for does not get unloaded while they are using it. This has always been the case; driver_find() has never prevented a driver from being unregistered or unloaded. Hence the patch will not introduce any new bugs. The existing callers all seem to be okay in this respect, however I don't understand the video drivers well enough to be certain about them. Signed-off-by: Alan Stern CC: Dmitry Torokhov CC: Kyungmin Park CC: Andy Walls CC: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 7 +++++-- drivers/input/gameport/gameport.c | 1 - drivers/input/serio/serio.c | 1 - drivers/media/video/cx18/cx18-alsa-main.c | 1 - drivers/media/video/ivtv/ivtvfb.c | 2 -- drivers/media/video/s5p-fimc/fimc-mdevice.c | 5 +---- drivers/media/video/s5p-tv/mixer_video.c | 1 - drivers/s390/net/smsgiucv_app.c | 9 ++++----- 8 files changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index b631f7c5945..e979cad75c6 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -234,7 +234,6 @@ int driver_register(struct device_driver *drv) other = driver_find(drv->name, drv->bus); if (other) { - put_driver(other); printk(KERN_ERR "Error: Driver '%s' is already registered, " "aborting...\n", drv->name); return -EBUSY; @@ -275,7 +274,9 @@ EXPORT_SYMBOL_GPL(driver_unregister); * Call kset_find_obj() to iterate over list of drivers on * a bus to find driver by name. Return driver if found. * - * Note that kset_find_obj increments driver's reference count. + * This routine provides no locking to prevent the driver it returns + * from being unregistered or unloaded while the caller is using it. + * The caller is responsible for preventing this. */ struct device_driver *driver_find(const char *name, struct bus_type *bus) { @@ -283,6 +284,8 @@ struct device_driver *driver_find(const char *name, struct bus_type *bus) struct driver_private *priv; if (k) { + /* Drop reference added by kset_find_obj() */ + kobject_put(k); priv = to_driver(k); return priv->driver; } diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index c351aa421f8..da739d9d190 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -449,7 +449,6 @@ static ssize_t gameport_rebind_driver(struct device *dev, struct device_attribut } else if ((drv = driver_find(buf, &gameport_bus)) != NULL) { gameport_disconnect_port(gameport); error = gameport_bind_driver(gameport, to_gameport_driver(drv)); - put_driver(drv); } else { error = -EINVAL; } diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index ba70058e2be..d0f7533dbf8 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -441,7 +441,6 @@ static ssize_t serio_rebind_driver(struct device *dev, struct device_attribute * } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { serio_disconnect_port(serio); error = serio_bind_driver(serio, to_serio_driver(drv)); - put_driver(drv); serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); } else { error = -EINVAL; diff --git a/drivers/media/video/cx18/cx18-alsa-main.c b/drivers/media/video/cx18/cx18-alsa-main.c index a1e6c2a3247..e118361c2e7 100644 --- a/drivers/media/video/cx18/cx18-alsa-main.c +++ b/drivers/media/video/cx18/cx18-alsa-main.c @@ -285,7 +285,6 @@ static void __exit cx18_alsa_exit(void) drv = driver_find("cx18", &pci_bus_type); ret = driver_for_each_device(drv, NULL, NULL, cx18_alsa_exit_callback); - put_driver(drv); cx18_ext_init = NULL; printk(KERN_INFO "cx18-alsa: module unload complete\n"); diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c index d0fbfcf7133..e5e7fa9e737 100644 --- a/drivers/media/video/ivtv/ivtvfb.c +++ b/drivers/media/video/ivtv/ivtvfb.c @@ -1293,7 +1293,6 @@ static int __init ivtvfb_init(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, ®istered, ivtvfb_callback_init); - put_driver(drv); if (!registered) { printk(KERN_ERR "ivtvfb: no cards found\n"); return -ENODEV; @@ -1310,7 +1309,6 @@ static void ivtvfb_cleanup(void) drv = driver_find("ivtv", &pci_bus_type); err = driver_for_each_device(drv, NULL, NULL, ivtvfb_callback_cleanup); - put_driver(drv); } module_init(ivtvfb_init); diff --git a/drivers/media/video/s5p-fimc/fimc-mdevice.c b/drivers/media/video/s5p-fimc/fimc-mdevice.c index 8ea4ee116e4..63eccb55728 100644 --- a/drivers/media/video/s5p-fimc/fimc-mdevice.c +++ b/drivers/media/video/s5p-fimc/fimc-mdevice.c @@ -344,16 +344,13 @@ static int fimc_md_register_platform_entities(struct fimc_md *fmd) return -ENODEV; ret = driver_for_each_device(driver, NULL, fmd, fimc_register_callback); - put_driver(driver); if (ret) return ret; driver = driver_find(CSIS_DRIVER_NAME, &platform_bus_type); - if (driver) { + if (driver) ret = driver_for_each_device(driver, NULL, fmd, csis_register_callback); - put_driver(driver); - } return ret; } diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c index 7884baeff76..f7ca5cc143c 100644 --- a/drivers/media/video/s5p-tv/mixer_video.c +++ b/drivers/media/video/s5p-tv/mixer_video.c @@ -58,7 +58,6 @@ static struct v4l2_subdev *find_and_register_subdev( } done: - put_driver(drv); return sd; } diff --git a/drivers/s390/net/smsgiucv_app.c b/drivers/s390/net/smsgiucv_app.c index 4d2ea400042..32515a201bb 100644 --- a/drivers/s390/net/smsgiucv_app.c +++ b/drivers/s390/net/smsgiucv_app.c @@ -168,7 +168,7 @@ static int __init smsgiucv_app_init(void) rc = dev_set_name(smsg_app_dev, KMSG_COMPONENT); if (rc) { kfree(smsg_app_dev); - goto fail_put_driver; + goto fail; } smsg_app_dev->bus = &iucv_bus; smsg_app_dev->parent = iucv_root; @@ -177,7 +177,7 @@ static int __init smsgiucv_app_init(void) rc = device_register(smsg_app_dev); if (rc) { put_device(smsg_app_dev); - goto fail_put_driver; + goto fail; } /* convert sender to uppercase characters */ @@ -191,12 +191,11 @@ static int __init smsgiucv_app_init(void) rc = smsg_register_callback(SMSG_PREFIX, smsg_app_callback); if (rc) { device_unregister(smsg_app_dev); - goto fail_put_driver; + goto fail; } rc = 0; -fail_put_driver: - put_driver(smsgiucv_drv); +fail: return rc; } module_init(smsgiucv_app_init); -- cgit v1.2.3-70-g09d2 From cef9bc56e1e944afd11f96de569657117a138c6d Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:34:41 -0500 Subject: Dynamic ID addition doesn't need get_driver() As part of the removal of get_driver()/put_driver(), this patch (as1511) changes all the places that add dynamic IDs for drivers. Since these additions are done by writing to the drivers' sysfs attribute files, and the attributes are removed when the drivers are unregistered, there is no reason to take an extra reference to the drivers. The one exception is the pci-stub driver, which calls pci_add_dynid() as part of its registration. But again, there's no reason to take an extra reference here, because the driver can't be unloaded while it is being registered. Signed-off-by: Alan Stern CC: Dmitry Torokhov CC: Jiri Kosina CC: Jesse Barnes CC: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/hid/hid-core.c | 6 +----- drivers/pci/pci-driver.c | 2 -- drivers/pcmcia/ds.c | 5 +---- drivers/usb/core/driver.c | 5 +---- 4 files changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7207d..bce53fa0e16 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1619,11 +1619,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf, list_add_tail(&dynid->list, &hdrv->dyn_list); spin_unlock(&hdrv->dyn_lock); - ret = 0; - if (get_driver(&hdrv->driver)) { - ret = driver_attach(&hdrv->driver); - put_driver(&hdrv->driver); - } + ret = driver_attach(&hdrv->driver); return ret ? : count; } diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 3623d65f8b8..ff540477fe8 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -72,9 +72,7 @@ int pci_add_dynid(struct pci_driver *drv, list_add_tail(&dynid->node, &drv->dynids.list); spin_unlock(&drv->dynids.lock); - get_driver(&drv->driver); retval = driver_attach(&drv->driver); - put_driver(&drv->driver); return retval; } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 749c2a16012..059699f6363 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -127,10 +127,7 @@ pcmcia_store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&dynid->node, &pdrv->dynids.list); mutex_unlock(&pdrv->dynids.lock); - if (get_driver(&pdrv->drv)) { - retval = driver_attach(&pdrv->drv); - put_driver(&pdrv->drv); - } + retval = driver_attach(&pdrv->drv); if (retval) return retval; diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d40ff956881..54c493b4226 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -71,10 +71,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, list_add_tail(&dynid->node, &dynids->list); spin_unlock(&dynids->lock); - if (get_driver(driver)) { - retval = driver_attach(driver); - put_driver(driver); - } + retval = driver_attach(driver); if (retval) return retval; -- cgit v1.2.3-70-g09d2 From 9f30ea950edfaefa51221dd26a065b3442599778 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Tue, 24 Jan 2012 13:35:02 -0500 Subject: cio: remove {get,put}_driver Remove useless {get,put}_driver - the caller of the functions has to ensure valid driver pointers. Signed-off-by: Sebastian Ott Signed-off-by: Alan Stern CC: Martin Schwidefsky Signed-off-by: Greg Kroah-Hartman --- drivers/s390/cio/ccwgroup.c | 2 -- drivers/s390/cio/device.c | 8 +------- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index 4f1989d27b1..5f1dc6fb570 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -580,7 +580,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) struct device *dev; /* We don't want ccwgroup devices to live longer than their driver. */ - get_driver(&cdriver->driver); while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, __ccwgroup_match_all))) { struct ccwgroup_device *gdev = to_ccwgroupdev(dev); @@ -592,7 +591,6 @@ void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver) mutex_unlock(&gdev->reg_mutex); put_device(dev); } - put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); } EXPORT_SYMBOL(ccwgroup_driver_unregister); diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 47269858ecb..02d01525946 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -1676,15 +1676,9 @@ struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id) { struct device *dev; - struct device_driver *drv; - drv = get_driver(&cdrv->driver); - if (!drv) - return NULL; - - dev = driver_find_device(drv, NULL, (void *)bus_id, + dev = driver_find_device(&cdrv->driver, NULL, (void *)bus_id, __ccwdev_check_busid); - put_driver(drv); return dev ? to_ccwdev(dev) : NULL; } -- cgit v1.2.3-70-g09d2 From f3ff9247088a0af0c192a28908dab76ff3d8871f Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:35:24 -0500 Subject: Remove useless get_driver()/put_driver() calls As part of the removal of get_driver()/put_driver(), this patch (as1512) gets rid of various useless and unnecessary calls in several drivers. In some cases it may be desirable to pin the driver by calling try_module_get(), but that can be done later. Signed-off-by: Alan Stern CC: "David S. Miller" CC: Konrad Rzeszutek Wilk CC: Michael Buesch CC: Joerg Roedel Signed-off-by: Greg Kroah-Hartman --- drivers/net/phy/phy_device.c | 6 +----- drivers/pci/xen-pcifront.c | 3 +-- drivers/ssb/main.c | 20 ++------------------ lib/dma-debug.c | 3 +-- 4 files changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index f320f466f03..e8c42d6a7d1 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -915,9 +915,7 @@ static int phy_probe(struct device *dev) phydev = to_phy_device(dev); - /* Make sure the driver is held. - * XXX -- Is this correct? */ - drv = get_driver(phydev->dev.driver); + drv = phydev->dev.driver; phydrv = to_phy_driver(drv); phydev->drv = phydrv; @@ -957,8 +955,6 @@ static int phy_remove(struct device *dev) if (phydev->drv->remove) phydev->drv->remove(phydev); - - put_driver(dev->driver); phydev->drv = NULL; return 0; diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 7cf3d2fcf56..6f819988a8d 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } pdrv = pcidev->driver; - if (get_driver(&pdrv->driver)) { + if (pdrv->driver) { if (pdrv->err_handler && pdrv->err_handler->error_detected) { dev_dbg(&pcidev->dev, "trying to call AER service\n"); @@ -623,7 +623,6 @@ static pci_ers_result_t pcifront_common_process(int cmd, } } } - put_driver(&pdrv->driver); } if (!flag) result = PCI_ERS_RESULT_NONE; diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index bb6317fb925..ff109ae9476 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -140,19 +140,6 @@ static void ssb_device_put(struct ssb_device *dev) put_device(dev->dev); } -static inline struct ssb_driver *ssb_driver_get(struct ssb_driver *drv) -{ - if (drv) - get_driver(&drv->drv); - return drv; -} - -static inline void ssb_driver_put(struct ssb_driver *drv) -{ - if (drv) - put_driver(&drv->drv); -} - static int ssb_device_resume(struct device *dev) { struct ssb_device *ssb_dev = dev_to_ssb_dev(dev); @@ -250,11 +237,9 @@ int ssb_devices_freeze(struct ssb_bus *bus, struct ssb_freeze_context *ctx) ssb_device_put(sdev); continue; } - sdrv = ssb_driver_get(drv_to_ssb_drv(sdev->dev->driver)); - if (!sdrv || SSB_WARN_ON(!sdrv->remove)) { - ssb_device_put(sdev); + sdrv = drv_to_ssb_drv(sdev->dev->driver); + if (SSB_WARN_ON(!sdrv->remove)) continue; - } sdrv->remove(sdev); ctx->device_frozen[i] = 1; } @@ -293,7 +278,6 @@ int ssb_devices_thaw(struct ssb_freeze_context *ctx) dev_name(sdev->dev)); result = err; } - ssb_driver_put(sdrv); ssb_device_put(sdev); } diff --git a/lib/dma-debug.c b/lib/dma-debug.c index fea790a2b17..13ef2338be4 100644 --- a/lib/dma-debug.c +++ b/lib/dma-debug.c @@ -170,7 +170,7 @@ static bool driver_filter(struct device *dev) return false; /* driver filter on but not yet initialized */ - drv = get_driver(dev->driver); + drv = dev->driver; if (!drv) return false; @@ -185,7 +185,6 @@ static bool driver_filter(struct device *dev) } read_unlock_irqrestore(&driver_name_lock, flags); - put_driver(drv); return ret; } -- cgit v1.2.3-70-g09d2 From 9875bb480cc89d9b690f7028aadf7e58454f0dae Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 13:35:37 -0500 Subject: Eliminate get_driver() and put_driver() Now that there are no users of get_driver() or put_driver(), this patch (as1513) removes those routines completely. Signed-off-by: Alan Stern CC: Dmitry Torokhov Signed-off-by: Greg Kroah-Hartman --- drivers/base/driver.c | 28 ---------------------------- include/linux/device.h | 2 -- 2 files changed, 30 deletions(-) (limited to 'drivers') diff --git a/drivers/base/driver.c b/drivers/base/driver.c index e979cad75c6..60e4f77ca66 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -153,34 +153,6 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj, } EXPORT_SYMBOL_GPL(driver_add_kobj); -/** - * get_driver - increment driver reference count. - * @drv: driver. - */ -struct device_driver *get_driver(struct device_driver *drv) -{ - if (drv) { - struct driver_private *priv; - struct kobject *kobj; - - kobj = kobject_get(&drv->p->kobj); - priv = to_driver(kobj); - return priv->driver; - } - return NULL; -} -EXPORT_SYMBOL_GPL(get_driver); - -/** - * put_driver - decrement driver's refcount. - * @drv: driver. - */ -void put_driver(struct device_driver *drv) -{ - kobject_put(&drv->p->kobj); -} -EXPORT_SYMBOL_GPL(put_driver); - static int driver_add_groups(struct device_driver *drv, const struct attribute_group **groups) { diff --git a/include/linux/device.h b/include/linux/device.h index a782d7ff9e8..d28bd829567 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -238,8 +238,6 @@ struct device_driver { extern int __must_check driver_register(struct device_driver *drv); extern void driver_unregister(struct device_driver *drv); -extern struct device_driver *get_driver(struct device_driver *drv); -extern void put_driver(struct device_driver *drv); extern struct device_driver *driver_find(const char *name, struct bus_type *bus); extern int driver_probe_done(void); -- cgit v1.2.3-70-g09d2 From b00e126ffea89b687a83093546058b07aa054b4c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:33:49 +0800 Subject: MISC: convert drivers/misc/* to use module_platform_driver() This patch converts the drivers in drivers/misc/* to use the module_platform_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Acked-by: Ira W. Snyder Cc: Pavan Savoy Cc: Donggeun Kim Acked-By: Pratyush Anand Acked-by: Arnd Bergmann Acked-by: Pratyush Anand Signed-off-by: Greg Kroah-Hartman --- drivers/misc/carma/carma-fpga.c | 17 +---------------- drivers/misc/max8997-muic.c | 12 +----------- drivers/misc/spear13xx_pcie_gadget.c | 12 +----------- drivers/misc/ti-st/st_kim.c | 13 +------------ 4 files changed, 4 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/carma/carma-fpga.c b/drivers/misc/carma/carma-fpga.c index 14e974b2a78..366bc156e34 100644 --- a/drivers/misc/carma/carma-fpga.c +++ b/drivers/misc/carma/carma-fpga.c @@ -1410,23 +1410,8 @@ static struct platform_driver data_of_driver = { }, }; -/* - * Module Init / Exit - */ - -static int __init data_init(void) -{ - return platform_driver_register(&data_of_driver); -} - -static void __exit data_exit(void) -{ - platform_driver_unregister(&data_of_driver); -} +module_platform_driver(data_of_driver); MODULE_AUTHOR("Ira W. Snyder "); MODULE_DESCRIPTION("CARMA DATA-FPGA Access Driver"); MODULE_LICENSE("GPL"); - -module_init(data_init); -module_exit(data_exit); diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c index d74ef41aabd..19591eaa492 100644 --- a/drivers/misc/max8997-muic.c +++ b/drivers/misc/max8997-muic.c @@ -488,17 +488,7 @@ static struct platform_driver max8997_muic_driver = { .remove = __devexit_p(max8997_muic_remove), }; -static int __init max8997_muic_init(void) -{ - return platform_driver_register(&max8997_muic_driver); -} -module_init(max8997_muic_init); - -static void __exit max8997_muic_exit(void) -{ - platform_driver_unregister(&max8997_muic_driver); -} -module_exit(max8997_muic_exit); +module_platform_driver(max8997_muic_driver); MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver"); MODULE_AUTHOR("Donggeun Kim "); diff --git a/drivers/misc/spear13xx_pcie_gadget.c b/drivers/misc/spear13xx_pcie_gadget.c index 43d073bc1d9..123ed98eec3 100644 --- a/drivers/misc/spear13xx_pcie_gadget.c +++ b/drivers/misc/spear13xx_pcie_gadget.c @@ -891,17 +891,7 @@ static struct platform_driver spear_pcie_gadget_driver = { }, }; -static int __init spear_pcie_gadget_init(void) -{ - return platform_driver_register(&spear_pcie_gadget_driver); -} -module_init(spear_pcie_gadget_init); - -static void __exit spear_pcie_gadget_exit(void) -{ - platform_driver_unregister(&spear_pcie_gadget_driver); -} -module_exit(spear_pcie_gadget_exit); +module_platform_driver(spear_pcie_gadget_driver); MODULE_ALIAS("platform:pcie-gadget-spear"); MODULE_AUTHOR("Pratyush Anand"); diff --git a/drivers/misc/ti-st/st_kim.c b/drivers/misc/ti-st/st_kim.c index a7a861ceee2..7c14f8fd98d 100644 --- a/drivers/misc/ti-st/st_kim.c +++ b/drivers/misc/ti-st/st_kim.c @@ -837,19 +837,8 @@ static struct platform_driver kim_platform_driver = { }, }; -static int __init st_kim_init(void) -{ - return platform_driver_register(&kim_platform_driver); -} - -static void __exit st_kim_deinit(void) -{ - platform_driver_unregister(&kim_platform_driver); -} - +module_platform_driver(kim_platform_driver); -module_init(st_kim_init); -module_exit(st_kim_deinit); MODULE_AUTHOR("Pavan Savoy "); MODULE_DESCRIPTION("Shared Transport Driver for TI BT/FM/GPS combo chips "); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From a64fe2ed76614d37abb6966a67f4f39d10efba3c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:36:45 +0800 Subject: MISC: convert drivers/misc/* to use module_i2c_driver() This patch converts the drivers in drivers/misc/* to use the module_i2c_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Michael Hennerich Cc: Anantha Narayanan Cc: Hemanth V Cc: Christoph Mair Cc: Grant Likely Cc: Ben Gardner Cc: Minkyu Kang Cc: Kalhan Trisal Cc: Darrick J. Wong Cc: Daniel Mack Cc: Rodolfo Giometti Acked-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-i2c.c | 12 +----------- drivers/misc/apds9802als.c | 12 +----------- drivers/misc/apds990x.c | 13 +------------ drivers/misc/bh1770glc.c | 13 +------------ drivers/misc/bh1780gli.c | 15 ++------------- drivers/misc/bmp085.c | 14 +------------- drivers/misc/ds1682.c | 13 +------------ drivers/misc/eeprom/eeprom.c | 14 +------------- drivers/misc/eeprom/max6875.c | 14 +------------- drivers/misc/fsa9480.c | 12 +----------- drivers/misc/hmc6352.c | 13 +------------ drivers/misc/ics932s401.c | 13 +------------ drivers/misc/isl29003.c | 14 +------------- drivers/misc/isl29020.c | 13 +------------ drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 13 +------------ drivers/misc/tsl2550.c | 13 +------------ 16 files changed, 17 insertions(+), 194 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 83adab69bfd..820826270b6 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c @@ -113,17 +113,7 @@ static struct i2c_driver ad_dpot_i2c_driver = { .id_table = ad_dpot_id, }; -static int __init ad_dpot_i2c_init(void) -{ - return i2c_add_driver(&ad_dpot_i2c_driver); -} -module_init(ad_dpot_i2c_init); - -static void __exit ad_dpot_i2c_exit(void) -{ - i2c_del_driver(&ad_dpot_i2c_driver); -} -module_exit(ad_dpot_i2c_exit); +module_i2c_driver(ad_dpot_i2c_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("digital potentiometer I2C bus driver"); diff --git a/drivers/misc/apds9802als.c b/drivers/misc/apds9802als.c index 81db7811cf6..0314773f6db 100644 --- a/drivers/misc/apds9802als.c +++ b/drivers/misc/apds9802als.c @@ -332,17 +332,7 @@ static struct i2c_driver apds9802als_driver = { .id_table = apds9802als_id, }; -static int __init sensor_apds9802als_init(void) -{ - return i2c_add_driver(&apds9802als_driver); -} - -static void __exit sensor_apds9802als_exit(void) -{ - i2c_del_driver(&apds9802als_driver); -} -module_init(sensor_apds9802als_init); -module_exit(sensor_apds9802als_exit); +module_i2c_driver(apds9802als_driver); MODULE_AUTHOR("Anantha Narayanan "); MODULE_DESCRIPTION("DS1682 Elapsed Time Indicator driver"); MODULE_LICENSE("GPL"); - -module_init(ds1682_init); -module_exit(ds1682_exit); diff --git a/drivers/misc/eeprom/eeprom.c b/drivers/misc/eeprom/eeprom.c index 45060ddc4e5..c169e07654c 100644 --- a/drivers/misc/eeprom/eeprom.c +++ b/drivers/misc/eeprom/eeprom.c @@ -229,22 +229,10 @@ static struct i2c_driver eeprom_driver = { .address_list = normal_i2c, }; -static int __init eeprom_init(void) -{ - return i2c_add_driver(&eeprom_driver); -} - -static void __exit eeprom_exit(void) -{ - i2c_del_driver(&eeprom_driver); -} - +module_i2c_driver(eeprom_driver); MODULE_AUTHOR("Frodo Looijaard and " "Philip Edelbrock and " "Greg Kroah-Hartman "); MODULE_DESCRIPTION("I2C EEPROM driver"); MODULE_LICENSE("GPL"); - -module_init(eeprom_init); -module_exit(eeprom_exit); diff --git a/drivers/misc/eeprom/max6875.c b/drivers/misc/eeprom/max6875.c index 5653a3ce051..e36157d5d3a 100644 --- a/drivers/misc/eeprom/max6875.c +++ b/drivers/misc/eeprom/max6875.c @@ -208,20 +208,8 @@ static struct i2c_driver max6875_driver = { .id_table = max6875_id, }; -static int __init max6875_init(void) -{ - return i2c_add_driver(&max6875_driver); -} - -static void __exit max6875_exit(void) -{ - i2c_del_driver(&max6875_driver); -} - +module_i2c_driver(max6875_driver); MODULE_AUTHOR("Ben Gardner "); MODULE_DESCRIPTION("MAX6875 driver"); MODULE_LICENSE("GPL"); - -module_init(max6875_init); -module_exit(max6875_exit); diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index f6586d53e1a..483d6b73809 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c @@ -541,17 +541,7 @@ static struct i2c_driver fsa9480_i2c_driver = { .id_table = fsa9480_id, }; -static int __init fsa9480_init(void) -{ - return i2c_add_driver(&fsa9480_i2c_driver); -} -module_init(fsa9480_init); - -static void __exit fsa9480_exit(void) -{ - i2c_del_driver(&fsa9480_i2c_driver); -} -module_exit(fsa9480_exit); +module_i2c_driver(fsa9480_i2c_driver); MODULE_AUTHOR("Minkyu Kang "); MODULE_DESCRIPTION("FSA9480 USB Switch driver"); diff --git a/drivers/misc/hmc6352.c b/drivers/misc/hmc6352.c index ca938fc8a8d..423cd40f1c0 100644 --- a/drivers/misc/hmc6352.c +++ b/drivers/misc/hmc6352.c @@ -148,18 +148,7 @@ static struct i2c_driver hmc6352_driver = { .id_table = hmc6352_id, }; -static int __init sensor_hmc6352_init(void) -{ - return i2c_add_driver(&hmc6352_driver); -} - -static void __exit sensor_hmc6352_exit(void) -{ - i2c_del_driver(&hmc6352_driver); -} - -module_init(sensor_hmc6352_init); -module_exit(sensor_hmc6352_exit); +module_i2c_driver(hmc6352_driver); MODULE_AUTHOR("Kalhan Trisal "); MODULE_DESCRIPTION("ICS932S401 driver"); MODULE_LICENSE("GPL"); -module_init(ics932s401_init); -module_exit(ics932s401_exit); - /* IBM IntelliStation Z30 */ MODULE_ALIAS("dmi:bvnIBM:*:rn9228:*"); MODULE_ALIAS("dmi:bvnIBM:*:rn9232:*"); diff --git a/drivers/misc/isl29003.c b/drivers/misc/isl29003.c index a71e245801e..eb5de2e210d 100644 --- a/drivers/misc/isl29003.c +++ b/drivers/misc/isl29003.c @@ -455,21 +455,9 @@ static struct i2c_driver isl29003_driver = { .id_table = isl29003_id, }; -static int __init isl29003_init(void) -{ - return i2c_add_driver(&isl29003_driver); -} - -static void __exit isl29003_exit(void) -{ - i2c_del_driver(&isl29003_driver); -} +module_i2c_driver(isl29003_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("ISL29003 ambient light sensor driver"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRIVER_VERSION); - -module_init(isl29003_init); -module_exit(isl29003_exit); - diff --git a/drivers/misc/isl29020.c b/drivers/misc/isl29020.c index 3d6cce663be..0aa08c74646 100644 --- a/drivers/misc/isl29020.c +++ b/drivers/misc/isl29020.c @@ -230,18 +230,7 @@ static struct i2c_driver isl29020_driver = { .id_table = isl29020_id, }; -static int __init sensor_isl29020_init(void) -{ - return i2c_add_driver(&isl29020_driver); -} - -static void __exit sensor_isl29020_exit(void) -{ - i2c_del_driver(&isl29020_driver); -} - -module_init(sensor_isl29020_init); -module_exit(sensor_isl29020_exit); +module_i2c_driver(isl29020_driver); MODULE_AUTHOR("Kalhan Trisal "); MODULE_DESCRIPTION("Intersil isl29020 ALS Driver"); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index c02fea029dc..e8c0019da97 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c @@ -256,19 +256,8 @@ static struct i2c_driver lis3lv02d_i2c_driver = { .id_table = lis3lv02d_id, }; -static int __init lis3lv02d_init(void) -{ - return i2c_add_driver(&lis3lv02d_i2c_driver); -} - -static void __exit lis3lv02d_exit(void) -{ - i2c_del_driver(&lis3lv02d_i2c_driver); -} +module_i2c_driver(lis3lv02d_i2c_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("lis3lv02d I2C interface"); MODULE_LICENSE("GPL"); - -module_init(lis3lv02d_init); -module_exit(lis3lv02d_exit); diff --git a/drivers/misc/tsl2550.c b/drivers/misc/tsl2550.c index 483ae5f7f68..0beb298a17d 100644 --- a/drivers/misc/tsl2550.c +++ b/drivers/misc/tsl2550.c @@ -454,20 +454,9 @@ static struct i2c_driver tsl2550_driver = { .id_table = tsl2550_id, }; -static int __init tsl2550_init(void) -{ - return i2c_add_driver(&tsl2550_driver); -} - -static void __exit tsl2550_exit(void) -{ - i2c_del_driver(&tsl2550_driver); -} +module_i2c_driver(tsl2550_driver); MODULE_AUTHOR("Rodolfo Giometti "); MODULE_DESCRIPTION("TSL2550 ambient light sensor driver"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); - -module_init(tsl2550_init); -module_exit(tsl2550_exit); -- cgit v1.2.3-70-g09d2 From a3dc3c9eb0a7bcf17604ee444c48b94e2591812d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 22 Jan 2012 15:38:22 +0800 Subject: MISC: convert drivers/misc/* to use module_spi_driver() This patch converts the drivers in drivers/misc/* to use the module_spi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Michael Hennerich Cc: Anatolij Gustschin Cc: Daniel Mack Acked-by: Michael Hennerich Signed-off-by: Greg Kroah-Hartman --- drivers/misc/ad525x_dpot-spi.c | 12 +----------- drivers/misc/eeprom/at25.c | 12 +----------- drivers/misc/eeprom/eeprom_93xx46.c | 12 +----------- drivers/misc/lis3lv02d/lis3lv02d_spi.c | 13 +------------ drivers/misc/ti_dac7512.c | 13 +------------ 5 files changed, 5 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/ad525x_dpot-spi.c b/drivers/misc/ad525x_dpot-spi.c index 822749e41fe..f62317540d0 100644 --- a/drivers/misc/ad525x_dpot-spi.c +++ b/drivers/misc/ad525x_dpot-spi.c @@ -135,17 +135,7 @@ static struct spi_driver ad_dpot_spi_driver = { .id_table = ad_dpot_spi_id, }; -static int __init ad_dpot_spi_init(void) -{ - return spi_register_driver(&ad_dpot_spi_driver); -} -module_init(ad_dpot_spi_init); - -static void __exit ad_dpot_spi_exit(void) -{ - spi_unregister_driver(&ad_dpot_spi_driver); -} -module_exit(ad_dpot_spi_exit); +module_spi_driver(ad_dpot_spi_driver); MODULE_AUTHOR("Michael Hennerich "); MODULE_DESCRIPTION("digital potentiometer SPI bus driver"); diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c index c627e4174cc..01ab3c9b4cf 100644 --- a/drivers/misc/eeprom/at25.c +++ b/drivers/misc/eeprom/at25.c @@ -405,17 +405,7 @@ static struct spi_driver at25_driver = { .remove = __devexit_p(at25_remove), }; -static int __init at25_init(void) -{ - return spi_register_driver(&at25_driver); -} -module_init(at25_init); - -static void __exit at25_exit(void) -{ - spi_unregister_driver(&at25_driver); -} -module_exit(at25_exit); +module_spi_driver(at25_driver); MODULE_DESCRIPTION("Driver for most SPI EEPROMs"); MODULE_AUTHOR("David Brownell"); diff --git a/drivers/misc/eeprom/eeprom_93xx46.c b/drivers/misc/eeprom/eeprom_93xx46.c index 0c7ebb1e19e..ce3fe3633dd 100644 --- a/drivers/misc/eeprom/eeprom_93xx46.c +++ b/drivers/misc/eeprom/eeprom_93xx46.c @@ -392,17 +392,7 @@ static struct spi_driver eeprom_93xx46_driver = { .remove = __devexit_p(eeprom_93xx46_remove), }; -static int __init eeprom_93xx46_init(void) -{ - return spi_register_driver(&eeprom_93xx46_driver); -} -module_init(eeprom_93xx46_init); - -static void __exit eeprom_93xx46_exit(void) -{ - spi_unregister_driver(&eeprom_93xx46_driver); -} -module_exit(eeprom_93xx46_exit); +module_spi_driver(eeprom_93xx46_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for 93xx46 EEPROMs"); diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index b2c1be12d16..80880e984b4 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c @@ -126,18 +126,7 @@ static struct spi_driver lis302dl_spi_driver = { .remove = __devexit_p(lis302dl_spi_remove), }; -static int __init lis302dl_init(void) -{ - return spi_register_driver(&lis302dl_spi_driver); -} - -static void __exit lis302dl_exit(void) -{ - spi_unregister_driver(&lis302dl_spi_driver); -} - -module_init(lis302dl_init); -module_exit(lis302dl_exit); +module_spi_driver(lis302dl_spi_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("lis3lv02d SPI glue layer"); diff --git a/drivers/misc/ti_dac7512.c b/drivers/misc/ti_dac7512.c index d3f229a3a77..5acbba120de 100644 --- a/drivers/misc/ti_dac7512.c +++ b/drivers/misc/ti_dac7512.c @@ -82,20 +82,9 @@ static struct spi_driver dac7512_driver = { .remove = __devexit_p(dac7512_remove), }; -static int __init dac7512_init(void) -{ - return spi_register_driver(&dac7512_driver); -} - -static void __exit dac7512_exit(void) -{ - spi_unregister_driver(&dac7512_driver); -} +module_spi_driver(dac7512_driver); MODULE_AUTHOR("Daniel Mack "); MODULE_DESCRIPTION("DAC7512 16-bit DAC"); MODULE_LICENSE("GPL v2"); MODULE_VERSION(DRIVER_VERSION); - -module_init(dac7512_init); -module_exit(dac7512_exit); -- cgit v1.2.3-70-g09d2 From cf66f9d48a9c95baf8f13b199a633ce1c4cf952a Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 23 Jan 2012 08:24:43 +0000 Subject: xen/netfront: add netconsole support. add polling interface to xen-netfront device to support netconsole This patch also alters the spin_lock usage to use irqsave variant. Documentation/networking/netdevices.txt states that start_xmit can be called with interrupts disabled by netconsole and therefore using the irqsave/restore locking in this function is looks correct. Signed-off-by: Tina.Yang Cc: Jeremy Fitzhardinge Signed-off-by: Zhenzhong.Duan Tested-by: gurudas.pai [v1: Copy-n-pasted Ian Campbell comments] Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Ian Campbell Signed-off-by: David S. Miller --- drivers/net/xen-netfront.c | 57 +++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index fa679057630..db638b4454e 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -489,6 +489,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) int frags = skb_shinfo(skb)->nr_frags; unsigned int offset = offset_in_page(data); unsigned int len = skb_headlen(skb); + unsigned long flags; frags += DIV_ROUND_UP(offset + len, PAGE_SIZE); if (unlikely(frags > MAX_SKB_FRAGS + 1)) { @@ -498,12 +499,12 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; } - spin_lock_irq(&np->tx_lock); + spin_lock_irqsave(&np->tx_lock, flags); if (unlikely(!netif_carrier_ok(dev) || (frags > 1 && !xennet_can_sg(dev)) || netif_needs_gso(skb, netif_skb_features(skb)))) { - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); goto drop; } @@ -574,7 +575,7 @@ static int xennet_start_xmit(struct sk_buff *skb, struct net_device *dev) if (!netfront_tx_slot_available(np)) netif_stop_queue(dev); - spin_unlock_irq(&np->tx_lock); + spin_unlock_irqrestore(&np->tx_lock, flags); return NETDEV_TX_OK; @@ -1228,6 +1229,33 @@ static int xennet_set_features(struct net_device *dev, return 0; } +static irqreturn_t xennet_interrupt(int irq, void *dev_id) +{ + struct net_device *dev = dev_id; + struct netfront_info *np = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&np->tx_lock, flags); + + if (likely(netif_carrier_ok(dev))) { + xennet_tx_buf_gc(dev); + /* Under tx_lock: protects access to rx shared-ring indexes. */ + if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) + napi_schedule(&np->napi); + } + + spin_unlock_irqrestore(&np->tx_lock, flags); + + return IRQ_HANDLED; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +static void xennet_poll_controller(struct net_device *dev) +{ + xennet_interrupt(0, dev); +} +#endif + static const struct net_device_ops xennet_netdev_ops = { .ndo_open = xennet_open, .ndo_uninit = xennet_uninit, @@ -1239,6 +1267,9 @@ static const struct net_device_ops xennet_netdev_ops = { .ndo_validate_addr = eth_validate_addr, .ndo_fix_features = xennet_fix_features, .ndo_set_features = xennet_set_features, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = xennet_poll_controller, +#endif }; static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev) @@ -1448,26 +1479,6 @@ static int xen_net_read_mac(struct xenbus_device *dev, u8 mac[]) return 0; } -static irqreturn_t xennet_interrupt(int irq, void *dev_id) -{ - struct net_device *dev = dev_id; - struct netfront_info *np = netdev_priv(dev); - unsigned long flags; - - spin_lock_irqsave(&np->tx_lock, flags); - - if (likely(netif_carrier_ok(dev))) { - xennet_tx_buf_gc(dev); - /* Under tx_lock: protects access to rx shared-ring indexes. */ - if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx)) - napi_schedule(&np->napi); - } - - spin_unlock_irqrestore(&np->tx_lock, flags); - - return IRQ_HANDLED; -} - static int setup_netfront(struct xenbus_device *dev, struct netfront_info *info) { struct xen_netif_tx_sring *txs; -- cgit v1.2.3-70-g09d2 From aaca2377e9c08d1964a5cacb95330708a6f6d106 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Mon, 23 Jan 2012 16:44:50 +0000 Subject: net: fec: use module_platform_driver Using module_platform_driver can make the code smaller. Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 7b25e9cf13f..e5885ccfc8f 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1739,21 +1739,6 @@ static struct platform_driver fec_driver = { .remove = __devexit_p(fec_drv_remove), }; -static int __init -fec_enet_module_init(void) -{ - printk(KERN_INFO "FEC Ethernet Driver\n"); - - return platform_driver_register(&fec_driver); -} - -static void __exit -fec_enet_cleanup(void) -{ - platform_driver_unregister(&fec_driver); -} - -module_exit(fec_enet_cleanup); -module_init(fec_enet_module_init); +module_platform_driver(fec_driver); MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 8d79c3490aecfe6e51f0ba6f9780746fb1434954 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jan 2012 10:50:05 -0800 Subject: drm/i915: Remove the MI_FLUSH_ENABLE setting. We have always been using the wrong bit -- it's bit 12. However, the bit also doesn't do anything -- hardware has always accepted the MI_FLUSH command even when it was specced not to. Given that there is only one MI_FLUSH emitted in all of the driver stack on gen6+ (in i965_video.c of the 2d driver, and it should be using other code to do its flush instead), just remove the MI_FLUSH enable instead of trying to fix it. Signed-off-by: Eric Anholt Reviewed-by: Kenneth Graunke Reviewed-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 77e729d4e4f..b3da17af899 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -399,8 +399,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen > 3) { int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; - if (IS_GEN6(dev) || IS_GEN7(dev)) - mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); if (IS_GEN7(dev)) I915_WRITE(GFX_MODE_GEN7, -- cgit v1.2.3-70-g09d2 From d5dc9271b25822f36d299f8cab985379743424b9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:07:47 +0000 Subject: ARM: amba: add amba_device allocation/add/put functions Add functions to allocate and initialize AMBA device structures, and add them to the Linux device manager. This allows us to kill this type of operation from individual platforms, moving it to core code. Signed-off-by: Russell King --- drivers/amba/bus.c | 100 +++++++++++++++++++++++++++++++++++------------ include/linux/amba/bus.h | 3 ++ 2 files changed, 78 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 54eaf96ab21..82b65e1e12b 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -497,38 +497,20 @@ static void amba_device_release(struct device *dev) } /** - * amba_device_register - register an AMBA device - * @dev: AMBA device to register - * @parent: parent memory resource + * amba_device_add - add a previously allocated AMBA device structure + * @dev: AMBA device allocated by amba_device_alloc + * @parent: resource parent for this devices resources * - * Setup the AMBA device, reading the cell ID if present. - * Claim the resource, and register the AMBA device with - * the Linux device manager. + * Claim the resource, and read the device cell ID if not already + * initialized. Register the AMBA device with the Linux device + * manager. */ -int amba_device_register(struct amba_device *dev, struct resource *parent) +int amba_device_add(struct amba_device *dev, struct resource *parent) { u32 size; void __iomem *tmp; int i, ret; - device_initialize(&dev->dev); - - /* - * Copy from device_add - */ - if (dev->dev.init_name) { - dev_set_name(&dev->dev, "%s", dev->dev.init_name); - dev->dev.init_name = NULL; - } - - dev->dev.release = amba_device_release; - dev->dev.bus = &amba_bustype; - dev->dev.dma_mask = &dev->dma_mask; - dev->res.name = dev_name(&dev->dev); - - if (!dev->dev.coherent_dma_mask && dev->dma_mask) - dev_warn(&dev->dev, "coherent dma mask is unset\n"); - ret = request_resource(parent, &dev->res); if (ret) goto err_out; @@ -596,6 +578,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent) err_out: return ret; } +EXPORT_SYMBOL_GPL(amba_device_add); + +static void amba_device_initialize(struct amba_device *dev, const char *name) +{ + device_initialize(&dev->dev); + if (name) + dev_set_name(&dev->dev, "%s", name); + dev->dev.release = amba_device_release; + dev->dev.bus = &amba_bustype; + dev->dev.dma_mask = &dev->dma_mask; + dev->res.name = dev_name(&dev->dev); +} + +/** + * amba_device_alloc - allocate an AMBA device + * @name: sysfs name of the AMBA device + * @base: base of AMBA device + * @size: size of AMBA device + * + * Allocate and initialize an AMBA device structure. Returns %NULL + * on failure. + */ +struct amba_device *amba_device_alloc(const char *name, resource_size_t base, + size_t size) +{ + struct amba_device *dev; + + dev = kzalloc(sizeof(*dev), GFP_KERNEL); + if (dev) { + amba_device_initialize(dev, name); + dev->res.start = base; + dev->res.end = base + size - 1; + dev->res.flags = IORESOURCE_MEM; + } + + return dev; +} +EXPORT_SYMBOL_GPL(amba_device_alloc); + +/** + * amba_device_register - register an AMBA device + * @dev: AMBA device to register + * @parent: parent memory resource + * + * Setup the AMBA device, reading the cell ID if present. + * Claim the resource, and register the AMBA device with + * the Linux device manager. + */ +int amba_device_register(struct amba_device *dev, struct resource *parent) +{ + amba_device_initialize(dev, dev->dev.init_name); + dev->dev.init_name = NULL; + + if (!dev->dev.coherent_dma_mask && dev->dma_mask) + dev_warn(&dev->dev, "coherent dma mask is unset\n"); + + return amba_device_add(dev, parent); +} + +/** + * amba_device_put - put an AMBA device + * @dev: AMBA device to put + */ +void amba_device_put(struct amba_device *dev) +{ + put_device(&dev->dev); +} +EXPORT_SYMBOL_GPL(amba_device_put); /** * amba_device_unregister - unregister an AMBA device diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h index 724c69c40bb..e1929620e5a 100644 --- a/include/linux/amba/bus.h +++ b/include/linux/amba/bus.h @@ -60,6 +60,9 @@ extern struct bus_type amba_bustype; int amba_driver_register(struct amba_driver *); void amba_driver_unregister(struct amba_driver *); +struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t); +void amba_device_put(struct amba_device *); +int amba_device_add(struct amba_device *, struct resource *); int amba_device_register(struct amba_device *, struct resource *); void amba_device_unregister(struct amba_device *); struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int); -- cgit v1.2.3-70-g09d2 From c0f72f8a9279f82520fc476c32c09f693661c5f4 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:45:17 +0000 Subject: ARM: amba: of: convert to use amba_device_alloc Convert DT code to use the new amba_device_alloc APIs. Acked-by: Rob Herring Signed-off-by: Russell King --- drivers/of/platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 63b3ec48c20..cae9477a6ed 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (!of_device_is_available(node)) return NULL; - dev = kzalloc(sizeof(*dev), GFP_KERNEL); + dev = amba_device_alloc(NULL, 0, 0); if (!dev) return NULL; @@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node, if (ret) goto err_free; - ret = amba_device_register(dev, &iomem_resource); + ret = amba_device_add(dev, &iomem_resource); if (ret) goto err_free; return dev; err_free: - kfree(dev); + amba_device_put(dev); return NULL; } #else /* CONFIG_ARM_AMBA */ -- cgit v1.2.3-70-g09d2 From 023f117c547719fbc087ad72276aec5a026370df Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:31:51 +0000 Subject: ARM: amba: make irq 0 invalid Fix core bus and MMCI such that irq 0 means that there is no IRQ attached. Signed-off-by: Russell King --- drivers/amba/bus.c | 4 ++-- drivers/mmc/host/mmci.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index 82b65e1e12b..d15acbb4d59 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -564,9 +564,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) if (ret) goto err_release; - if (dev->irq[0] != NO_IRQ) + if (dev->irq[0] && dev->irq[0] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq0); - if (ret == 0 && dev->irq[1] != NO_IRQ) + if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ) ret = device_create_file(&dev->dev, &dev_attr_irq1); if (ret == 0) return ret; diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 0d955ffaf44..304f2f98b68 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -1325,7 +1325,7 @@ static int __devinit mmci_probe(struct amba_device *dev, if (ret) goto unmap; - if (dev->irq[1] == NO_IRQ) + if (dev->irq[1] == NO_IRQ || !dev->irq[1]) host->singleirq = true; else { ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED, -- cgit v1.2.3-70-g09d2 From 2eac58d5026e4ec8b17ff8b62877fea9e1d2f1b3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 Dec 2011 11:43:56 +0000 Subject: ARM: amba: make use of -1 IRQs warn Make the core warn about the use of -1 (NO_IRQ) Signed-off-by: Russell King --- drivers/amba/bus.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c index d15acbb4d59..01c2cf4efcd 100644 --- a/drivers/amba/bus.c +++ b/drivers/amba/bus.c @@ -511,6 +511,9 @@ int amba_device_add(struct amba_device *dev, struct resource *parent) void __iomem *tmp; int i, ret; + WARN_ON(dev->irq[0] == (unsigned int)-1); + WARN_ON(dev->irq[1] == (unsigned int)-1); + ret = request_resource(parent, &dev->res); if (ret) goto err_out; -- cgit v1.2.3-70-g09d2 From e6b0f884520e604408ebda3b60605cabe0a8d162 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:24:04 +0200 Subject: OMAPDSS: FEAT: Add FIFO_MERGE feature Add feature flag for fifo merge. OMAP2 doesn't contain fifo merge, later OMAPs do. dispc_enable_fifomerge() checks for the flag when called, and gives a WARN if fifo merge is being enabled when it is not supported. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 5 +++++ drivers/video/omap2/dss/dss_features.c | 9 +++++---- drivers/video/omap2/dss/dss_features.h | 1 + 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a5ec7f37c18..d711518f9f1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1054,6 +1054,11 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) void dispc_enable_fifomerge(bool enable) { + if (!dss_has_feature(FEAT_FIFO_MERGE)) { + WARN_ON(enable); + return; + } + DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled"); REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index afcb59301c3..c2456c5bcd3 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -370,7 +370,7 @@ static const struct omap_dss_features omap3430_dss_features = { FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 2, .num_ovls = 3, @@ -394,7 +394,7 @@ static const struct omap_dss_features omap3630_dss_features = { FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 2, .num_ovls = 3, @@ -419,7 +419,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | FEAT_DSI_GNQ | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | FEAT_PRELOAD | FEAT_FIR_COEF_V | - FEAT_ALPHA_FREE_ZORDER, + FEAT_ALPHA_FREE_ZORDER | FEAT_FIFO_MERGE, .num_mgrs = 3, .num_ovls = 4, @@ -443,7 +443,8 @@ static const struct omap_dss_features omap4_dss_features = { FEAT_DSI_DCS_CMD_CONFIG_VC | FEAT_DSI_VC_OCP_WIDTH | FEAT_DSI_GNQ | FEAT_HDMI_CTS_SWMODE | FEAT_HANDLE_UV_SEPARATE | FEAT_ATTR2 | FEAT_CPR | - FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER, + FEAT_PRELOAD | FEAT_FIR_COEF_V | FEAT_ALPHA_FREE_ZORDER | + FEAT_FIFO_MERGE, .num_mgrs = 3, .num_ovls = 4, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index cd833bbaac3..50caee9192a 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -58,6 +58,7 @@ enum dss_feat_id { FEAT_FIR_COEF_V = 1 << 25, FEAT_ALPHA_FIXED_ZORDER = 1 << 26, FEAT_ALPHA_FREE_ZORDER = 1 << 27, + FEAT_FIFO_MERGE = 1 << 28, }; /* DSS register field id */ -- cgit v1.2.3-70-g09d2 From fb0119742291b6f30cd97026ee137b2d3d1f4de8 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 15:00:22 +0200 Subject: OMAPDSS: APPLY: add fifo merge support funcs Add mechanism to set/unset the DISPC fifo-merge: Add new fields to dss_data, fifo_merge and fifo_merge_dirty. These are similar to the other info/dirty flags in ovl_priv_data and ovl_mgr_data, but fifo merge is a common attribute to all managers and thus outside the ovl_mgr_data. The fifo-merge field is used in the dss_write_regs_common, which handles writing the register. dss_apply_fifo_merge() can be used to set/unset the fifo merge field in the dss_data. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 43 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 052dc874cd3..604737f1187 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -105,6 +105,9 @@ static struct { struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS]; struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS]; + bool fifo_merge_dirty; + bool fifo_merge; + bool irq_enabled; } dss_data; @@ -585,11 +588,40 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr) } } +static void dss_write_regs_common(void) +{ + const int num_mgrs = omap_dss_get_num_overlay_managers(); + int i; + + if (!dss_data.fifo_merge_dirty) + return; + + for (i = 0; i < num_mgrs; ++i) { + struct omap_overlay_manager *mgr; + struct mgr_priv_data *mp; + + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); + + if (mp->enabled) { + if (dss_data.fifo_merge_dirty) { + dispc_enable_fifomerge(dss_data.fifo_merge); + dss_data.fifo_merge_dirty = false; + } + + if (mp->updating) + mp->shadow_info_dirty = true; + } + } +} + static void dss_write_regs(void) { const int num_mgrs = omap_dss_get_num_overlay_managers(); int i; + dss_write_regs_common(); + for (i = 0; i < num_mgrs; ++i) { struct omap_overlay_manager *mgr; struct mgr_priv_data *mp; @@ -659,6 +691,8 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr) dss_mgr_write_regs(mgr); + dss_write_regs_common(); + mp->updating = true; if (!dss_data.irq_enabled && need_isr()) @@ -859,6 +893,15 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl, op->extra_info_dirty = true; } +static void dss_apply_fifo_merge(bool use_fifo_merge) +{ + if (dss_data.fifo_merge == use_fifo_merge) + return; + + dss_data.fifo_merge = use_fifo_merge; + dss_data.fifo_merge_dirty = true; +} + static void dss_ovl_setup_fifo(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); -- cgit v1.2.3-70-g09d2 From 1d71f42b35ed66d90a9a39bc515bb16cfe2d4a46 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 16 Nov 2011 16:44:08 +0200 Subject: OMAPDSS: APPLY: add fifo-merge support Add fifo-merge support. This is done mainly in four functions: mgr_enable/disable and ovl_enable/disable. These are the functions where overlays are taken into and out of active use. The process to enable and disable fifo-merge is not simple. We need to do it in steps, waiting in between for certain settings to be taken into use, and continuing after that. The reason for this is that fifo-merge is a common thing for all managers/overlays, and its use must be synchronized. As an example, when we disable an overlay, we first set the overlay as disabled, then wait until the overlay is actually disabled in the HW, and only after that we may re-configure the fifos, possibly taking fifo-merge into use. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 164 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 156 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 604737f1187..6f7b213e096 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -902,7 +902,8 @@ static void dss_apply_fifo_merge(bool use_fifo_merge) dss_data.fifo_merge_dirty = true; } -static void dss_ovl_setup_fifo(struct omap_overlay *ovl) +static void dss_ovl_setup_fifo(struct omap_overlay *ovl, + bool use_fifo_merge) { struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; @@ -914,7 +915,16 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dssdev = ovl->manager->device; - size = dispc_ovl_get_fifo_size(ovl->id); + if (use_fifo_merge) { + int i; + + size = 0; + + for (i = 0; i < omap_dss_get_num_overlays(); ++i) + size += dispc_ovl_get_fifo_size(i); + } else { + size = dispc_ovl_get_fifo_size(ovl->id); + } burst_size = dispc_ovl_get_burst_size(ovl->id); @@ -940,7 +950,8 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl) dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } -static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) +static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr, + bool use_fifo_merge) { struct omap_overlay *ovl; struct mgr_priv_data *mp; @@ -951,10 +962,10 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr) return; list_for_each_entry(ovl, &mgr->overlays, list) - dss_ovl_setup_fifo(ovl); + dss_ovl_setup_fifo(ovl, use_fifo_merge); } -static void dss_setup_fifos(void) +static void dss_setup_fifos(bool use_fifo_merge) { const int num_mgrs = omap_dss_get_num_overlay_managers(); struct omap_overlay_manager *mgr; @@ -962,15 +973,91 @@ static void dss_setup_fifos(void) for (i = 0; i < num_mgrs; ++i) { mgr = omap_dss_get_overlay_manager(i); - dss_mgr_setup_fifos(mgr); + dss_mgr_setup_fifos(mgr, use_fifo_merge); } } +static int get_num_used_managers(void) +{ + const int num_mgrs = omap_dss_get_num_overlay_managers(); + struct omap_overlay_manager *mgr; + struct mgr_priv_data *mp; + int i; + int enabled_mgrs; + + enabled_mgrs = 0; + + for (i = 0; i < num_mgrs; ++i) { + mgr = omap_dss_get_overlay_manager(i); + mp = get_mgr_priv(mgr); + + if (!mp->enabled) + continue; + + enabled_mgrs++; + } + + return enabled_mgrs; +} + +static int get_num_used_overlays(void) +{ + const int num_ovls = omap_dss_get_num_overlays(); + struct omap_overlay *ovl; + struct ovl_priv_data *op; + struct mgr_priv_data *mp; + int i; + int enabled_ovls; + + enabled_ovls = 0; + + for (i = 0; i < num_ovls; ++i) { + ovl = omap_dss_get_overlay(i); + op = get_ovl_priv(ovl); + + if (!op->enabled && !op->enabling) + continue; + + mp = get_mgr_priv(ovl->manager); + + if (!mp->enabled) + continue; + + enabled_ovls++; + } + + return enabled_ovls; +} + +static bool get_use_fifo_merge(void) +{ + int enabled_mgrs = get_num_used_managers(); + int enabled_ovls = get_num_used_overlays(); + + if (!dss_has_feature(FEAT_FIFO_MERGE)) + return false; + + /* + * In theory the only requirement for fifomerge is enabled_ovls <= 1. + * However, if we have two managers enabled and set/unset the fifomerge, + * we need to set the GO bits in particular sequence for the managers, + * and wait in between. + * + * This is rather difficult as new apply calls can happen at any time, + * so we simplify the problem by requiring also that enabled_mgrs <= 1. + * In practice this shouldn't matter, because when only one overlay is + * enabled, most likely only one output is enabled. + */ + + return enabled_mgrs <= 1 && enabled_ovls <= 1; +} + int dss_mgr_enable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; int r; + bool fifo_merge; mutex_lock(&apply_lock); @@ -988,11 +1075,23 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr) goto err; } - dss_setup_fifos(); + /* step 1: setup fifos/fifomerge before enabling the manager */ + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); dss_write_regs(); dss_set_go_bits(); + spin_unlock_irqrestore(&data_lock, flags); + + /* wait until fifo config is in */ + wait_pending_extra_info_updates(); + + /* step 2: enable the manager */ + spin_lock_irqsave(&data_lock, flags); + if (!mgr_manual_update(mgr)) mp->updating = true; @@ -1017,6 +1116,7 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); unsigned long flags; + bool fifo_merge; mutex_lock(&apply_lock); @@ -1031,8 +1131,16 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr) mp->updating = false; mp->enabled = false; + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + spin_unlock_irqrestore(&data_lock, flags); + wait_pending_extra_info_updates(); out: mutex_unlock(&apply_lock); } @@ -1284,6 +1392,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; + bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1309,7 +1418,22 @@ int dss_ovl_enable(struct omap_overlay *ovl) goto err2; } - dss_setup_fifos(); + /* step 1: configure fifos/fifomerge for currently enabled ovls */ + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(&data_lock, flags); + + /* wait for fifo configs to go in */ + wait_pending_extra_info_updates(); + + /* step 2: enable the overlay */ + spin_lock_irqsave(&data_lock, flags); op->enabling = false; dss_apply_ovl_enable(ovl, true); @@ -1319,6 +1443,9 @@ int dss_ovl_enable(struct omap_overlay *ovl) spin_unlock_irqrestore(&data_lock, flags); + /* wait for overlay to be enabled */ + wait_pending_extra_info_updates(); + mutex_unlock(&apply_lock); return 0; @@ -1334,6 +1461,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) { struct ovl_priv_data *op = get_ovl_priv(ovl); unsigned long flags; + bool fifo_merge; int r; mutex_lock(&apply_lock); @@ -1348,14 +1476,34 @@ int dss_ovl_disable(struct omap_overlay *ovl) goto err; } + /* step 1: disable the overlay */ spin_lock_irqsave(&data_lock, flags); dss_apply_ovl_enable(ovl, false); + dss_write_regs(); dss_set_go_bits(); spin_unlock_irqrestore(&data_lock, flags); + /* wait for the overlay to be disabled */ + wait_pending_extra_info_updates(); + + /* step 2: configure fifos/fifomerge */ + spin_lock_irqsave(&data_lock, flags); + + fifo_merge = get_use_fifo_merge(); + dss_setup_fifos(fifo_merge); + dss_apply_fifo_merge(fifo_merge); + + dss_write_regs(); + dss_set_go_bits(); + + spin_unlock_irqrestore(&data_lock, flags); + + /* wait for fifo config to go in */ + wait_pending_extra_info_updates(); + mutex_unlock(&apply_lock); return 0; -- cgit v1.2.3-70-g09d2 From 3cb5d966e233167fcbeb7c7d7a66294e13ee9d90 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:14:57 +0200 Subject: OMAPDSS: DISPC: print fifo threshold values in bytes Fifo thresholds are calculated using bytes, but the debug print prints values in buffer units. Change the prints to use bytes to be in line with the calculations, and also to print in the same units on all OMAPs. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index d711518f9f1..ba907bd6009 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1039,13 +1039,13 @@ void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high) dss_feat_get_reg_field(FEAT_REG_FIFOHIGHTHRESHOLD, &hi_start, &hi_end); dss_feat_get_reg_field(FEAT_REG_FIFOLOWTHRESHOLD, &lo_start, &lo_end); - DSSDBG("fifo(%d) low/high old %u/%u, new %u/%u\n", + DSSDBG("fifo(%d) threshold (bytes), old %u/%u, new %u/%u\n", plane, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), - lo_start, lo_end), + lo_start, lo_end) * unit, REG_GET(DISPC_OVL_FIFO_THRESHOLD(plane), - hi_start, hi_end), - low, high); + hi_start, hi_end) * unit, + low * unit, high * unit); dispc_write_reg(DISPC_OVL_FIFO_THRESHOLD(plane), FLD_VAL(high, hi_start, hi_end) | -- cgit v1.2.3-70-g09d2 From 83fa2f2e940dc21a204cff697d84d37214a91708 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:17:01 +0200 Subject: OMAPDSS: DISPC: move fifo threhold calc to dispc.c Move fifo threshold calculation into dispc.c, as the thresholds are really dispc internal thing. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/apply.c | 34 ++-------------------------------- drivers/video/omap2/dss/dispc.c | 22 ++++++++++++++++++++-- drivers/video/omap2/dss/display.c | 10 ---------- drivers/video/omap2/dss/dsi.c | 8 -------- drivers/video/omap2/dss/dss.h | 10 ++-------- 5 files changed, 24 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 6f7b213e096..b0264a16465 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -907,7 +907,6 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, { struct ovl_priv_data *op = get_ovl_priv(ovl); struct omap_dss_device *dssdev; - u32 size, burst_size; u32 fifo_low, fifo_high; if (!op->enabled && !op->enabling) @@ -915,37 +914,8 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl, dssdev = ovl->manager->device; - if (use_fifo_merge) { - int i; - - size = 0; - - for (i = 0; i < omap_dss_get_num_overlays(); ++i) - size += dispc_ovl_get_fifo_size(i); - } else { - size = dispc_ovl_get_fifo_size(ovl->id); - } - - burst_size = dispc_ovl_get_burst_size(ovl->id); - - switch (dssdev->type) { - case OMAP_DISPLAY_TYPE_DPI: - case OMAP_DISPLAY_TYPE_DBI: - case OMAP_DISPLAY_TYPE_SDI: - case OMAP_DISPLAY_TYPE_VENC: - case OMAP_DISPLAY_TYPE_HDMI: - default_get_overlay_fifo_thresholds(ovl->id, size, - burst_size, &fifo_low, &fifo_high); - break; -#ifdef CONFIG_OMAP2_DSS_DSI - case OMAP_DISPLAY_TYPE_DSI: - dsi_get_overlay_fifo_thresholds(ovl->id, size, - burst_size, &fifo_low, &fifo_high); - break; -#endif - default: - BUG(); - } + dispc_ovl_compute_fifo_thresholds(ovl->id, &fifo_low, &fifo_high, + use_fifo_merge); dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high); } diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index ba907bd6009..a75972250a2 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -909,7 +909,7 @@ static void dispc_configure_burst_sizes(void) dispc_ovl_set_burst_size(i, burst_size); } -u32 dispc_ovl_get_burst_size(enum omap_plane plane) +static u32 dispc_ovl_get_burst_size(enum omap_plane plane) { unsigned unit = dss_feat_get_burst_size_unit(); /* burst multiplier is always x8 (see dispc_configure_burst_sizes()) */ @@ -1018,7 +1018,7 @@ static void dispc_read_plane_fifo_sizes(void) } } -u32 dispc_ovl_get_fifo_size(enum omap_plane plane) +static u32 dispc_ovl_get_fifo_size(enum omap_plane plane) { return dispc.fifo_size[plane]; } @@ -1063,6 +1063,24 @@ void dispc_enable_fifomerge(bool enable) REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14); } +void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge) +{ + /* + * All sizes are in bytes. Both the buffer and burst are made of + * buffer_units, and the fifo thresholds must be buffer_unit aligned. + */ + + unsigned buf_unit = dss_feat_get_buffer_size_unit(); + unsigned fifo_size, burst_size; + + burst_size = dispc_ovl_get_burst_size(plane); + fifo_size = dispc_ovl_get_fifo_size(plane); + + *fifo_low = fifo_size - burst_size; + *fifo_high = fifo_size - buf_unit; +} + static void dispc_ovl_set_fir(enum omap_plane plane, int hinc, int vinc, enum omap_color_component color_comp) diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index be331dc5a61..4424c198dbc 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -279,16 +279,6 @@ void omapdss_default_get_resolution(struct omap_dss_device *dssdev, } EXPORT_SYMBOL(omapdss_default_get_resolution); -void default_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high) -{ - unsigned buf_unit = dss_feat_get_buffer_size_unit(); - - *fifo_high = fifo_size - buf_unit; - *fifo_low = fifo_size - burst_size; -} - int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev) { switch (dssdev->type) { diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d4d676c82c1..a4b9d58e8b4 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4524,14 +4524,6 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable) } EXPORT_SYMBOL(omapdss_dsi_enable_te); -void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high) -{ - *fifo_high = fifo_size - burst_size; - *fifo_low = fifo_size - burst_size * 2; -} - int dsi_init_display(struct omap_dss_device *dssdev) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 32ff69fb333..d4b3dff2ead 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -202,9 +202,6 @@ void dss_uninit_device(struct platform_device *pdev, struct omap_dss_device *dssdev); bool dss_use_replication(struct omap_dss_device *dssdev, enum omap_color_mode mode); -void default_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high); /* manager */ int dss_init_overlay_managers(struct platform_device *pdev); @@ -313,9 +310,6 @@ int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, bool is_tft, int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, bool enable_hsdiv); void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); -void dsi_get_overlay_fifo_thresholds(enum omap_plane plane, - u32 fifo_size, u32 burst_size, - u32 *fifo_low, u32 *fifo_high); void dsi_wait_pll_hsdiv_dispc_active(struct platform_device *dsidev); void dsi_wait_pll_hsdiv_dsi_active(struct platform_device *dsidev); struct platform_device *dsi_get_dsidev_from_id(int module); @@ -429,8 +423,8 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high); -u32 dispc_ovl_get_fifo_size(enum omap_plane plane); -u32 dispc_ovl_get_burst_size(enum omap_plane plane); +void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, + u32 *fifo_low, u32 *fifo_high, bool use_fifomerge); int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi, bool ilace, bool replication); int dispc_ovl_enable(enum omap_plane plane, bool enable); -- cgit v1.2.3-70-g09d2 From e0e405b9252e5e8926786d796e0d4293bc90cd56 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 13 Jan 2012 13:18:11 +0200 Subject: OMAPDSS: DISPC: Add naive threshold calc for fifomerge Take fifo merge into use by implementing a rather naive fifo merge threshold calculation: keep the low threshold always the same, but increase the high threshold when fifo merge is used. This should greatly increase the time between pixel data fetches from SDRAM, as the usable fifo size is much larger. However, it probably won't help for fifo underflows, as the low threshols is kept the same. Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 28 ++++++++++++++++++++++++---- drivers/video/omap2/dss/dss_features.c | 6 ++++-- drivers/video/omap2/dss/dss_features.h | 2 ++ 3 files changed, 30 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a75972250a2..374c987038a 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -1072,13 +1072,33 @@ void dispc_ovl_compute_fifo_thresholds(enum omap_plane plane, */ unsigned buf_unit = dss_feat_get_buffer_size_unit(); - unsigned fifo_size, burst_size; + unsigned ovl_fifo_size, total_fifo_size, burst_size; + int i; burst_size = dispc_ovl_get_burst_size(plane); - fifo_size = dispc_ovl_get_fifo_size(plane); + ovl_fifo_size = dispc_ovl_get_fifo_size(plane); - *fifo_low = fifo_size - burst_size; - *fifo_high = fifo_size - buf_unit; + if (use_fifomerge) { + total_fifo_size = 0; + for (i = 0; i < omap_dss_get_num_overlays(); ++i) + total_fifo_size += dispc_ovl_get_fifo_size(i); + } else { + total_fifo_size = ovl_fifo_size; + } + + /* + * We use the same low threshold for both fifomerge and non-fifomerge + * cases, but for fifomerge we calculate the high threshold using the + * combined fifo size + */ + + if (dss_has_feature(FEAT_OMAP3_DSI_FIFO_BUG)) { + *fifo_low = ovl_fifo_size - burst_size * 2; + *fifo_high = total_fifo_size - burst_size; + } else { + *fifo_low = ovl_fifo_size - burst_size; + *fifo_high = total_fifo_size - buf_unit; + } } static void dispc_ovl_set_fir(enum omap_plane plane, diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c index c2456c5bcd3..419419ad049 100644 --- a/drivers/video/omap2/dss/dss_features.c +++ b/drivers/video/omap2/dss/dss_features.c @@ -370,7 +370,8 @@ static const struct omap_dss_features omap3430_dss_features = { FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_FREQSEL | FEAT_DSI_REVERSE_TXCLKESC | FEAT_VENC_REQUIRES_TV_DAC_CLK | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, @@ -394,7 +395,8 @@ static const struct omap_dss_features omap3630_dss_features = { FEAT_ROWREPEATENABLE | FEAT_LINEBUFFERSPLIT | FEAT_RESIZECONF | FEAT_DSI_PLL_PWR_BUG | FEAT_DSI_PLL_FREQSEL | FEAT_CPR | FEAT_PRELOAD | - FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE, + FEAT_FIR_COEF_V | FEAT_ALPHA_FIXED_ZORDER | FEAT_FIFO_MERGE | + FEAT_OMAP3_DSI_FIFO_BUG, .num_mgrs = 2, .num_ovls = 3, diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h index 50caee9192a..5f9b8215677 100644 --- a/drivers/video/omap2/dss/dss_features.h +++ b/drivers/video/omap2/dss/dss_features.h @@ -59,6 +59,8 @@ enum dss_feat_id { FEAT_ALPHA_FIXED_ZORDER = 1 << 26, FEAT_ALPHA_FREE_ZORDER = 1 << 27, FEAT_FIFO_MERGE = 1 << 28, + /* An unknown HW bug causing the normal FIFO thresholds not to work */ + FEAT_OMAP3_DSI_FIFO_BUG = 1 << 29, }; /* DSS register field id */ -- cgit v1.2.3-70-g09d2 From aeec1a6ccbe28c2cea5f19803394f99859566552 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:07 +0530 Subject: OMAPDSS: HDMI: remove duplicate video interface code video interface structure is a duplicate structure with parameters which are already present in ip_data config structure, Thus removing the structure and modifying corresponding code. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 31 ++++++++----------------------- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h | 7 ------- 2 files changed, 8 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index 9af81f18f16..bafbd9fad4b 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -629,8 +629,7 @@ static void hdmi_core_av_packet_config(struct hdmi_ip_data *ip_data, } static void hdmi_wp_init(struct omap_video_timings *timings, - struct hdmi_video_format *video_fmt, - struct hdmi_video_interface *video_int) + struct hdmi_video_format *video_fmt) { pr_debug("Enter hdmi_wp_init\n"); @@ -645,12 +644,6 @@ static void hdmi_wp_init(struct omap_video_timings *timings, video_fmt->y_res = 0; video_fmt->x_res = 0; - video_int->vsp = 0; - video_int->hsp = 0; - - video_int->interlacing = 0; - video_int->tm = 0; /* HDMI_TIMING_SLAVE */ - } void ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data, bool start) @@ -687,17 +680,16 @@ static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_SIZE, l); } -static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data, - struct hdmi_video_interface *video_int) +static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) { u32 r; pr_debug("Enter hdmi_wp_video_config_interface\n"); r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); - r = FLD_MOD(r, video_int->vsp, 7, 7); - r = FLD_MOD(r, video_int->hsp, 6, 6); - r = FLD_MOD(r, video_int->interlacing, 3, 3); - r = FLD_MOD(r, video_int->tm, 1, 0); + r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); + r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); + r = FLD_MOD(r, ip_data->cfg.interlace, 3, 3); + r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); } @@ -725,15 +717,13 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) /* HDMI */ struct omap_video_timings video_timing; struct hdmi_video_format video_format; - struct hdmi_video_interface video_interface; /* HDMI core */ struct hdmi_core_infoframe_avi avi_cfg; struct hdmi_core_video_config v_core_cfg; struct hdmi_core_packet_enable_repeat repeat_cfg; struct hdmi_config *cfg = &ip_data->cfg; - hdmi_wp_init(&video_timing, &video_format, - &video_interface); + hdmi_wp_init(&video_timing, &video_format); hdmi_core_init(&v_core_cfg, &avi_cfg, @@ -748,12 +738,7 @@ void ti_hdmi_4xxx_basic_configure(struct hdmi_ip_data *ip_data) hdmi_wp_video_config_format(ip_data, &video_format); - video_interface.vsp = cfg->timings.vsync_pol; - video_interface.hsp = cfg->timings.hsync_pol; - video_interface.interlacing = cfg->interlace; - video_interface.tm = 1 ; /* HDMI_TIMING_MASTER_24BIT */ - - hdmi_wp_video_config_interface(ip_data, &video_interface); + hdmi_wp_video_config_interface(ip_data); /* * configure core video part diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h index a442998980f..004b4182bdd 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h @@ -517,13 +517,6 @@ struct hdmi_video_format { u32 x_res; /* pixel per line */ }; -struct hdmi_video_interface { - int vsp; /* Vsync polarity */ - int hsp; /* Hsync polarity */ - int interlacing; - int tm; /* Timing mode */ -}; - struct hdmi_audio_format { enum hdmi_stereo_channels stereo_channels; u8 active_chnnls_msk; -- cgit v1.2.3-70-g09d2 From a05ce78f308fa22b6254995c25ff79e82a27de75 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:08 +0530 Subject: OMAPDSS: HDMI: update static timing table Add the vsync polarity, hsync polarity, interlace to hdmi_video_timings. Remove the now duplicate structure hdmi_timings. update the static table structure in HDMI with CEA/VESA code and mode. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 96 +++++++++++++++---------------- drivers/video/omap2/dss/ti_hdmi.h | 14 ++--- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 20 +++---- 3 files changed, 63 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index b4c270edb91..266af264eb9 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -88,42 +88,42 @@ static struct { * map it to corresponding CEA or VESA index. */ -static const struct hdmi_timings cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { - { {640, 480, 25200, 96, 16, 48, 2, 10, 33} , 0 , 0}, - { {1280, 720, 74250, 40, 440, 220, 5, 5, 20}, 1, 1}, - { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1}, - { {720, 480, 27027, 62, 16, 60, 6, 9, 30}, 0, 0}, - { {2880, 576, 108000, 256, 48, 272, 5, 5, 39}, 0, 0}, - { {1440, 240, 27027, 124, 38, 114, 3, 4, 15}, 0, 0}, - { {1440, 288, 27000, 126, 24, 138, 3, 2, 19}, 0, 0}, - { {1920, 540, 74250, 44, 528, 148, 5, 2, 15}, 1, 1}, - { {1920, 540, 74250, 44, 88, 148, 5, 2, 15}, 1, 1}, - { {1920, 1080, 148500, 44, 88, 148, 5, 4, 36}, 1, 1}, - { {720, 576, 27000, 64, 12, 68, 5, 5, 39}, 0, 0}, - { {1440, 576, 54000, 128, 24, 136, 5, 5, 39}, 0, 0}, - { {1920, 1080, 148500, 44, 528, 148, 5, 4, 36}, 1, 1}, - { {2880, 480, 108108, 248, 64, 240, 6, 9, 30}, 0, 0}, - { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36}, 1, 1}, - /* VESA From Here */ - { {640, 480, 25175, 96, 16, 48, 2 , 11, 31}, 0, 0}, - { {800, 600, 40000, 128, 40, 88, 4 , 1, 23}, 1, 1}, - { {848, 480, 33750, 112, 16, 112, 8 , 6, 23}, 1, 1}, - { {1280, 768, 79500, 128, 64, 192, 7 , 3, 20}, 1, 0}, - { {1280, 800, 83500, 128, 72, 200, 6 , 3, 22}, 1, 0}, - { {1360, 768, 85500, 112, 64, 256, 6 , 3, 18}, 1, 1}, - { {1280, 960, 108000, 112, 96, 312, 3 , 1, 36}, 1, 1}, - { {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38}, 1, 1}, - { {1024, 768, 65000, 136, 24, 160, 6, 3, 29}, 0, 0}, - { {1400, 1050, 121750, 144, 88, 232, 4, 3, 32}, 1, 0}, - { {1440, 900, 106500, 152, 80, 232, 6, 3, 25}, 1, 0}, - { {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30}, 1, 0}, - { {1366, 768, 85500, 143, 70, 213, 3, 3, 24}, 1, 1}, - { {1920, 1080, 148500, 44, 148, 80, 5, 4, 36}, 1, 1}, - { {1280, 768, 68250, 32, 48, 80, 7, 3, 12}, 0, 1}, - { {1400, 1050, 101000, 32, 48, 80, 4, 3, 23}, 0, 1}, - { {1680, 1050, 119000, 32, 48, 80, 6, 3, 21}, 0, 1}, - { {1280, 800, 79500, 32, 48, 80, 6, 3, 14}, 0, 1}, - { {1280, 720, 74250, 40, 110, 220, 5, 5, 20}, 1, 1} +static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { +{ {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, +{ {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, +{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, +{ {1920, 540, 74250, 44, 88, 148, 5, 2, 15, 1, 1, 1}, {5, HDMI_HDMI} }, +{ {1440, 240, 27027, 124, 38, 114, 3, 4, 15, 0, 0, 1}, {6, HDMI_HDMI} }, +{ {1920, 1080, 148500, 44, 88, 148, 5, 4, 36, 1, 1, 0}, {16, HDMI_HDMI} }, +{ {720, 576, 27000, 64, 12, 68, 5, 5, 39, 0, 0, 0}, {17, HDMI_HDMI} }, +{ {1280, 720, 74250, 40, 440, 220, 5, 5, 20, 1, 1, 0}, {19, HDMI_HDMI} }, +{ {1920, 540, 74250, 44, 528, 148, 5, 2, 15, 1, 1, 1}, {20, HDMI_HDMI} }, +{ {1440, 288, 27000, 126, 24, 138, 3, 2, 19, 0, 0, 1}, {21, HDMI_HDMI} }, +{ {1440, 576, 54000, 128, 24, 136, 5, 5, 39, 0, 0, 0}, {29, HDMI_HDMI} }, +{ {1920, 1080, 148500, 44, 528, 148, 5, 4, 36, 1, 1, 0}, {31, HDMI_HDMI} }, +{ {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, +{ {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, +{ {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, +/* VESA From Here */ +{ {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, +{ {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, +{ {848, 480, 33750, 112, 16, 112, 8 , 6, 23, 1, 1, 0}, {0xE, HDMI_DVI} }, +{ {1280, 768, 79500, 128, 64, 192, 7 , 3, 20, 1, 0, 0}, {0x17, HDMI_DVI} }, +{ {1280, 800, 83500, 128, 72, 200, 6 , 3, 22, 1, 0, 0}, {0x1C, HDMI_DVI} }, +{ {1360, 768, 85500, 112, 64, 256, 6 , 3, 18, 1, 1, 0}, {0x27, HDMI_DVI} }, +{ {1280, 960, 108000, 112, 96, 312, 3 , 1, 36, 1, 1, 0}, {0x20, HDMI_DVI} }, +{ {1280, 1024, 108000, 112, 48, 248, 3 , 1, 38, 1, 1, 0}, {0x23, HDMI_DVI} }, +{ {1024, 768, 65000, 136, 24, 160, 6, 3, 29, 0, 0, 0}, {0x10, HDMI_DVI} }, +{ {1400, 1050, 121750, 144, 88, 232, 4, 3, 32, 1, 0, 0}, {0x2A, HDMI_DVI} }, +{ {1440, 900, 106500, 152, 80, 232, 6, 3, 25, 1, 0, 0}, {0x2F, HDMI_DVI} }, +{ {1680, 1050, 146250, 176 , 104, 280, 6, 3, 30, 1, 0, 0}, {0x3A, HDMI_DVI} }, +{ {1366, 768, 85500, 143, 70, 213, 3, 3, 24, 1, 1, 0}, {0x51, HDMI_DVI} }, +{ {1920, 1080, 148500, 44, 148, 80, 5, 4, 36, 1, 1, 0}, {0x52, HDMI_DVI} }, +{ {1280, 768, 68250, 32, 48, 80, 7, 3, 12, 0, 1, 0}, {0x16, HDMI_DVI} }, +{ {1400, 1050, 101000, 32, 48, 80, 4, 3, 23, 0, 1, 0}, {0x29, HDMI_DVI} }, +{ {1680, 1050, 119000, 32, 48, 80, 6, 3, 21, 0, 1, 0}, {0x39, HDMI_DVI} }, +{ {1280, 800, 79500, 32, 48, 80, 6, 3, 14, 0, 1, 0}, {0x1B, HDMI_DVI} }, +{ {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } }; /* @@ -253,23 +253,23 @@ static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) static void update_hdmi_timings(struct hdmi_config *cfg, struct omap_video_timings *timings, int code) { - cfg->timings.timings.x_res = timings->x_res; - cfg->timings.timings.y_res = timings->y_res; - cfg->timings.timings.hbp = timings->hbp; - cfg->timings.timings.hfp = timings->hfp; - cfg->timings.timings.hsw = timings->hsw; - cfg->timings.timings.vbp = timings->vbp; - cfg->timings.timings.vfp = timings->vfp; - cfg->timings.timings.vsw = timings->vsw; - cfg->timings.timings.pixel_clock = timings->pixel_clock; - cfg->timings.vsync_pol = cea_vesa_timings[code].vsync_pol; - cfg->timings.hsync_pol = cea_vesa_timings[code].hsync_pol; + cfg->timings.x_res = timings->x_res; + cfg->timings.y_res = timings->y_res; + cfg->timings.hbp = timings->hbp; + cfg->timings.hfp = timings->hfp; + cfg->timings.hsw = timings->hsw; + cfg->timings.vbp = timings->vbp; + cfg->timings.vfp = timings->vfp; + cfg->timings.vsw = timings->vsw; + cfg->timings.pixel_clock = timings->pixel_clock; + cfg->timings.vsync_pol = cea_vesa_timings[code].timings.vsync_pol; + cfg->timings.hsync_pol = cea_vesa_timings[code].timings.hsync_pol; } unsigned long hdmi_get_pixel_clock(void) { /* HDMI Pixel Clock in Mhz */ - return hdmi.ip_data.cfg.timings.timings.pixel_clock * 1000; + return hdmi.ip_data.cfg.timings.pixel_clock * 1000; } static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h index 7503f7f619a..26ec6d1162f 100644 --- a/drivers/video/omap2/dss/ti_hdmi.h +++ b/drivers/video/omap2/dss/ti_hdmi.h @@ -42,6 +42,7 @@ enum hdmi_clk_refsel { HDMI_REFSEL_SYSCLK = 3 }; +/* HDMI timing structure */ struct hdmi_video_timings { u16 x_res; u16 y_res; @@ -53,13 +54,9 @@ struct hdmi_video_timings { u16 vsw; u16 vfp; u16 vbp; -}; - -/* HDMI timing structure */ -struct hdmi_timings { - struct hdmi_video_timings timings; - int vsync_pol; - int hsync_pol; + bool vsync_pol; + bool hsync_pol; + bool interlace; }; struct hdmi_cm { @@ -68,8 +65,7 @@ struct hdmi_cm { }; struct hdmi_config { - struct hdmi_timings timings; - u16 interlace; + struct hdmi_video_timings timings; struct hdmi_cm cm; }; diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index bafbd9fad4b..a229ae71be7 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -656,15 +656,15 @@ static void hdmi_wp_video_init_format(struct hdmi_video_format *video_fmt, { pr_debug("Enter hdmi_wp_video_init_format\n"); - video_fmt->y_res = param->timings.timings.y_res; - video_fmt->x_res = param->timings.timings.x_res; - - timings->hbp = param->timings.timings.hbp; - timings->hfp = param->timings.timings.hfp; - timings->hsw = param->timings.timings.hsw; - timings->vbp = param->timings.timings.vbp; - timings->vfp = param->timings.timings.vfp; - timings->vsw = param->timings.timings.vsw; + video_fmt->y_res = param->timings.y_res; + video_fmt->x_res = param->timings.x_res; + + timings->hbp = param->timings.hbp; + timings->hfp = param->timings.hfp; + timings->hsw = param->timings.hsw; + timings->vbp = param->timings.vbp; + timings->vfp = param->timings.vfp; + timings->vsw = param->timings.vsw; } static void hdmi_wp_video_config_format(struct hdmi_ip_data *ip_data, @@ -688,7 +688,7 @@ static void hdmi_wp_video_config_interface(struct hdmi_ip_data *ip_data) r = hdmi_read_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG); r = FLD_MOD(r, ip_data->cfg.timings.vsync_pol, 7, 7); r = FLD_MOD(r, ip_data->cfg.timings.hsync_pol, 6, 6); - r = FLD_MOD(r, ip_data->cfg.interlace, 3, 3); + r = FLD_MOD(r, ip_data->cfg.timings.interlace, 3, 3); r = FLD_MOD(r, 1, 1, 0); /* HDMI_TIMING_MASTER_24BIT */ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_VIDEO_CFG, r); } -- cgit v1.2.3-70-g09d2 From 46095b2d96bac92c2cc5ca557ec7de73e13311ab Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:09 +0530 Subject: OMAPDSS: HDMI: change the timing match logic Change the timing match logic, Instead of the statically mapped method to get the corresponding timings for a given code and mode, move to a simpler array indexed method. It will help to scale up to add more timings when needed. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 176 ++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 100 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 266af264eb9..6f027d30d5d 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -58,8 +58,6 @@ #define EDID_SIZE_BLOCK0_TIMING_DESCRIPTOR 4 #define EDID_SIZE_BLOCK1_TIMING_DESCRIPTOR 4 -#define OMAP_HDMI_TIMINGS_NB 34 - #define HDMI_DEFAULT_REGN 16 #define HDMI_DEFAULT_REGM2 1 @@ -88,7 +86,7 @@ static struct { * map it to corresponding CEA or VESA index. */ -static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { +static const struct hdmi_config cea_timings[] = { { {640, 480, 25200, 96, 16, 48, 2, 10, 33, 0, 0, 0}, {1, HDMI_HDMI} }, { {720, 480, 27027, 62, 16, 60, 6, 9, 30, 0, 0, 0}, {2, HDMI_HDMI} }, { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {4, HDMI_HDMI} }, @@ -104,6 +102,8 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { { {1920, 1080, 74250, 44, 638, 148, 5, 4, 36, 1, 1, 0}, {32, HDMI_HDMI} }, { {2880, 480, 108108, 248, 64, 240, 6, 9, 30, 0, 0, 0}, {35, HDMI_HDMI} }, { {2880, 576, 108000, 256, 48, 272, 5, 5, 39, 0, 0, 0}, {37, HDMI_HDMI} }, +}; +static const struct hdmi_config vesa_timings[] = { /* VESA From Here */ { {640, 480, 25175, 96, 16, 48, 2 , 11, 31, 0, 0, 0}, {4, HDMI_DVI} }, { {800, 600, 40000, 128, 40, 88, 4 , 1, 23, 1, 1, 0}, {9, HDMI_DVI} }, @@ -126,39 +126,6 @@ static const struct hdmi_config cea_vesa_timings[OMAP_HDMI_TIMINGS_NB] = { { {1280, 720, 74250, 40, 110, 220, 5, 5, 20, 1, 1, 0}, {0x55, HDMI_DVI} } }; -/* - * This is a static mapping array which maps the timing values - * with corresponding CEA / VESA code - */ -static const int code_index[OMAP_HDMI_TIMINGS_NB] = { - 1, 19, 4, 2, 37, 6, 21, 20, 5, 16, 17, 29, 31, 35, 32, - /* <--15 CEA 17--> vesa*/ - 4, 9, 0xE, 0x17, 0x1C, 0x27, 0x20, 0x23, 0x10, 0x2A, - 0X2F, 0x3A, 0X51, 0X52, 0x16, 0x29, 0x39, 0x1B -}; - -/* - * This is reverse static mapping which maps the CEA / VESA code - * to the corresponding timing values - */ -static const int code_cea[39] = { - -1, 0, 3, 3, 2, 8, 5, 5, -1, -1, - -1, -1, -1, -1, -1, -1, 9, 10, 10, 1, - 7, 6, 6, -1, -1, -1, -1, -1, -1, 11, - 11, 12, 14, -1, -1, 13, 13, 4, 4 -}; - -static const int code_vesa[85] = { - -1, -1, -1, -1, 15, -1, -1, -1, -1, 16, - -1, -1, -1, -1, 17, -1, 23, -1, -1, -1, - -1, -1, 29, 18, -1, -1, -1, 32, 19, -1, - -1, -1, 21, -1, -1, 22, -1, -1, -1, 20, - -1, 30, 24, -1, -1, -1, -1, 25, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 31, 26, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 27, 28, -1, 33}; - static int hdmi_runtime_get(void) { int r; @@ -188,82 +155,83 @@ int hdmi_init_display(struct omap_dss_device *dssdev) return 0; } -static int get_timings_index(void) +static const struct hdmi_config *hdmi_find_timing( + const struct hdmi_config *timings_arr, + int len) { - int code; + int i; - if (hdmi.mode == 0) - code = code_vesa[hdmi.code]; - else - code = code_cea[hdmi.code]; + for (i = 0; i < len; i++) { + if (timings_arr[i].cm.code == hdmi.code) + return &timings_arr[i]; + } + return NULL; +} - if (code == -1) { - /* HDMI code 4 corresponds to 640 * 480 VGA */ - hdmi.code = 4; - /* DVI mode 1 corresponds to HDMI 0 to DVI */ - hdmi.mode = HDMI_DVI; +static const struct hdmi_config *hdmi_get_timings(void) +{ + const struct hdmi_config *arr; + int len; + + if (hdmi.mode == HDMI_DVI) { + arr = vesa_timings; + len = ARRAY_SIZE(vesa_timings); + } else { + arr = cea_timings; + len = ARRAY_SIZE(cea_timings); + } + + return hdmi_find_timing(arr, len); +} + +static bool hdmi_timings_compare(struct omap_video_timings *timing1, + const struct hdmi_video_timings *timing2) +{ + int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync; + + if ((timing2->pixel_clock == timing1->pixel_clock) && + (timing2->x_res == timing1->x_res) && + (timing2->y_res == timing1->y_res)) { + + timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp; + timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp; + timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp; + timing1_vsync = timing2->vfp + timing2->vsw + timing2->vbp; - code = code_vesa[hdmi.code]; + DSSDBG("timing1_hsync = %d timing1_vsync = %d"\ + "timing2_hsync = %d timing2_vsync = %d\n", + timing1_hsync, timing1_vsync, + timing2_hsync, timing2_vsync); + + if ((timing1_hsync == timing2_hsync) && + (timing1_vsync == timing2_vsync)) { + return true; + } } - return code; + return false; } static struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing) { - int i = 0, code = -1, temp_vsync = 0, temp_hsync = 0; - int timing_vsync = 0, timing_hsync = 0; - struct hdmi_video_timings temp; + int i; struct hdmi_cm cm = {-1}; DSSDBG("hdmi_get_code\n"); - for (i = 0; i < OMAP_HDMI_TIMINGS_NB; i++) { - temp = cea_vesa_timings[i].timings; - if ((temp.pixel_clock == timing->pixel_clock) && - (temp.x_res == timing->x_res) && - (temp.y_res == timing->y_res)) { - - temp_hsync = temp.hfp + temp.hsw + temp.hbp; - timing_hsync = timing->hfp + timing->hsw + timing->hbp; - temp_vsync = temp.vfp + temp.vsw + temp.vbp; - timing_vsync = timing->vfp + timing->vsw + timing->vbp; - - DSSDBG("temp_hsync = %d , temp_vsync = %d" - "timing_hsync = %d, timing_vsync = %d\n", - temp_hsync, temp_hsync, - timing_hsync, timing_vsync); - - if ((temp_hsync == timing_hsync) && - (temp_vsync == timing_vsync)) { - code = i; - cm.code = code_index[i]; - if (code < 14) - cm.mode = HDMI_HDMI; - else - cm.mode = HDMI_DVI; - DSSDBG("Hdmi_code = %d mode = %d\n", - cm.code, cm.mode); - break; - } + for (i = 0; i < ARRAY_SIZE(cea_timings); i++) { + if (hdmi_timings_compare(timing, &cea_timings[i].timings)) { + cm = cea_timings[i].cm; + goto end; + } + } + for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) { + if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) { + cm = vesa_timings[i].cm; + goto end; } } - return cm; -} +end: return cm; -static void update_hdmi_timings(struct hdmi_config *cfg, - struct omap_video_timings *timings, int code) -{ - cfg->timings.x_res = timings->x_res; - cfg->timings.y_res = timings->y_res; - cfg->timings.hbp = timings->hbp; - cfg->timings.hfp = timings->hfp; - cfg->timings.hsw = timings->hsw; - cfg->timings.vbp = timings->vbp; - cfg->timings.vfp = timings->vfp; - cfg->timings.vsw = timings->vsw; - cfg->timings.pixel_clock = timings->pixel_clock; - cfg->timings.vsync_pol = cea_vesa_timings[code].timings.vsync_pol; - cfg->timings.hsync_pol = cea_vesa_timings[code].timings.hsync_pol; } unsigned long hdmi_get_pixel_clock(void) @@ -325,7 +293,8 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy, static int hdmi_power_on(struct omap_dss_device *dssdev) { - int r, code = 0; + int r; + const struct hdmi_config *timing; struct omap_video_timings *p; unsigned long phy; @@ -341,9 +310,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) dssdev->panel.timings.x_res, dssdev->panel.timings.y_res); - code = get_timings_index(); - update_hdmi_timings(&hdmi.ip_data.cfg, p, code); - + timing = hdmi_get_timings(); + if (timing == NULL) { + /* HDMI code 4 corresponds to 640 * 480 VGA */ + hdmi.code = 4; + /* DVI mode 1 corresponds to HDMI 0 to DVI */ + hdmi.mode = HDMI_DVI; + hdmi.ip_data.cfg = vesa_timings[0]; + } else { + hdmi.ip_data.cfg = *timing; + } phy = p->pixel_clock; hdmi_compute_pll(dssdev, phy, &hdmi.ip_data.pll_data); -- cgit v1.2.3-70-g09d2 From 9e4ed603e6ec71da9e0a7484a694f98dff869068 Mon Sep 17 00:00:00 2001 From: Mythri P K Date: Fri, 6 Jan 2012 17:52:10 +0530 Subject: OMAPDSS: HDMI: remove duplicate code and mode parameter code and mode parameters are already a part of the ip_data structure so no need to keep the same parameters again in hdmi global structure. Signed-off-by: Mythri P K Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/hdmi.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index 6f027d30d5d..92a66798f67 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -66,8 +66,6 @@ static struct { struct omap_display_platform_data *pdata; struct platform_device *pdev; struct hdmi_ip_data ip_data; - int code; - int mode; struct clk *sys_clk; } hdmi; @@ -162,7 +160,7 @@ static const struct hdmi_config *hdmi_find_timing( int i; for (i = 0; i < len; i++) { - if (timings_arr[i].cm.code == hdmi.code) + if (timings_arr[i].cm.code == hdmi.ip_data.cfg.cm.code) return &timings_arr[i]; } return NULL; @@ -173,7 +171,7 @@ static const struct hdmi_config *hdmi_get_timings(void) const struct hdmi_config *arr; int len; - if (hdmi.mode == HDMI_DVI) { + if (hdmi.ip_data.cfg.cm.mode == HDMI_DVI) { arr = vesa_timings; len = ARRAY_SIZE(vesa_timings); } else { @@ -313,9 +311,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) timing = hdmi_get_timings(); if (timing == NULL) { /* HDMI code 4 corresponds to 640 * 480 VGA */ - hdmi.code = 4; + hdmi.ip_data.cfg.cm.code = 4; /* DVI mode 1 corresponds to HDMI 0 to DVI */ - hdmi.mode = HDMI_DVI; + hdmi.ip_data.cfg.cm.mode = HDMI_DVI; hdmi.ip_data.cfg = vesa_timings[0]; } else { hdmi.ip_data.cfg = *timing; @@ -339,8 +337,6 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) goto err; } - hdmi.ip_data.cfg.cm.mode = hdmi.mode; - hdmi.ip_data.cfg.cm.code = hdmi.code; hdmi.ip_data.ops->video_configure(&hdmi.ip_data); /* Make selection of HDMI in DSS */ @@ -407,8 +403,8 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev) struct hdmi_cm cm; cm = hdmi_get_code(&dssdev->panel.timings); - hdmi.code = cm.code; - hdmi.mode = cm.mode; + hdmi.ip_data.cfg.cm.code = cm.code; + hdmi.ip_data.cfg.cm.mode = cm.mode; if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) { int r; @@ -707,7 +703,7 @@ static int hdmi_audio_hw_params(struct snd_pcm_substream *substream, static int hdmi_audio_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - if (!hdmi.mode) { + if (!hdmi.ip_data.cfg.cm.mode) { pr_err("Current video settings do not support audio.\n"); return -EIO; } -- cgit v1.2.3-70-g09d2 From 1149c74419179d57fdcd506424da2444755e65d9 Mon Sep 17 00:00:00 2001 From: Ricardo Neri Date: Thu, 19 Jan 2012 12:21:41 -0600 Subject: OMAPDSS: HDMI: Correct source of the pixel clock in ACR calculation Due to changes in struct hdmi_config, the pixel clock has to be obtained differently. The pixel clock is needed to calculate the CTS value as defined in the HDMI specification. Signed-off-by: Ricardo Neri Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c index a229ae71be7..9bbf9614fe0 100644 --- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c +++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c @@ -1137,7 +1137,7 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data, { u32 r; u32 deep_color = 0; - u32 pclk = ip_data->cfg.timings.timings.pixel_clock; + u32 pclk = ip_data->cfg.timings.pixel_clock; if (n == NULL || cts == NULL) return -EINVAL; -- cgit v1.2.3-70-g09d2 From cc1d3e032df53d83d0ca4d537d8eb67eb5b3e808 Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Tue, 24 Jan 2012 16:44:42 +0100 Subject: OMAPDSS: VENC: fix NULL pointer dereference in DSS2 VENC sysfs debug attr on OMAP4 Commit ba02fa37de80bea10d706f39f076dd848348320a disabled the venc driver registration on OMAP4. Since the driver never gets probed/initialised your get a dereferenceed NULL pointer if you try to get info from /sys/kernel/debug/omapdss/venc Return info message about disabled venc if venc_dump_regs() gets called. Signed-off-by: Danny Kukawka Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/venc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index b3e9f909158..82865bec945 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -699,6 +699,11 @@ void venc_dump_regs(struct seq_file *s) { #define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, venc_read_reg(r)) + if (cpu_is_omap44xx()) { + seq_printf(s, "VENC currently disabled on OMAP44xx\n"); + return; + } + if (venc_runtime_get()) return; -- cgit v1.2.3-70-g09d2 From 6e2a14d2c59f6208310eeb6b031e9d1c22b38c6a Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Tue, 24 Jan 2012 14:00:45 +0100 Subject: OMAPDSS: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. Signed-off-by: Julia Lawall Signed-off-by: Tomi Valkeinen --- drivers/video/omap2/dss/dispc.c | 16 ++++++---------- drivers/video/omap2/dss/dsi.c | 28 +++++++++------------------- drivers/video/omap2/dss/dss.c | 9 +++------ drivers/video/omap2/dss/rfbi.c | 5 ++--- drivers/video/omap2/dss/venc.c | 8 +++----- 5 files changed, 23 insertions(+), 43 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index a5ec7f37c18..6fa866a83f1 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3322,7 +3322,8 @@ static int omap_dispchw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - dispc.base = ioremap(dispc_mem->start, resource_size(dispc_mem)); + dispc.base = devm_ioremap(&pdev->dev, dispc_mem->start, + resource_size(dispc_mem)); if (!dispc.base) { DSSERR("can't ioremap DISPC\n"); r = -ENOMEM; @@ -3332,14 +3333,14 @@ static int omap_dispchw_probe(struct platform_device *pdev) if (dispc.irq < 0) { DSSERR("platform_get_irq failed\n"); r = -ENODEV; - goto err_irq; + goto err_ioremap; } - r = request_irq(dispc.irq, omap_dispc_irq_handler, IRQF_SHARED, - "OMAP DISPC", dispc.pdev); + r = devm_request_irq(&pdev->dev, dispc.irq, omap_dispc_irq_handler, + IRQF_SHARED, "OMAP DISPC", dispc.pdev); if (r < 0) { DSSERR("request_irq failed\n"); - goto err_irq; + goto err_ioremap; } pm_runtime_enable(&pdev->dev); @@ -3362,9 +3363,6 @@ static int omap_dispchw_probe(struct platform_device *pdev) err_runtime_get: pm_runtime_disable(&pdev->dev); - free_irq(dispc.irq, dispc.pdev); -err_irq: - iounmap(dispc.base); err_ioremap: clk_put(dispc.dss_clk); err_get_clk: @@ -3377,8 +3375,6 @@ static int omap_dispchw_remove(struct platform_device *pdev) clk_put(dispc.dss_clk); - free_irq(dispc.irq, dispc.pdev); - iounmap(dispc.base); return 0; } diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index d4d676c82c1..52b93597730 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -4695,7 +4695,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) struct resource *dsi_mem; struct dsi_data *dsi; - dsi = kzalloc(sizeof(*dsi), GFP_KERNEL); + dsi = devm_kzalloc(&dsidev->dev, sizeof(*dsi), GFP_KERNEL); if (!dsi) { r = -ENOMEM; goto err_alloc; @@ -4724,7 +4724,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = dsi_get_clocks(dsidev); if (r) - goto err_get_clk; + goto err_alloc; pm_runtime_enable(&dsidev->dev); @@ -4742,7 +4742,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = -EINVAL; goto err_ioremap; } - dsi->base = ioremap(dsi_mem->start, resource_size(dsi_mem)); + dsi->base = devm_ioremap(&dsidev->dev, dsi_mem->start, + resource_size(dsi_mem)); if (!dsi->base) { DSSERR("can't ioremap DSI\n"); r = -ENOMEM; @@ -4752,14 +4753,14 @@ static int omap_dsihw_probe(struct platform_device *dsidev) if (dsi->irq < 0) { DSSERR("platform_get_irq failed\n"); r = -ENODEV; - goto err_get_irq; + goto err_ioremap; } - r = request_irq(dsi->irq, omap_dsi_irq_handler, IRQF_SHARED, - dev_name(&dsidev->dev), dsi->pdev); + r = devm_request_irq(&dsidev->dev, dsi->irq, omap_dsi_irq_handler, + IRQF_SHARED, dev_name(&dsidev->dev), dsi->pdev); if (r < 0) { DSSERR("request_irq failed\n"); - goto err_get_irq; + goto err_ioremap; } /* DSI VCs initialization */ @@ -4773,7 +4774,7 @@ static int omap_dsihw_probe(struct platform_device *dsidev) r = dsi_runtime_get(dsidev); if (r) - goto err_get_dsi; + goto err_ioremap; rev = dsi_read_reg(dsidev, DSI_REVISION); dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n", @@ -4791,14 +4792,8 @@ static int omap_dsihw_probe(struct platform_device *dsidev) return 0; -err_get_dsi: - free_irq(dsi->irq, dsi->pdev); -err_get_irq: - iounmap(dsi->base); err_ioremap: pm_runtime_disable(&dsidev->dev); -err_get_clk: - kfree(dsi); err_alloc: return r; } @@ -4823,11 +4818,6 @@ static int omap_dsihw_remove(struct platform_device *dsidev) dsi->vdds_dsi_reg = NULL; } - free_irq(dsi->irq, dsi->pdev); - iounmap(dsi->base); - - kfree(dsi); - return 0; } diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 17033457ee8..e75f837c766 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -751,7 +751,8 @@ static int omap_dsshw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - dss.base = ioremap(dss_mem->start, resource_size(dss_mem)); + dss.base = devm_ioremap(&pdev->dev, dss_mem->start, + resource_size(dss_mem)); if (!dss.base) { DSSERR("can't ioremap DSS\n"); r = -ENOMEM; @@ -760,7 +761,7 @@ static int omap_dsshw_probe(struct platform_device *pdev) r = dss_get_clocks(); if (r) - goto err_clocks; + goto err_ioremap; pm_runtime_enable(&pdev->dev); @@ -808,8 +809,6 @@ err_dpi: err_runtime_get: pm_runtime_disable(&pdev->dev); dss_put_clocks(); -err_clocks: - iounmap(dss.base); err_ioremap: return r; } @@ -819,8 +818,6 @@ static int omap_dsshw_remove(struct platform_device *pdev) dpi_exit(); sdi_exit(); - iounmap(dss.base); - pm_runtime_disable(&pdev->dev); dss_put_clocks(); diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 814bb9500dc..159e914063c 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -925,7 +925,8 @@ static int omap_rfbihw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - rfbi.base = ioremap(rfbi_mem->start, resource_size(rfbi_mem)); + rfbi.base = devm_ioremap(&pdev->dev, rfbi_mem->start, + resource_size(rfbi_mem)); if (!rfbi.base) { DSSERR("can't ioremap RFBI\n"); r = -ENOMEM; @@ -963,7 +964,6 @@ err_get_ick: rfbi_runtime_put(); err_get_rfbi: pm_runtime_disable(&pdev->dev); - iounmap(rfbi.base); err_ioremap: return r; } @@ -971,7 +971,6 @@ err_ioremap: static int omap_rfbihw_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); - iounmap(rfbi.base); return 0; } diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 82865bec945..4172232cdec 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -798,7 +798,8 @@ static int omap_venchw_probe(struct platform_device *pdev) r = -EINVAL; goto err_ioremap; } - venc.base = ioremap(venc_mem->start, resource_size(venc_mem)); + venc.base = devm_ioremap(&pdev->dev, venc_mem->start, + resource_size(venc_mem)); if (!venc.base) { DSSERR("can't ioremap VENC\n"); r = -ENOMEM; @@ -807,7 +808,7 @@ static int omap_venchw_probe(struct platform_device *pdev) r = venc_get_clocks(pdev); if (r) - goto err_get_clk; + goto err_ioremap; pm_runtime_enable(&pdev->dev); @@ -825,8 +826,6 @@ static int omap_venchw_probe(struct platform_device *pdev) err_get_venc: pm_runtime_disable(&pdev->dev); venc_put_clocks(); -err_get_clk: - iounmap(venc.base); err_ioremap: return r; } @@ -842,7 +841,6 @@ static int omap_venchw_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); venc_put_clocks(); - iounmap(venc.base); return 0; } -- cgit v1.2.3-70-g09d2 From 49e226323d462785582750d9f38acca5ffa5dd48 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Wed, 25 Jan 2012 12:35:38 +0100 Subject: regulator: Reverse the disable sequence in regulator_bulk_disable() Often there is a need for disabling a set of regulators in order opposite to the enable order. Currently the function regulator_bulk_disable() walks list of regulators in same order as regulator_bulk_enable(). This may cause trouble, especially for devices with mixed analogue and digital circuits. So reverse the disabling sequence of regulator_bulk_disable(). While at it, also correct the comment. Signed-off-by: Sylwester Nawrocki Signed-off-by: Kyungmin Park Signed-off-by: Mark Brown --- drivers/regulator/core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index ca86f39a0fd..daba2f60f7d 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2463,8 +2463,8 @@ EXPORT_SYMBOL_GPL(regulator_bulk_enable); * @return 0 on success, an errno on failure * * This convenience API allows consumers to disable multiple regulator - * clients in a single API call. If any consumers cannot be enabled - * then any others that were disabled will be disabled again prior to + * clients in a single API call. If any consumers cannot be disabled + * then any others that were disabled will be enabled again prior to * return. */ int regulator_bulk_disable(int num_consumers, @@ -2473,7 +2473,7 @@ int regulator_bulk_disable(int num_consumers, int i; int ret; - for (i = 0; i < num_consumers; i++) { + for (i = num_consumers - 1; i >= 0; --i) { ret = regulator_disable(consumers[i].consumer); if (ret != 0) goto err; @@ -2483,7 +2483,7 @@ int regulator_bulk_disable(int num_consumers, err: pr_err("Failed to disable %s: %d\n", consumers[i].supply, ret); - for (--i; i >= 0; --i) + for (++i; i < num_consumers; ++i) regulator_enable(consumers[i].consumer); return ret; -- cgit v1.2.3-70-g09d2 From 7e53b195e412a813e915843adc7e4d91868e8e94 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 20:46:53 +0000 Subject: regmap: Unexport regcache_write() and regcache_read() They have no current users which is fortunate as they don't take the lock and therefore aren't safe to use externally. We'll need to add new operations if direct cache access is needed. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7..99beccfad4d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -211,7 +211,6 @@ int regcache_read(struct regmap *map, return -EINVAL; } -EXPORT_SYMBOL_GPL(regcache_read); /** * regcache_write: Set the value of a given register in the cache. @@ -238,7 +237,6 @@ int regcache_write(struct regmap *map, return 0; } -EXPORT_SYMBOL_GPL(regcache_write); /** * regcache_sync: Sync the register cache with the hardware. -- cgit v1.2.3-70-g09d2 From d9db762708e27c2892db9d8a54e735a8e506e16e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 21:06:33 +0000 Subject: regmap: Skip patch application when the cache is not dirty on sync On the basis that if we don't actually need to resync the cache then the patches are probably also already applied. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index ce2034c10ff..9c6a5c13f1d 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -269,6 +269,9 @@ int regcache_sync(struct regmap *map) name = map->cache_ops->name; trace_regcache_sync(map->dev, name, "start"); + if (!map->cache_dirty) + goto out; + /* Apply any patch first */ for (i = 0; i < map->patch_regs; i++) { ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); @@ -279,8 +282,6 @@ int regcache_sync(struct regmap *map) } } - if (!map->cache_dirty) - goto out; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); } else { -- cgit v1.2.3-70-g09d2 From 8a892d6996b60c822f19ad1844eb15b96ce393c7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 25 Jan 2012 21:05:48 +0000 Subject: regmap: Bypass the cache when applying patches Otherwise any patch that affects a register which is writable may trash cached values. Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 9c6a5c13f1d..ee36bed9479 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -273,6 +273,7 @@ int regcache_sync(struct regmap *map) goto out; /* Apply any patch first */ + map->cache_bypass = 1; for (i = 0; i < map->patch_regs; i++) { ret = _regmap_write(map, map->patch[i].reg, map->patch[i].def); if (ret != 0) { @@ -281,6 +282,7 @@ int regcache_sync(struct regmap *map) goto out; } } + map->cache_bypass = 0; if (map->cache_ops->sync) { ret = map->cache_ops->sync(map); -- cgit v1.2.3-70-g09d2 From 8bca5d1ebb8bf18187256845ba3aaff5fbc01934 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 24 Jan 2012 19:47:21 +0000 Subject: vmxnet3: cleanup tso headers manipulation Use existing helpers to clarify skb headers manipulation. Signed-off-by: Eric Dumazet Cc: Shreyas Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index de7fc345148..be6aa353f6a 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -816,27 +816,24 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq, if (ctx->mss) { /* TSO */ ctx->eth_ip_hdr_size = skb_transport_offset(skb); - ctx->l4_hdr_size = ((struct tcphdr *) - skb_transport_header(skb))->doff * 4; + ctx->l4_hdr_size = tcp_hdrlen(skb); ctx->copy_size = ctx->eth_ip_hdr_size + ctx->l4_hdr_size; } else { if (skb->ip_summed == CHECKSUM_PARTIAL) { ctx->eth_ip_hdr_size = skb_checksum_start_offset(skb); if (ctx->ipv4) { - struct iphdr *iph = (struct iphdr *) - skb_network_header(skb); + const struct iphdr *iph = ip_hdr(skb); + if (iph->protocol == IPPROTO_TCP) - ctx->l4_hdr_size = ((struct tcphdr *) - skb_transport_header(skb))->doff * 4; + ctx->l4_hdr_size = tcp_hdrlen(skb); else if (iph->protocol == IPPROTO_UDP) /* * Use tcp header size so that bytes to * be copied are more than required by * the device. */ - ctx->l4_hdr_size = - sizeof(struct tcphdr); + ctx->l4_hdr_size = sizeof(struct tcphdr); else ctx->l4_hdr_size = 0; } else { @@ -881,14 +878,17 @@ static void vmxnet3_prepare_tso(struct sk_buff *skb, struct vmxnet3_tx_ctx *ctx) { - struct tcphdr *tcph = (struct tcphdr *)skb_transport_header(skb); + struct tcphdr *tcph = tcp_hdr(skb); + if (ctx->ipv4) { - struct iphdr *iph = (struct iphdr *)skb_network_header(skb); + struct iphdr *iph = ip_hdr(skb); + iph->check = 0; tcph->check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, 0, IPPROTO_TCP, 0); } else { - struct ipv6hdr *iph = (struct ipv6hdr *)skb_network_header(skb); + struct ipv6hdr *iph = ipv6_hdr(skb); + tcph->check = ~csum_ipv6_magic(&iph->saddr, &iph->daddr, 0, IPPROTO_TCP, 0); } -- cgit v1.2.3-70-g09d2 From a44acd551467d78a26bfa76ea348225575830efc Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 24 Jan 2012 21:59:31 +0000 Subject: bnx2x: unlock before returning an error We introduced a new return here but forgot to drop the lock. Signed-off-by: Dan Carpenter Acked-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index cb6339c3557..69465c32e5f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1836,6 +1836,7 @@ static int bnx2x_vlan_mac_del_all(struct bnx2x *bp, rc = exeq->remove(bp, exeq->owner, exeq_pos); if (rc) { BNX2X_ERR("Failed to remove command\n"); + spin_unlock_bh(&exeq->lock); return rc; } list_del(&exeq_pos->link); -- cgit v1.2.3-70-g09d2 From 8a3b7a252dca9fb28c23b5bf76c49180a2b60d3b Mon Sep 17 00:00:00 2001 From: "danborkmann@iogearbox.net" Date: Thu, 19 Jan 2012 00:39:31 +0000 Subject: drivers/net/ethernet/xilinx: added Xilinx AXI Ethernet driver This driver adds support for Xilinx 10/100/1000 AXI Ethernet. It can be used, for instance, on Xilinx boards with a Microblaze architecture like the ML605. The patch is against the latest net-next tree and checkpatch clean. Signed-off-by: Ariane Keller Signed-off-by: Daniel Borkmann Signed-off-by: David S. Miller --- MAINTAINERS | 6 + drivers/net/ethernet/xilinx/Kconfig | 8 + drivers/net/ethernet/xilinx/Makefile | 2 + drivers/net/ethernet/xilinx/xilinx_axienet.h | 508 +++++++ drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 1682 +++++++++++++++++++++ drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c | 238 +++ 6 files changed, 2444 insertions(+) create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet.h create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_main.c create mode 100644 drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 93c68d5f1cf..087b65d1258 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7469,6 +7469,12 @@ S: Supported F: Documentation/filesystems/xfs.txt F: fs/xfs/ +XILINX AXI ETHERNET DRIVER +M: Ariane Keller +M: Daniel Borkmann +S: Maintained +F: drivers/net/ethernet/xilinx/xilinx_axienet* + XILINX SYSTEMACE DRIVER M: Grant Likely W: http://www.secretlab.ca/ diff --git a/drivers/net/ethernet/xilinx/Kconfig b/drivers/net/ethernet/xilinx/Kconfig index d5a826063a8..5778a4ae116 100644 --- a/drivers/net/ethernet/xilinx/Kconfig +++ b/drivers/net/ethernet/xilinx/Kconfig @@ -25,6 +25,14 @@ config XILINX_EMACLITE ---help--- This driver supports the 10/100 Ethernet Lite from Xilinx. +config XILINX_AXI_EMAC + tristate "Xilinx 10/100/1000 AXI Ethernet support" + depends on (PPC32 || MICROBLAZE) + select PHYLIB + ---help--- + This driver supports the 10/100/1000 Ethernet from Xilinx for the + AXI bus interface used in Xilinx Virtex FPGAs. + config XILINX_LL_TEMAC tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver" depends on (PPC || MICROBLAZE) diff --git a/drivers/net/ethernet/xilinx/Makefile b/drivers/net/ethernet/xilinx/Makefile index 5feac734ea4..214205e975e 100644 --- a/drivers/net/ethernet/xilinx/Makefile +++ b/drivers/net/ethernet/xilinx/Makefile @@ -5,3 +5,5 @@ ll_temac-objs := ll_temac_main.o ll_temac_mdio.o obj-$(CONFIG_XILINX_LL_TEMAC) += ll_temac.o obj-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o +xilinx_emac-objs := xilinx_axienet_main.o xilinx_axienet_mdio.o +obj-$(CONFIG_XILINX_AXI_EMAC) += xilinx_emac.o diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet.h b/drivers/net/ethernet/xilinx/xilinx_axienet.h new file mode 100644 index 00000000000..cc83af083fd --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet.h @@ -0,0 +1,508 @@ +/* + * Definitions for Xilinx Axi Ethernet device driver. + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + */ + +#ifndef XILINX_AXIENET_H +#define XILINX_AXIENET_H + +#include +#include +#include + +/* Packet size info */ +#define XAE_HDR_SIZE 14 /* Size of Ethernet header */ +#define XAE_HDR_VLAN_SIZE 18 /* Size of an Ethernet hdr + VLAN */ +#define XAE_TRL_SIZE 4 /* Size of Ethernet trailer (FCS) */ +#define XAE_MTU 1500 /* Max MTU of an Ethernet frame */ +#define XAE_JUMBO_MTU 9000 /* Max MTU of a jumbo Eth. frame */ + +#define XAE_MAX_FRAME_SIZE (XAE_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE) +#define XAE_MAX_VLAN_FRAME_SIZE (XAE_MTU + XAE_HDR_VLAN_SIZE + XAE_TRL_SIZE) +#define XAE_MAX_JUMBO_FRAME_SIZE (XAE_JUMBO_MTU + XAE_HDR_SIZE + XAE_TRL_SIZE) + +/* Configuration options */ + +/* Accept all incoming packets. Default: disabled (cleared) */ +#define XAE_OPTION_PROMISC (1 << 0) + +/* Jumbo frame support for Tx & Rx. Default: disabled (cleared) */ +#define XAE_OPTION_JUMBO (1 << 1) + +/* VLAN Rx & Tx frame support. Default: disabled (cleared) */ +#define XAE_OPTION_VLAN (1 << 2) + +/* Enable recognition of flow control frames on Rx. Default: enabled (set) */ +#define XAE_OPTION_FLOW_CONTROL (1 << 4) + +/* Strip FCS and PAD from incoming frames. Note: PAD from VLAN frames is not + * stripped. Default: disabled (set) */ +#define XAE_OPTION_FCS_STRIP (1 << 5) + +/* Generate FCS field and add PAD automatically for outgoing frames. + * Default: enabled (set) */ +#define XAE_OPTION_FCS_INSERT (1 << 6) + +/* Enable Length/Type error checking for incoming frames. When this option is + * set, the MAC will filter frames that have a mismatched type/length field + * and if XAE_OPTION_REPORT_RXERR is set, the user is notified when these + * types of frames are encountered. When this option is cleared, the MAC will + * allow these types of frames to be received. Default: enabled (set) */ +#define XAE_OPTION_LENTYPE_ERR (1 << 7) + +/* Enable the transmitter. Default: enabled (set) */ +#define XAE_OPTION_TXEN (1 << 11) + +/* Enable the receiver. Default: enabled (set) */ +#define XAE_OPTION_RXEN (1 << 12) + +/* Default options set when device is initialized or reset */ +#define XAE_OPTION_DEFAULTS \ + (XAE_OPTION_TXEN | \ + XAE_OPTION_FLOW_CONTROL | \ + XAE_OPTION_RXEN) + +/* Axi DMA Register definitions */ + +#define XAXIDMA_TX_CR_OFFSET 0x00000000 /* Channel control */ +#define XAXIDMA_TX_SR_OFFSET 0x00000004 /* Status */ +#define XAXIDMA_TX_CDESC_OFFSET 0x00000008 /* Current descriptor pointer */ +#define XAXIDMA_TX_TDESC_OFFSET 0x00000010 /* Tail descriptor pointer */ + +#define XAXIDMA_RX_CR_OFFSET 0x00000030 /* Channel control */ +#define XAXIDMA_RX_SR_OFFSET 0x00000034 /* Status */ +#define XAXIDMA_RX_CDESC_OFFSET 0x00000038 /* Current descriptor pointer */ +#define XAXIDMA_RX_TDESC_OFFSET 0x00000040 /* Tail descriptor pointer */ + +#define XAXIDMA_CR_RUNSTOP_MASK 0x00000001 /* Start/stop DMA channel */ +#define XAXIDMA_CR_RESET_MASK 0x00000004 /* Reset DMA engine */ + +#define XAXIDMA_BD_NDESC_OFFSET 0x00 /* Next descriptor pointer */ +#define XAXIDMA_BD_BUFA_OFFSET 0x08 /* Buffer address */ +#define XAXIDMA_BD_CTRL_LEN_OFFSET 0x18 /* Control/buffer length */ +#define XAXIDMA_BD_STS_OFFSET 0x1C /* Status */ +#define XAXIDMA_BD_USR0_OFFSET 0x20 /* User IP specific word0 */ +#define XAXIDMA_BD_USR1_OFFSET 0x24 /* User IP specific word1 */ +#define XAXIDMA_BD_USR2_OFFSET 0x28 /* User IP specific word2 */ +#define XAXIDMA_BD_USR3_OFFSET 0x2C /* User IP specific word3 */ +#define XAXIDMA_BD_USR4_OFFSET 0x30 /* User IP specific word4 */ +#define XAXIDMA_BD_ID_OFFSET 0x34 /* Sw ID */ +#define XAXIDMA_BD_HAS_STSCNTRL_OFFSET 0x38 /* Whether has stscntrl strm */ +#define XAXIDMA_BD_HAS_DRE_OFFSET 0x3C /* Whether has DRE */ + +#define XAXIDMA_BD_HAS_DRE_SHIFT 8 /* Whether has DRE shift */ +#define XAXIDMA_BD_HAS_DRE_MASK 0xF00 /* Whether has DRE mask */ +#define XAXIDMA_BD_WORDLEN_MASK 0xFF /* Whether has DRE mask */ + +#define XAXIDMA_BD_CTRL_LENGTH_MASK 0x007FFFFF /* Requested len */ +#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ +#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ +#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /* All control bits */ + +#define XAXIDMA_DELAY_MASK 0xFF000000 /* Delay timeout counter */ +#define XAXIDMA_COALESCE_MASK 0x00FF0000 /* Coalesce counter */ + +#define XAXIDMA_DELAY_SHIFT 24 +#define XAXIDMA_COALESCE_SHIFT 16 + +#define XAXIDMA_IRQ_IOC_MASK 0x00001000 /* Completion intr */ +#define XAXIDMA_IRQ_DELAY_MASK 0x00002000 /* Delay interrupt */ +#define XAXIDMA_IRQ_ERROR_MASK 0x00004000 /* Error interrupt */ +#define XAXIDMA_IRQ_ALL_MASK 0x00007000 /* All interrupts */ + +/* Default TX/RX Threshold and waitbound values for SGDMA mode */ +#define XAXIDMA_DFT_TX_THRESHOLD 24 +#define XAXIDMA_DFT_TX_WAITBOUND 254 +#define XAXIDMA_DFT_RX_THRESHOLD 24 +#define XAXIDMA_DFT_RX_WAITBOUND 254 + +#define XAXIDMA_BD_CTRL_TXSOF_MASK 0x08000000 /* First tx packet */ +#define XAXIDMA_BD_CTRL_TXEOF_MASK 0x04000000 /* Last tx packet */ +#define XAXIDMA_BD_CTRL_ALL_MASK 0x0C000000 /* All control bits */ + +#define XAXIDMA_BD_STS_ACTUAL_LEN_MASK 0x007FFFFF /* Actual len */ +#define XAXIDMA_BD_STS_COMPLETE_MASK 0x80000000 /* Completed */ +#define XAXIDMA_BD_STS_DEC_ERR_MASK 0x40000000 /* Decode error */ +#define XAXIDMA_BD_STS_SLV_ERR_MASK 0x20000000 /* Slave error */ +#define XAXIDMA_BD_STS_INT_ERR_MASK 0x10000000 /* Internal err */ +#define XAXIDMA_BD_STS_ALL_ERR_MASK 0x70000000 /* All errors */ +#define XAXIDMA_BD_STS_RXSOF_MASK 0x08000000 /* First rx pkt */ +#define XAXIDMA_BD_STS_RXEOF_MASK 0x04000000 /* Last rx pkt */ +#define XAXIDMA_BD_STS_ALL_MASK 0xFC000000 /* All status bits */ + +#define XAXIDMA_BD_MINIMUM_ALIGNMENT 0x40 + +/* Axi Ethernet registers definition */ +#define XAE_RAF_OFFSET 0x00000000 /* Reset and Address filter */ +#define XAE_TPF_OFFSET 0x00000004 /* Tx Pause Frame */ +#define XAE_IFGP_OFFSET 0x00000008 /* Tx Inter-frame gap adjustment*/ +#define XAE_IS_OFFSET 0x0000000C /* Interrupt status */ +#define XAE_IP_OFFSET 0x00000010 /* Interrupt pending */ +#define XAE_IE_OFFSET 0x00000014 /* Interrupt enable */ +#define XAE_TTAG_OFFSET 0x00000018 /* Tx VLAN TAG */ +#define XAE_RTAG_OFFSET 0x0000001C /* Rx VLAN TAG */ +#define XAE_UAWL_OFFSET 0x00000020 /* Unicast address word lower */ +#define XAE_UAWU_OFFSET 0x00000024 /* Unicast address word upper */ +#define XAE_TPID0_OFFSET 0x00000028 /* VLAN TPID0 register */ +#define XAE_TPID1_OFFSET 0x0000002C /* VLAN TPID1 register */ +#define XAE_PPST_OFFSET 0x00000030 /* PCS PMA Soft Temac Status Reg */ +#define XAE_RCW0_OFFSET 0x00000400 /* Rx Configuration Word 0 */ +#define XAE_RCW1_OFFSET 0x00000404 /* Rx Configuration Word 1 */ +#define XAE_TC_OFFSET 0x00000408 /* Tx Configuration */ +#define XAE_FCC_OFFSET 0x0000040C /* Flow Control Configuration */ +#define XAE_EMMC_OFFSET 0x00000410 /* EMAC mode configuration */ +#define XAE_PHYC_OFFSET 0x00000414 /* RGMII/SGMII configuration */ +#define XAE_MDIO_MC_OFFSET 0x00000500 /* MII Management Config */ +#define XAE_MDIO_MCR_OFFSET 0x00000504 /* MII Management Control */ +#define XAE_MDIO_MWD_OFFSET 0x00000508 /* MII Management Write Data */ +#define XAE_MDIO_MRD_OFFSET 0x0000050C /* MII Management Read Data */ +#define XAE_MDIO_MIS_OFFSET 0x00000600 /* MII Management Interrupt Status */ +#define XAE_MDIO_MIP_OFFSET 0x00000620 /* MII Mgmt Interrupt Pending + * register offset */ +#define XAE_MDIO_MIE_OFFSET 0x00000640 /* MII Management Interrupt Enable + * register offset */ +#define XAE_MDIO_MIC_OFFSET 0x00000660 /* MII Management Interrupt Clear + * register offset. */ +#define XAE_UAW0_OFFSET 0x00000700 /* Unicast address word 0 */ +#define XAE_UAW1_OFFSET 0x00000704 /* Unicast address word 1 */ +#define XAE_FMI_OFFSET 0x00000708 /* Filter Mask Index */ +#define XAE_AF0_OFFSET 0x00000710 /* Address Filter 0 */ +#define XAE_AF1_OFFSET 0x00000714 /* Address Filter 1 */ + +#define XAE_TX_VLAN_DATA_OFFSET 0x00004000 /* TX VLAN data table address */ +#define XAE_RX_VLAN_DATA_OFFSET 0x00008000 /* RX VLAN data table address */ +#define XAE_MCAST_TABLE_OFFSET 0x00020000 /* Multicast table address */ + +/* Bit Masks for Axi Ethernet RAF register */ +#define XAE_RAF_MCSTREJ_MASK 0x00000002 /* Reject receive multicast + * destination address */ +#define XAE_RAF_BCSTREJ_MASK 0x00000004 /* Reject receive broadcast + * destination address */ +#define XAE_RAF_TXVTAGMODE_MASK 0x00000018 /* Tx VLAN TAG mode */ +#define XAE_RAF_RXVTAGMODE_MASK 0x00000060 /* Rx VLAN TAG mode */ +#define XAE_RAF_TXVSTRPMODE_MASK 0x00000180 /* Tx VLAN STRIP mode */ +#define XAE_RAF_RXVSTRPMODE_MASK 0x00000600 /* Rx VLAN STRIP mode */ +#define XAE_RAF_NEWFNCENBL_MASK 0x00000800 /* New function mode */ +#define XAE_RAF_EMULTIFLTRENBL_MASK 0x00001000 /* Exteneded Multicast + * Filtering mode + */ +#define XAE_RAF_STATSRST_MASK 0x00002000 /* Stats. Counter Reset */ +#define XAE_RAF_RXBADFRMEN_MASK 0x00004000 /* Recv Bad Frame Enable */ +#define XAE_RAF_TXVTAGMODE_SHIFT 3 /* Tx Tag mode shift bits */ +#define XAE_RAF_RXVTAGMODE_SHIFT 5 /* Rx Tag mode shift bits */ +#define XAE_RAF_TXVSTRPMODE_SHIFT 7 /* Tx strip mode shift bits*/ +#define XAE_RAF_RXVSTRPMODE_SHIFT 9 /* Rx Strip mode shift bits*/ + +/* Bit Masks for Axi Ethernet TPF and IFGP registers */ +#define XAE_TPF_TPFV_MASK 0x0000FFFF /* Tx pause frame value */ +#define XAE_IFGP0_IFGP_MASK 0x0000007F /* Transmit inter-frame + * gap adjustment value */ + +/* Bit Masks for Axi Ethernet IS, IE and IP registers, Same masks apply + * for all 3 registers. */ +#define XAE_INT_HARDACSCMPLT_MASK 0x00000001 /* Hard register access + * complete */ +#define XAE_INT_AUTONEG_MASK 0x00000002 /* Auto negotiation + * complete */ +#define XAE_INT_RXCMPIT_MASK 0x00000004 /* Rx complete */ +#define XAE_INT_RXRJECT_MASK 0x00000008 /* Rx frame rejected */ +#define XAE_INT_RXFIFOOVR_MASK 0x00000010 /* Rx fifo overrun */ +#define XAE_INT_TXCMPIT_MASK 0x00000020 /* Tx complete */ +#define XAE_INT_RXDCMLOCK_MASK 0x00000040 /* Rx Dcm Lock */ +#define XAE_INT_MGTRDY_MASK 0x00000080 /* MGT clock Lock */ +#define XAE_INT_PHYRSTCMPLT_MASK 0x00000100 /* Phy Reset complete */ +#define XAE_INT_ALL_MASK 0x0000003F /* All the ints */ + +#define XAE_INT_RECV_ERROR_MASK \ + (XAE_INT_RXRJECT_MASK | XAE_INT_RXFIFOOVR_MASK) /* INT bits that + * indicate receive + * errors */ + +/* Bit masks for Axi Ethernet VLAN TPID Word 0 register */ +#define XAE_TPID_0_MASK 0x0000FFFF /* TPID 0 */ +#define XAE_TPID_1_MASK 0xFFFF0000 /* TPID 1 */ + +/* Bit masks for Axi Ethernet VLAN TPID Word 1 register */ +#define XAE_TPID_2_MASK 0x0000FFFF /* TPID 0 */ +#define XAE_TPID_3_MASK 0xFFFF0000 /* TPID 1 */ + +/* Bit masks for Axi Ethernet RCW1 register */ +#define XAE_RCW1_RST_MASK 0x80000000 /* Reset */ +#define XAE_RCW1_JUM_MASK 0x40000000 /* Jumbo frame enable */ +#define XAE_RCW1_FCS_MASK 0x20000000 /* In-Band FCS enable + * (FCS not stripped) */ +#define XAE_RCW1_RX_MASK 0x10000000 /* Receiver enable */ +#define XAE_RCW1_VLAN_MASK 0x08000000 /* VLAN frame enable */ +#define XAE_RCW1_LT_DIS_MASK 0x02000000 /* Length/type field valid check + * disable */ +#define XAE_RCW1_CL_DIS_MASK 0x01000000 /* Control frame Length check + * disable */ +#define XAE_RCW1_PAUSEADDR_MASK 0x0000FFFF /* Pause frame source address + * bits [47:32]. Bits [31:0] are + * stored in register RCW0 */ + +/* Bit masks for Axi Ethernet TC register */ +#define XAE_TC_RST_MASK 0x80000000 /* Reset */ +#define XAE_TC_JUM_MASK 0x40000000 /* Jumbo frame enable */ +#define XAE_TC_FCS_MASK 0x20000000 /* In-Band FCS enable + * (FCS not generated) */ +#define XAE_TC_TX_MASK 0x10000000 /* Transmitter enable */ +#define XAE_TC_VLAN_MASK 0x08000000 /* VLAN frame enable */ +#define XAE_TC_IFG_MASK 0x02000000 /* Inter-frame gap adjustment + * enable */ + +/* Bit masks for Axi Ethernet FCC register */ +#define XAE_FCC_FCRX_MASK 0x20000000 /* Rx flow control enable */ +#define XAE_FCC_FCTX_MASK 0x40000000 /* Tx flow control enable */ + +/* Bit masks for Axi Ethernet EMMC register */ +#define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */ +#define XAE_EMMC_RGMII_MASK 0x20000000 /* RGMII mode enable */ +#define XAE_EMMC_SGMII_MASK 0x10000000 /* SGMII mode enable */ +#define XAE_EMMC_GPCS_MASK 0x08000000 /* 1000BaseX mode enable */ +#define XAE_EMMC_HOST_MASK 0x04000000 /* Host interface enable */ +#define XAE_EMMC_TX16BIT 0x02000000 /* 16 bit Tx client enable */ +#define XAE_EMMC_RX16BIT 0x01000000 /* 16 bit Rx client enable */ +#define XAE_EMMC_LINKSPD_10 0x00000000 /* Link Speed mask for 10 Mbit */ +#define XAE_EMMC_LINKSPD_100 0x40000000 /* Link Speed mask for 100 Mbit */ +#define XAE_EMMC_LINKSPD_1000 0x80000000 /* Link Speed mask for 1000 Mbit */ + +/* Bit masks for Axi Ethernet PHYC register */ +#define XAE_PHYC_SGMIILINKSPEED_MASK 0xC0000000 /* SGMII link speed mask*/ +#define XAE_PHYC_RGMIILINKSPEED_MASK 0x0000000C /* RGMII link speed */ +#define XAE_PHYC_RGMIIHD_MASK 0x00000002 /* RGMII Half-duplex */ +#define XAE_PHYC_RGMIILINK_MASK 0x00000001 /* RGMII link status */ +#define XAE_PHYC_RGLINKSPD_10 0x00000000 /* RGMII link 10 Mbit */ +#define XAE_PHYC_RGLINKSPD_100 0x00000004 /* RGMII link 100 Mbit */ +#define XAE_PHYC_RGLINKSPD_1000 0x00000008 /* RGMII link 1000 Mbit */ +#define XAE_PHYC_SGLINKSPD_10 0x00000000 /* SGMII link 10 Mbit */ +#define XAE_PHYC_SGLINKSPD_100 0x40000000 /* SGMII link 100 Mbit */ +#define XAE_PHYC_SGLINKSPD_1000 0x80000000 /* SGMII link 1000 Mbit */ + +/* Bit masks for Axi Ethernet MDIO interface MC register */ +#define XAE_MDIO_MC_MDIOEN_MASK 0x00000040 /* MII management enable */ +#define XAE_MDIO_MC_CLOCK_DIVIDE_MAX 0x3F /* Maximum MDIO divisor */ + +/* Bit masks for Axi Ethernet MDIO interface MCR register */ +#define XAE_MDIO_MCR_PHYAD_MASK 0x1F000000 /* Phy Address Mask */ +#define XAE_MDIO_MCR_PHYAD_SHIFT 24 /* Phy Address Shift */ +#define XAE_MDIO_MCR_REGAD_MASK 0x001F0000 /* Reg Address Mask */ +#define XAE_MDIO_MCR_REGAD_SHIFT 16 /* Reg Address Shift */ +#define XAE_MDIO_MCR_OP_MASK 0x0000C000 /* Operation Code Mask */ +#define XAE_MDIO_MCR_OP_SHIFT 13 /* Operation Code Shift */ +#define XAE_MDIO_MCR_OP_READ_MASK 0x00008000 /* Op Code Read Mask */ +#define XAE_MDIO_MCR_OP_WRITE_MASK 0x00004000 /* Op Code Write Mask */ +#define XAE_MDIO_MCR_INITIATE_MASK 0x00000800 /* Ready Mask */ +#define XAE_MDIO_MCR_READY_MASK 0x00000080 /* Ready Mask */ + +/* Bit masks for Axi Ethernet MDIO interface MIS, MIP, MIE, MIC registers */ +#define XAE_MDIO_INT_MIIM_RDY_MASK 0x00000001 /* MIIM Interrupt */ + +/* Bit masks for Axi Ethernet UAW1 register */ +#define XAE_UAW1_UNICASTADDR_MASK 0x0000FFFF /* Station address bits + * [47:32]; Station address + * bits [31:0] are stored in + * register UAW0 */ + +/* Bit masks for Axi Ethernet FMI register */ +#define XAE_FMI_PM_MASK 0x80000000 /* Promis. mode enable */ +#define XAE_FMI_IND_MASK 0x00000003 /* Index Mask */ + +#define XAE_MDIO_DIV_DFT 29 /* Default MDIO clock divisor */ + +/* Defines for different options for C_PHY_TYPE parameter in Axi Ethernet IP */ +#define XAE_PHY_TYPE_MII 0 +#define XAE_PHY_TYPE_GMII 1 +#define XAE_PHY_TYPE_RGMII_1_3 2 +#define XAE_PHY_TYPE_RGMII_2_0 3 +#define XAE_PHY_TYPE_SGMII 4 +#define XAE_PHY_TYPE_1000BASE_X 5 + +#define XAE_MULTICAST_CAM_TABLE_NUM 4 /* Total number of entries in the + * hardware multicast table. */ + +/* Axi Ethernet Synthesis features */ +#define XAE_FEATURE_PARTIAL_RX_CSUM (1 << 0) +#define XAE_FEATURE_PARTIAL_TX_CSUM (1 << 1) +#define XAE_FEATURE_FULL_RX_CSUM (1 << 2) +#define XAE_FEATURE_FULL_TX_CSUM (1 << 3) + +#define XAE_NO_CSUM_OFFLOAD 0 + +#define XAE_FULL_CSUM_STATUS_MASK 0x00000038 +#define XAE_IP_UDP_CSUM_VALIDATED 0x00000003 +#define XAE_IP_TCP_CSUM_VALIDATED 0x00000002 + +#define DELAY_OF_ONE_MILLISEC 1000 + +/** + * struct axidma_bd - Axi Dma buffer descriptor layout + * @next: MM2S/S2MM Next Descriptor Pointer + * @reserved1: Reserved and not used + * @phys: MM2S/S2MM Buffer Address + * @reserved2: Reserved and not used + * @reserved3: Reserved and not used + * @reserved4: Reserved and not used + * @cntrl: MM2S/S2MM Control value + * @status: MM2S/S2MM Status value + * @app0: MM2S/S2MM User Application Field 0. + * @app1: MM2S/S2MM User Application Field 1. + * @app2: MM2S/S2MM User Application Field 2. + * @app3: MM2S/S2MM User Application Field 3. + * @app4: MM2S/S2MM User Application Field 4. + * @sw_id_offset: MM2S/S2MM Sw ID + * @reserved5: Reserved and not used + * @reserved6: Reserved and not used + */ +struct axidma_bd { + u32 next; /* Physical address of next buffer descriptor */ + u32 reserved1; + u32 phys; + u32 reserved2; + u32 reserved3; + u32 reserved4; + u32 cntrl; + u32 status; + u32 app0; + u32 app1; /* TX start << 16 | insert */ + u32 app2; /* TX csum seed */ + u32 app3; + u32 app4; + u32 sw_id_offset; + u32 reserved5; + u32 reserved6; +}; + +/** + * struct axienet_local - axienet private per device data + * @ndev: Pointer for net_device to which it will be attached. + * @dev: Pointer to device structure + * @phy_dev: Pointer to PHY device structure attached to the axienet_local + * @phy_node: Pointer to device node structure + * @mii_bus: Pointer to MII bus structure + * @mdio_irqs: IRQs table for MDIO bus required in mii_bus structure + * @regs: Base address for the axienet_local device address space + * @dma_regs: Base address for the axidma device address space + * @dma_err_tasklet: Tasklet structure to process Axi DMA errors + * @tx_irq: Axidma TX IRQ number + * @rx_irq: Axidma RX IRQ number + * @temac_type: axienet type to identify between soft and hard temac + * @phy_type: Phy type to identify between MII/GMII/RGMII/SGMII/1000 Base-X + * @options: AxiEthernet option word + * @last_link: Phy link state in which the PHY was negotiated earlier + * @features: Stores the extended features supported by the axienet hw + * @tx_bd_v: Virtual address of the TX buffer descriptor ring + * @tx_bd_p: Physical address(start address) of the TX buffer descr. ring + * @rx_bd_v: Virtual address of the RX buffer descriptor ring + * @rx_bd_p: Physical address(start address) of the RX buffer descr. ring + * @tx_bd_ci: Stores the index of the Tx buffer descriptor in the ring being + * accessed currently. Used while alloc. BDs before a TX starts + * @tx_bd_tail: Stores the index of the Tx buffer descriptor in the ring being + * accessed currently. Used while processing BDs after the TX + * completed. + * @rx_bd_ci: Stores the index of the Rx buffer descriptor in the ring being + * accessed currently. + * @max_frm_size: Stores the maximum size of the frame that can be that + * Txed/Rxed in the existing hardware. If jumbo option is + * supported, the maximum frame size would be 9k. Else it is + * 1522 bytes (assuming support for basic VLAN) + * @jumbo_support: Stores hardware configuration for jumbo support. If hardware + * can handle jumbo packets, this entry will be 1, else 0. + */ +struct axienet_local { + struct net_device *ndev; + struct device *dev; + + /* Connection to PHY device */ + struct phy_device *phy_dev; /* Pointer to PHY device */ + struct device_node *phy_node; + + /* MDIO bus data */ + struct mii_bus *mii_bus; /* MII bus reference */ + int mdio_irqs[PHY_MAX_ADDR]; /* IRQs table for MDIO bus */ + + /* IO registers, dma functions and IRQs */ + void __iomem *regs; + void __iomem *dma_regs; + + struct tasklet_struct dma_err_tasklet; + + int tx_irq; + int rx_irq; + u32 temac_type; + u32 phy_type; + + u32 options; /* Current options word */ + u32 last_link; + u32 features; + + /* Buffer descriptors */ + struct axidma_bd *tx_bd_v; + dma_addr_t tx_bd_p; + struct axidma_bd *rx_bd_v; + dma_addr_t rx_bd_p; + u32 tx_bd_ci; + u32 tx_bd_tail; + u32 rx_bd_ci; + + u32 max_frm_size; + u32 jumbo_support; + + int csum_offload_on_tx_path; + int csum_offload_on_rx_path; + + u32 coalesce_count_rx; + u32 coalesce_count_tx; +}; + +/** + * struct axiethernet_option - Used to set axi ethernet hardware options + * @opt: Option to be set. + * @reg: Register offset to be written for setting the option + * @m_or: Mask to be ORed for setting the option in the register + */ +struct axienet_option { + u32 opt; + u32 reg; + u32 m_or; +}; + +/** + * axienet_ior - Memory mapped Axi Ethernet register read + * @lp: Pointer to axienet local structure + * @offset: Address offset from the base address of Axi Ethernet core + * + * returns: The contents of the Axi Ethernet register + * + * This function returns the contents of the corresponding register. + */ +static inline u32 axienet_ior(struct axienet_local *lp, off_t offset) +{ + return in_be32(lp->regs + offset); +} + +/** + * axienet_iow - Memory mapped Axi Ethernet register write + * @lp: Pointer to axienet local structure + * @offset: Address offset from the base address of Axi Ethernet core + * @value: Value to be written into the Axi Ethernet register + * + * This function writes the desired value into the corresponding Axi Ethernet + * register. + */ +static inline void axienet_iow(struct axienet_local *lp, off_t offset, + u32 value) +{ + out_be32((lp->regs + offset), value); +} + +/* Function prototypes visible in xilinx_axienet_mdio.c for other files */ +int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np); +int axienet_mdio_wait_until_ready(struct axienet_local *lp); +void axienet_mdio_teardown(struct axienet_local *lp); + +#endif /* XILINX_AXI_ENET_H */ diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c new file mode 100644 index 00000000000..ea50caf8925 --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -0,0 +1,1682 @@ +/* + * Xilinx Axi Ethernet device driver + * + * Copyright (c) 2008 Nissin Systems Co., Ltd., Yoshio Kashiwagi + * Copyright (c) 2005-2008 DLA Systems, David H. Lynch Jr. + * Copyright (c) 2008-2009 Secret Lab Technologies Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + * + * This is a driver for the Xilinx Axi Ethernet which is used in the Virtex6 + * and Spartan6. + * + * TODO: + * - Add Axi Fifo support. + * - Factor out Axi DMA code into separate driver. + * - Test and fix basic multicast filtering. + * - Add support for extended multicast filtering. + * - Test basic VLAN support. + * - Add support for extended VLAN support. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "xilinx_axienet.h" + +/* Descriptors defines for Tx and Rx DMA - 2^n for the best performance */ +#define TX_BD_NUM 64 +#define RX_BD_NUM 128 + +/* Must be shorter than length of ethtool_drvinfo.driver field to fit */ +#define DRIVER_NAME "xaxienet" +#define DRIVER_DESCRIPTION "Xilinx Axi Ethernet driver" +#define DRIVER_VERSION "1.00a" + +#define AXIENET_REGS_N 32 + +/* Match table for of_platform binding */ +static struct of_device_id axienet_of_match[] __devinitdata = { + { .compatible = "xlnx,axi-ethernet-1.00.a", }, + { .compatible = "xlnx,axi-ethernet-1.01.a", }, + { .compatible = "xlnx,axi-ethernet-2.01.a", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, axienet_of_match); + +/* Option table for setting up Axi Ethernet hardware options */ +static struct axienet_option axienet_options[] = { + /* Turn on jumbo packet support for both Rx and Tx */ + { + .opt = XAE_OPTION_JUMBO, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_JUM_MASK, + }, { + .opt = XAE_OPTION_JUMBO, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_JUM_MASK, + }, { /* Turn on VLAN packet support for both Rx and Tx */ + .opt = XAE_OPTION_VLAN, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_VLAN_MASK, + }, { + .opt = XAE_OPTION_VLAN, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_VLAN_MASK, + }, { /* Turn on FCS stripping on receive packets */ + .opt = XAE_OPTION_FCS_STRIP, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_FCS_MASK, + }, { /* Turn on FCS insertion on transmit packets */ + .opt = XAE_OPTION_FCS_INSERT, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_FCS_MASK, + }, { /* Turn off length/type field checking on receive packets */ + .opt = XAE_OPTION_LENTYPE_ERR, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_LT_DIS_MASK, + }, { /* Turn on Rx flow control */ + .opt = XAE_OPTION_FLOW_CONTROL, + .reg = XAE_FCC_OFFSET, + .m_or = XAE_FCC_FCRX_MASK, + }, { /* Turn on Tx flow control */ + .opt = XAE_OPTION_FLOW_CONTROL, + .reg = XAE_FCC_OFFSET, + .m_or = XAE_FCC_FCTX_MASK, + }, { /* Turn on promiscuous frame filtering */ + .opt = XAE_OPTION_PROMISC, + .reg = XAE_FMI_OFFSET, + .m_or = XAE_FMI_PM_MASK, + }, { /* Enable transmitter */ + .opt = XAE_OPTION_TXEN, + .reg = XAE_TC_OFFSET, + .m_or = XAE_TC_TX_MASK, + }, { /* Enable receiver */ + .opt = XAE_OPTION_RXEN, + .reg = XAE_RCW1_OFFSET, + .m_or = XAE_RCW1_RX_MASK, + }, + {} +}; + +/** + * axienet_dma_in32 - Memory mapped Axi DMA register read + * @lp: Pointer to axienet local structure + * @reg: Address offset from the base address of the Axi DMA core + * + * returns: The contents of the Axi DMA register + * + * This function returns the contents of the corresponding Axi DMA register. + */ +static inline u32 axienet_dma_in32(struct axienet_local *lp, off_t reg) +{ + return in_be32(lp->dma_regs + reg); +} + +/** + * axienet_dma_out32 - Memory mapped Axi DMA register write. + * @lp: Pointer to axienet local structure + * @reg: Address offset from the base address of the Axi DMA core + * @value: Value to be written into the Axi DMA register + * + * This function writes the desired value into the corresponding Axi DMA + * register. + */ +static inline void axienet_dma_out32(struct axienet_local *lp, + off_t reg, u32 value) +{ + out_be32((lp->dma_regs + reg), value); +} + +/** + * axienet_dma_bd_release - Release buffer descriptor rings + * @ndev: Pointer to the net_device structure + * + * This function is used to release the descriptors allocated in + * axienet_dma_bd_init. axienet_dma_bd_release is called when Axi Ethernet + * driver stop api is called. + */ +static void axienet_dma_bd_release(struct net_device *ndev) +{ + int i; + struct axienet_local *lp = netdev_priv(ndev); + + for (i = 0; i < RX_BD_NUM; i++) { + dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys, + lp->max_frm_size, DMA_FROM_DEVICE); + dev_kfree_skb((struct sk_buff *) + (lp->rx_bd_v[i].sw_id_offset)); + } + + if (lp->rx_bd_v) { + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * RX_BD_NUM, + lp->rx_bd_v, + lp->rx_bd_p); + } + if (lp->tx_bd_v) { + dma_free_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * TX_BD_NUM, + lp->tx_bd_v, + lp->tx_bd_p); + } +} + +/** + * axienet_dma_bd_init - Setup buffer descriptor rings for Axi DMA + * @ndev: Pointer to the net_device structure + * + * returns: 0, on success + * -ENOMEM, on failure + * + * This function is called to initialize the Rx and Tx DMA descriptor + * rings. This initializes the descriptors with required default values + * and is called when Axi Ethernet driver reset is called. + */ +static int axienet_dma_bd_init(struct net_device *ndev) +{ + u32 cr; + int i; + struct sk_buff *skb; + struct axienet_local *lp = netdev_priv(ndev); + + /* Reset the indexes which are used for accessing the BDs */ + lp->tx_bd_ci = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + + /* + * Allocate the Tx and Rx buffer descriptors. + */ + lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->tx_bd_v) * TX_BD_NUM, + &lp->tx_bd_p, + GFP_KERNEL); + if (!lp->tx_bd_v) { + dev_err(&ndev->dev, "unable to allocate DMA Tx buffer " + "descriptors"); + goto out; + } + + lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent, + sizeof(*lp->rx_bd_v) * RX_BD_NUM, + &lp->rx_bd_p, + GFP_KERNEL); + if (!lp->rx_bd_v) { + dev_err(&ndev->dev, "unable to allocate DMA Rx buffer " + "descriptors"); + goto out; + } + + memset(lp->tx_bd_v, 0, sizeof(*lp->tx_bd_v) * TX_BD_NUM); + for (i = 0; i < TX_BD_NUM; i++) { + lp->tx_bd_v[i].next = lp->tx_bd_p + + sizeof(*lp->tx_bd_v) * + ((i + 1) % TX_BD_NUM); + } + + memset(lp->rx_bd_v, 0, sizeof(*lp->rx_bd_v) * RX_BD_NUM); + for (i = 0; i < RX_BD_NUM; i++) { + lp->rx_bd_v[i].next = lp->rx_bd_p + + sizeof(*lp->rx_bd_v) * + ((i + 1) % RX_BD_NUM); + + skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); + if (!skb) { + dev_err(&ndev->dev, "alloc_skb error %d\n", i); + goto out; + } + + lp->rx_bd_v[i].sw_id_offset = (u32) skb; + lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent, + skb->data, + lp->max_frm_size, + DMA_FROM_DEVICE); + lp->rx_bd_v[i].cntrl = lp->max_frm_size; + } + + /* Start updating the Rx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = ((cr & ~XAXIDMA_COALESCE_MASK) | + ((lp->coalesce_count_rx) << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = ((cr & ~XAXIDMA_DELAY_MASK) | + (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + /* Start updating the Tx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = (((cr & ~XAXIDMA_COALESCE_MASK)) | + ((lp->coalesce_count_tx) << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = (((cr & ~XAXIDMA_DELAY_MASK)) | + (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + /* Populate the tail pointer and bring the Rx Axi DMA engine out of + * halted state. This will make the Rx side ready for reception.*/ + axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + + /* Write to the RS (Run-stop) bit in the Tx channel control register. + * Tx channel is now ready to run. But only after we write to the + * tail pointer register that the Tx channel will start transmitting */ + axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + + return 0; +out: + axienet_dma_bd_release(ndev); + return -ENOMEM; +} + +/** + * axienet_set_mac_address - Write the MAC address + * @ndev: Pointer to the net_device structure + * @address: 6 byte Address to be written as MAC address + * + * This function is called to initialize the MAC address of the Axi Ethernet + * core. It writes to the UAW0 and UAW1 registers of the core. + */ +static void axienet_set_mac_address(struct net_device *ndev, void *address) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (address) + memcpy(ndev->dev_addr, address, ETH_ALEN); + if (!is_valid_ether_addr(ndev->dev_addr)) + random_ether_addr(ndev->dev_addr); + + /* Set up unicast MAC address filter set its mac address */ + axienet_iow(lp, XAE_UAW0_OFFSET, + (ndev->dev_addr[0]) | + (ndev->dev_addr[1] << 8) | + (ndev->dev_addr[2] << 16) | + (ndev->dev_addr[3] << 24)); + axienet_iow(lp, XAE_UAW1_OFFSET, + (((axienet_ior(lp, XAE_UAW1_OFFSET)) & + ~XAE_UAW1_UNICASTADDR_MASK) | + (ndev->dev_addr[4] | + (ndev->dev_addr[5] << 8)))); +} + +/** + * netdev_set_mac_address - Write the MAC address (from outside the driver) + * @ndev: Pointer to the net_device structure + * @p: 6 byte Address to be written as MAC address + * + * returns: 0 for all conditions. Presently, there is no failure case. + * + * This function is called to initialize the MAC address of the Axi Ethernet + * core. It calls the core specific axienet_set_mac_address. This is the + * function that goes into net_device_ops structure entry ndo_set_mac_address. + */ +static int netdev_set_mac_address(struct net_device *ndev, void *p) +{ + struct sockaddr *addr = p; + axienet_set_mac_address(ndev, addr->sa_data); + return 0; +} + +/** + * axienet_set_multicast_list - Prepare the multicast table + * @ndev: Pointer to the net_device structure + * + * This function is called to initialize the multicast table during + * initialization. The Axi Ethernet basic multicast support has a four-entry + * multicast table which is initialized here. Additionally this function + * goes into the net_device_ops structure entry ndo_set_multicast_list. This + * means whenever the multicast table entries need to be updated this + * function gets called. + */ +static void axienet_set_multicast_list(struct net_device *ndev) +{ + int i; + u32 reg, af0reg, af1reg; + struct axienet_local *lp = netdev_priv(ndev); + + if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) || + netdev_mc_count(ndev) > XAE_MULTICAST_CAM_TABLE_NUM) { + /* We must make the kernel realize we had to move into + * promiscuous mode. If it was a promiscuous mode request + * the flag is already set. If not we set it. */ + ndev->flags |= IFF_PROMISC; + reg = axienet_ior(lp, XAE_FMI_OFFSET); + reg |= XAE_FMI_PM_MASK; + axienet_iow(lp, XAE_FMI_OFFSET, reg); + dev_info(&ndev->dev, "Promiscuous mode enabled.\n"); + } else if (!netdev_mc_empty(ndev)) { + struct netdev_hw_addr *ha; + + i = 0; + netdev_for_each_mc_addr(ha, ndev) { + if (i >= XAE_MULTICAST_CAM_TABLE_NUM) + break; + + af0reg = (ha->addr[0]); + af0reg |= (ha->addr[1] << 8); + af0reg |= (ha->addr[2] << 16); + af0reg |= (ha->addr[3] << 24); + + af1reg = (ha->addr[4]); + af1reg |= (ha->addr[5] << 8); + + reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; + reg |= i; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_AF0_OFFSET, af0reg); + axienet_iow(lp, XAE_AF1_OFFSET, af1reg); + i++; + } + } else { + reg = axienet_ior(lp, XAE_FMI_OFFSET); + reg &= ~XAE_FMI_PM_MASK; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + + for (i = 0; i < XAE_MULTICAST_CAM_TABLE_NUM; i++) { + reg = axienet_ior(lp, XAE_FMI_OFFSET) & 0xFFFFFF00; + reg |= i; + + axienet_iow(lp, XAE_FMI_OFFSET, reg); + axienet_iow(lp, XAE_AF0_OFFSET, 0); + axienet_iow(lp, XAE_AF1_OFFSET, 0); + } + + dev_info(&ndev->dev, "Promiscuous mode disabled.\n"); + } +} + +/** + * axienet_setoptions - Set an Axi Ethernet option + * @ndev: Pointer to the net_device structure + * @options: Option to be enabled/disabled + * + * The Axi Ethernet core has multiple features which can be selectively turned + * on or off. The typical options could be jumbo frame option, basic VLAN + * option, promiscuous mode option etc. This function is used to set or clear + * these options in the Axi Ethernet hardware. This is done through + * axienet_option structure . + */ +static void axienet_setoptions(struct net_device *ndev, u32 options) +{ + int reg; + struct axienet_local *lp = netdev_priv(ndev); + struct axienet_option *tp = &axienet_options[0]; + + while (tp->opt) { + reg = ((axienet_ior(lp, tp->reg)) & ~(tp->m_or)); + if (options & tp->opt) + reg |= tp->m_or; + axienet_iow(lp, tp->reg, reg); + tp++; + } + + lp->options |= options; +} + +static void __axienet_device_reset(struct axienet_local *lp, + struct device *dev, off_t offset) +{ + u32 timeout; + /* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset + * process of Axi DMA takes a while to complete as all pending + * commands/transfers will be flushed or completed during this + * reset process. */ + axienet_dma_out32(lp, offset, XAXIDMA_CR_RESET_MASK); + timeout = DELAY_OF_ONE_MILLISEC; + while (axienet_dma_in32(lp, offset) & XAXIDMA_CR_RESET_MASK) { + udelay(1); + if (--timeout == 0) { + dev_err(dev, "axienet_device_reset DMA " + "reset timeout!\n"); + break; + } + } +} + +/** + * axienet_device_reset - Reset and initialize the Axi Ethernet hardware. + * @ndev: Pointer to the net_device structure + * + * This function is called to reset and initialize the Axi Ethernet core. This + * is typically called during initialization. It does a reset of the Axi DMA + * Rx/Tx channels and initializes the Axi DMA BDs. Since Axi DMA reset lines + * areconnected to Axi Ethernet reset lines, this in turn resets the Axi + * Ethernet core. No separate hardware reset is done for the Axi Ethernet + * core. + */ +static void axienet_device_reset(struct net_device *ndev) +{ + u32 axienet_status; + struct axienet_local *lp = netdev_priv(ndev); + + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + + lp->max_frm_size = XAE_MAX_VLAN_FRAME_SIZE; + lp->options &= (~XAE_OPTION_JUMBO); + + if ((ndev->mtu > XAE_MTU) && + (ndev->mtu <= XAE_JUMBO_MTU) && + (lp->jumbo_support)) { + lp->max_frm_size = ndev->mtu + XAE_HDR_VLAN_SIZE + + XAE_TRL_SIZE; + lp->options |= XAE_OPTION_JUMBO; + } + + if (axienet_dma_bd_init(ndev)) { + dev_err(&ndev->dev, "axienet_device_reset descriptor " + "allocation failed\n"); + } + + axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET); + axienet_status &= ~XAE_RCW1_RX_MASK; + axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status); + + axienet_status = axienet_ior(lp, XAE_IP_OFFSET); + if (axienet_status & XAE_INT_RXRJECT_MASK) + axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK); + + axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK); + + /* Sync default options with HW but leave receiver and + * transmitter disabled.*/ + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + axienet_set_mac_address(ndev, NULL); + axienet_set_multicast_list(ndev); + axienet_setoptions(ndev, lp->options); + + ndev->trans_start = jiffies; +} + +/** + * axienet_adjust_link - Adjust the PHY link speed/duplex. + * @ndev: Pointer to the net_device structure + * + * This function is called to change the speed and duplex setting after + * auto negotiation is done by the PHY. This is the function that gets + * registered with the PHY interface through the "of_phy_connect" call. + */ +static void axienet_adjust_link(struct net_device *ndev) +{ + u32 emmc_reg; + u32 link_state; + u32 setspeed = 1; + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phy = lp->phy_dev; + + link_state = phy->speed | (phy->duplex << 1) | phy->link; + if (lp->last_link != link_state) { + if ((phy->speed == SPEED_10) || (phy->speed == SPEED_100)) { + if (lp->phy_type == XAE_PHY_TYPE_1000BASE_X) + setspeed = 0; + } else { + if ((phy->speed == SPEED_1000) && + (lp->phy_type == XAE_PHY_TYPE_MII)) + setspeed = 0; + } + + if (setspeed == 1) { + emmc_reg = axienet_ior(lp, XAE_EMMC_OFFSET); + emmc_reg &= ~XAE_EMMC_LINKSPEED_MASK; + + switch (phy->speed) { + case SPEED_1000: + emmc_reg |= XAE_EMMC_LINKSPD_1000; + break; + case SPEED_100: + emmc_reg |= XAE_EMMC_LINKSPD_100; + break; + case SPEED_10: + emmc_reg |= XAE_EMMC_LINKSPD_10; + break; + default: + dev_err(&ndev->dev, "Speed other than 10, 100 " + "or 1Gbps is not supported\n"); + break; + } + + axienet_iow(lp, XAE_EMMC_OFFSET, emmc_reg); + lp->last_link = link_state; + phy_print_status(phy); + } else { + dev_err(&ndev->dev, "Error setting Axi Ethernet " + "mac speed\n"); + } + } +} + +/** + * axienet_start_xmit_done - Invoked once a transmit is completed by the + * Axi DMA Tx channel. + * @ndev: Pointer to the net_device structure + * + * This function is invoked from the Axi DMA Tx isr to notify the completion + * of transmit operation. It clears fields in the corresponding Tx BDs and + * unmaps the corresponding buffer so that CPU can regain ownership of the + * buffer. It finally invokes "netif_wake_queue" to restart transmission if + * required. + */ +static void axienet_start_xmit_done(struct net_device *ndev) +{ + u32 size = 0; + u32 packets = 0; + struct axienet_local *lp = netdev_priv(ndev); + struct axidma_bd *cur_p; + unsigned int status = 0; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + status = cur_p->status; + while (status & XAXIDMA_BD_STS_COMPLETE_MASK) { + dma_unmap_single(ndev->dev.parent, cur_p->phys, + (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), + DMA_TO_DEVICE); + if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff *)cur_p->app4); + /*cur_p->phys = 0;*/ + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app4 = 0; + cur_p->status = 0; + + size += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; + packets++; + + lp->tx_bd_ci = ++lp->tx_bd_ci % TX_BD_NUM; + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + status = cur_p->status; + } + + ndev->stats.tx_packets += packets; + ndev->stats.tx_bytes += size; + netif_wake_queue(ndev); +} + +/** + * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy + * @lp: Pointer to the axienet_local structure + * @num_frag: The number of BDs to check for + * + * returns: 0, on success + * NETDEV_TX_BUSY, if any of the descriptors are not free + * + * This function is invoked before BDs are allocated and transmission starts. + * This function returns 0 if a BD or group of BDs can be allocated for + * transmission. If the BD or any of the BDs are not free the function + * returns a busy status. This is invoked from axienet_start_xmit. + */ +static inline int axienet_check_tx_bd_space(struct axienet_local *lp, + int num_frag) +{ + struct axidma_bd *cur_p; + cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % TX_BD_NUM]; + if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK) + return NETDEV_TX_BUSY; + return 0; +} + +/** + * axienet_start_xmit - Starts the transmission. + * @skb: sk_buff pointer that contains data to be Txed. + * @ndev: Pointer to net_device structure. + * + * returns: NETDEV_TX_OK, on success + * NETDEV_TX_BUSY, if any of the descriptors are not free + * + * This function is invoked from upper layers to initiate transmission. The + * function uses the next available free BDs and populates their fields to + * start the transmission. Additionally if checksum offloading is supported, + * it populates AXI Stream Control fields with appropriate values. + */ +static int axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) +{ + u32 ii; + u32 num_frag; + u32 csum_start_off; + u32 csum_index_off; + skb_frag_t *frag; + dma_addr_t tail_p; + struct axienet_local *lp = netdev_priv(ndev); + struct axidma_bd *cur_p; + + num_frag = skb_shinfo(skb)->nr_frags; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + + if (axienet_check_tx_bd_space(lp, num_frag)) { + if (!netif_queue_stopped(ndev)) + netif_stop_queue(ndev); + return NETDEV_TX_BUSY; + } + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + if (lp->features & XAE_FEATURE_FULL_TX_CSUM) { + /* Tx Full Checksum Offload Enabled */ + cur_p->app0 |= 2; + } else if (lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) { + csum_start_off = skb_transport_offset(skb); + csum_index_off = csum_start_off + skb->csum_offset; + /* Tx Partial Checksum Offload Enabled */ + cur_p->app0 |= 1; + cur_p->app1 = (csum_start_off << 16) | csum_index_off; + } + } else if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + cur_p->app0 |= 2; /* Tx Full Checksum Offload Enabled */ + } + + cur_p->cntrl = skb_headlen(skb) | XAXIDMA_BD_CTRL_TXSOF_MASK; + cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, + skb_headlen(skb), DMA_TO_DEVICE); + + for (ii = 0; ii < num_frag; ii++) { + lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + frag = &skb_shinfo(skb)->frags[ii]; + cur_p->phys = dma_map_single(ndev->dev.parent, + skb_frag_address(frag), + skb_frag_size(frag), + DMA_TO_DEVICE); + cur_p->cntrl = skb_frag_size(frag); + } + + cur_p->cntrl |= XAXIDMA_BD_CTRL_TXEOF_MASK; + cur_p->app4 = (unsigned long)skb; + + tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail; + /* Start the transfer */ + axienet_dma_out32(lp, XAXIDMA_TX_TDESC_OFFSET, tail_p); + lp->tx_bd_tail = ++lp->tx_bd_tail % TX_BD_NUM; + + return NETDEV_TX_OK; +} + +/** + * axienet_recv - Is called from Axi DMA Rx Isr to complete the received + * BD processing. + * @ndev: Pointer to net_device structure. + * + * This function is invoked from the Axi DMA Rx isr to process the Rx BDs. It + * does minimal processing and invokes "netif_rx" to complete further + * processing. + */ +static void axienet_recv(struct net_device *ndev) +{ + u32 length; + u32 csumstatus; + u32 size = 0; + u32 packets = 0; + dma_addr_t tail_p; + struct axienet_local *lp = netdev_priv(ndev); + struct sk_buff *skb, *new_skb; + struct axidma_bd *cur_p; + + tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + + while ((cur_p->status & XAXIDMA_BD_STS_COMPLETE_MASK)) { + skb = (struct sk_buff *) (cur_p->sw_id_offset); + length = cur_p->app4 & 0x0000FFFF; + + dma_unmap_single(ndev->dev.parent, cur_p->phys, + lp->max_frm_size, + DMA_FROM_DEVICE); + + skb_put(skb, length); + skb->protocol = eth_type_trans(skb, ndev); + /*skb_checksum_none_assert(skb);*/ + skb->ip_summed = CHECKSUM_NONE; + + /* if we're doing Rx csum offload, set it up */ + if (lp->features & XAE_FEATURE_FULL_RX_CSUM) { + csumstatus = (cur_p->app2 & + XAE_FULL_CSUM_STATUS_MASK) >> 3; + if ((csumstatus == XAE_IP_TCP_CSUM_VALIDATED) || + (csumstatus == XAE_IP_UDP_CSUM_VALIDATED)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; + } + } else if ((lp->features & XAE_FEATURE_PARTIAL_RX_CSUM) != 0 && + skb->protocol == __constant_htons(ETH_P_IP) && + skb->len > 64) { + skb->csum = be32_to_cpu(cur_p->app3 & 0xFFFF); + skb->ip_summed = CHECKSUM_COMPLETE; + } + + netif_rx(skb); + + size += length; + packets++; + + new_skb = netdev_alloc_skb_ip_align(ndev, lp->max_frm_size); + if (!new_skb) { + dev_err(&ndev->dev, "no memory for new sk_buff\n"); + return; + } + cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data, + lp->max_frm_size, + DMA_FROM_DEVICE); + cur_p->cntrl = lp->max_frm_size; + cur_p->status = 0; + cur_p->sw_id_offset = (u32) new_skb; + + lp->rx_bd_ci = ++lp->rx_bd_ci % RX_BD_NUM; + cur_p = &lp->rx_bd_v[lp->rx_bd_ci]; + } + + ndev->stats.rx_packets += packets; + ndev->stats.rx_bytes += size; + + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, tail_p); +} + +/** + * axienet_tx_irq - Tx Done Isr. + * @irq: irq number + * @_ndev: net_device pointer + * + * returns: IRQ_HANDLED for all cases. + * + * This is the Axi DMA Tx done Isr. It invokes "axienet_start_xmit_done" + * to complete the BD processing. + */ +static irqreturn_t axienet_tx_irq(int irq, void *_ndev) +{ + u32 cr; + unsigned int status; + struct net_device *ndev = _ndev; + struct axienet_local *lp = netdev_priv(ndev); + + status = axienet_dma_in32(lp, XAXIDMA_TX_SR_OFFSET); + if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) { + axienet_start_xmit_done(lp->ndev); + goto out; + } + if (!(status & XAXIDMA_IRQ_ALL_MASK)) + dev_err(&ndev->dev, "No interrupts asserted in Tx path"); + if (status & XAXIDMA_IRQ_ERROR_MASK) { + dev_err(&ndev->dev, "DMA Tx error 0x%x\n", status); + dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + (lp->tx_bd_v[lp->tx_bd_ci]).phys); + + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + tasklet_schedule(&lp->dma_err_tasklet); + } +out: + axienet_dma_out32(lp, XAXIDMA_TX_SR_OFFSET, status); + return IRQ_HANDLED; +} + +/** + * axienet_rx_irq - Rx Isr. + * @irq: irq number + * @_ndev: net_device pointer + * + * returns: IRQ_HANDLED for all cases. + * + * This is the Axi DMA Rx Isr. It invokes "axienet_recv" to complete the BD + * processing. + */ +static irqreturn_t axienet_rx_irq(int irq, void *_ndev) +{ + u32 cr; + unsigned int status; + struct net_device *ndev = _ndev; + struct axienet_local *lp = netdev_priv(ndev); + + status = axienet_dma_in32(lp, XAXIDMA_RX_SR_OFFSET); + if (status & (XAXIDMA_IRQ_IOC_MASK | XAXIDMA_IRQ_DELAY_MASK)) { + axienet_recv(lp->ndev); + goto out; + } + if (!(status & XAXIDMA_IRQ_ALL_MASK)) + dev_err(&ndev->dev, "No interrupts asserted in Rx path"); + if (status & XAXIDMA_IRQ_ERROR_MASK) { + dev_err(&ndev->dev, "DMA Rx error 0x%x\n", status); + dev_err(&ndev->dev, "Current BD is at: 0x%x\n", + (lp->rx_bd_v[lp->rx_bd_ci]).phys); + + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* Finally write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Disable coalesce, delay timer and error interrupts */ + cr &= (~XAXIDMA_IRQ_ALL_MASK); + /* write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + tasklet_schedule(&lp->dma_err_tasklet); + } +out: + axienet_dma_out32(lp, XAXIDMA_RX_SR_OFFSET, status); + return IRQ_HANDLED; +} + +/** + * axienet_open - Driver open routine. + * @ndev: Pointer to net_device structure + * + * returns: 0, on success. + * -ENODEV, if PHY cannot be connected to + * non-zero error value on failure + * + * This is the driver open routine. It calls phy_start to start the PHY device. + * It also allocates interrupt service routines, enables the interrupt lines + * and ISR handling. Axi Ethernet core is reset through Axi DMA core. Buffer + * descriptors are initialized. + */ +static int axienet_open(struct net_device *ndev) +{ + int ret, mdio_mcreg; + struct axienet_local *lp = netdev_priv(ndev); + + dev_dbg(&ndev->dev, "axienet_open()\n"); + + mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + /* Disable the MDIO interface till Axi Ethernet Reset is completed. + * When we do an Axi Ethernet reset, it resets the complete core + * including the MDIO. If MDIO is not disabled when the reset + * process is started, MDIO will be broken afterwards. */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, + (mdio_mcreg & (~XAE_MDIO_MC_MDIOEN_MASK))); + axienet_device_reset(ndev); + /* Enable the MDIO */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg); + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + if (lp->phy_node) { + lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node, + axienet_adjust_link, 0, + PHY_INTERFACE_MODE_GMII); + if (!lp->phy_dev) { + dev_err(lp->dev, "of_phy_connect() failed\n"); + return -ENODEV; + } + phy_start(lp->phy_dev); + } + + /* Enable interrupts for Axi DMA Tx */ + ret = request_irq(lp->tx_irq, axienet_tx_irq, 0, ndev->name, ndev); + if (ret) + goto err_tx_irq; + /* Enable interrupts for Axi DMA Rx */ + ret = request_irq(lp->rx_irq, axienet_rx_irq, 0, ndev->name, ndev); + if (ret) + goto err_rx_irq; + /* Enable tasklets for Axi DMA error handling */ + tasklet_enable(&lp->dma_err_tasklet); + return 0; + +err_rx_irq: + free_irq(lp->tx_irq, ndev); +err_tx_irq: + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + dev_err(lp->dev, "request_irq() failed\n"); + return ret; +} + +/** + * axienet_stop - Driver stop routine. + * @ndev: Pointer to net_device structure + * + * returns: 0, on success. + * + * This is the driver stop routine. It calls phy_disconnect to stop the PHY + * device. It also removes the interrupt handlers and disables the interrupts. + * The Axi DMA Tx/Rx BDs are released. + */ +static int axienet_stop(struct net_device *ndev) +{ + u32 cr; + struct axienet_local *lp = netdev_priv(ndev); + + dev_dbg(&ndev->dev, "axienet_close()\n"); + + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr & (~XAXIDMA_CR_RUNSTOP_MASK)); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr & (~XAXIDMA_CR_RUNSTOP_MASK)); + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + + tasklet_disable(&lp->dma_err_tasklet); + + free_irq(lp->tx_irq, ndev); + free_irq(lp->rx_irq, ndev); + + if (lp->phy_dev) + phy_disconnect(lp->phy_dev); + lp->phy_dev = NULL; + + axienet_dma_bd_release(ndev); + return 0; +} + +/** + * axienet_change_mtu - Driver change mtu routine. + * @ndev: Pointer to net_device structure + * @new_mtu: New mtu value to be applied + * + * returns: Always returns 0 (success). + * + * This is the change mtu driver routine. It checks if the Axi Ethernet + * hardware supports jumbo frames before changing the mtu. This can be + * called only when the device is not up. + */ +static int axienet_change_mtu(struct net_device *ndev, int new_mtu) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) + return -EBUSY; + if (lp->jumbo_support) { + if ((new_mtu > XAE_JUMBO_MTU) || (new_mtu < 64)) + return -EINVAL; + ndev->mtu = new_mtu; + } else { + if ((new_mtu > XAE_MTU) || (new_mtu < 64)) + return -EINVAL; + ndev->mtu = new_mtu; + } + + return 0; +} + +#ifdef CONFIG_NET_POLL_CONTROLLER +/** + * axienet_poll_controller - Axi Ethernet poll mechanism. + * @ndev: Pointer to net_device structure + * + * This implements Rx/Tx ISR poll mechanisms. The interrupts are disabled prior + * to polling the ISRs and are enabled back after the polling is done. + */ +static void axienet_poll_controller(struct net_device *ndev) +{ + struct axienet_local *lp = netdev_priv(ndev); + disable_irq(lp->tx_irq); + disable_irq(lp->rx_irq); + axienet_rx_irq(lp->tx_irq, ndev); + axienet_tx_irq(lp->rx_irq, ndev); + enable_irq(lp->tx_irq); + enable_irq(lp->rx_irq); +} +#endif + +static const struct net_device_ops axienet_netdev_ops = { + .ndo_open = axienet_open, + .ndo_stop = axienet_stop, + .ndo_start_xmit = axienet_start_xmit, + .ndo_change_mtu = axienet_change_mtu, + .ndo_set_mac_address = netdev_set_mac_address, + .ndo_validate_addr = eth_validate_addr, + .ndo_set_rx_mode = axienet_set_multicast_list, +#ifdef CONFIG_NET_POLL_CONTROLLER + .ndo_poll_controller = axienet_poll_controller, +#endif +}; + +/** + * axienet_ethtools_get_settings - Get Axi Ethernet settings related to PHY. + * @ndev: Pointer to net_device structure + * @ecmd: Pointer to ethtool_cmd structure + * + * This implements ethtool command for getting PHY settings. If PHY could + * not be found, the function returns -ENODEV. This function calls the + * relevant PHY ethtool API to get the PHY settings. + * Issue "ethtool ethX" under linux prompt to execute this function. + */ +static int axienet_ethtools_get_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phydev = lp->phy_dev; + if (!phydev) + return -ENODEV; + return phy_ethtool_gset(phydev, ecmd); +} + +/** + * axienet_ethtools_set_settings - Set PHY settings as passed in the argument. + * @ndev: Pointer to net_device structure + * @ecmd: Pointer to ethtool_cmd structure + * + * This implements ethtool command for setting various PHY settings. If PHY + * could not be found, the function returns -ENODEV. This function calls the + * relevant PHY ethtool API to set the PHY. + * Issue e.g. "ethtool -s ethX speed 1000" under linux prompt to execute this + * function. + */ +static int axienet_ethtools_set_settings(struct net_device *ndev, + struct ethtool_cmd *ecmd) +{ + struct axienet_local *lp = netdev_priv(ndev); + struct phy_device *phydev = lp->phy_dev; + if (!phydev) + return -ENODEV; + return phy_ethtool_sset(phydev, ecmd); +} + +/** + * axienet_ethtools_get_drvinfo - Get various Axi Ethernet driver information. + * @ndev: Pointer to net_device structure + * @ed: Pointer to ethtool_drvinfo structure + * + * This implements ethtool command for getting the driver information. + * Issue "ethtool -i ethX" under linux prompt to execute this function. + */ +static void axienet_ethtools_get_drvinfo(struct net_device *ndev, + struct ethtool_drvinfo *ed) +{ + memset(ed, 0, sizeof(struct ethtool_drvinfo)); + strcpy(ed->driver, DRIVER_NAME); + strcpy(ed->version, DRIVER_VERSION); + ed->regdump_len = sizeof(u32) * AXIENET_REGS_N; +} + +/** + * axienet_ethtools_get_regs_len - Get the total regs length present in the + * AxiEthernet core. + * @ndev: Pointer to net_device structure + * + * This implements ethtool command for getting the total register length + * information. + */ +static int axienet_ethtools_get_regs_len(struct net_device *ndev) +{ + return sizeof(u32) * AXIENET_REGS_N; +} + +/** + * axienet_ethtools_get_regs - Dump the contents of all registers present + * in AxiEthernet core. + * @ndev: Pointer to net_device structure + * @regs: Pointer to ethtool_regs structure + * @ret: Void pointer used to return the contents of the registers. + * + * This implements ethtool command for getting the Axi Ethernet register dump. + * Issue "ethtool -d ethX" to execute this function. + */ +static void axienet_ethtools_get_regs(struct net_device *ndev, + struct ethtool_regs *regs, void *ret) +{ + u32 *data = (u32 *) ret; + size_t len = sizeof(u32) * AXIENET_REGS_N; + struct axienet_local *lp = netdev_priv(ndev); + + regs->version = 0; + regs->len = len; + + memset(data, 0, len); + data[0] = axienet_ior(lp, XAE_RAF_OFFSET); + data[1] = axienet_ior(lp, XAE_TPF_OFFSET); + data[2] = axienet_ior(lp, XAE_IFGP_OFFSET); + data[3] = axienet_ior(lp, XAE_IS_OFFSET); + data[4] = axienet_ior(lp, XAE_IP_OFFSET); + data[5] = axienet_ior(lp, XAE_IE_OFFSET); + data[6] = axienet_ior(lp, XAE_TTAG_OFFSET); + data[7] = axienet_ior(lp, XAE_RTAG_OFFSET); + data[8] = axienet_ior(lp, XAE_UAWL_OFFSET); + data[9] = axienet_ior(lp, XAE_UAWU_OFFSET); + data[10] = axienet_ior(lp, XAE_TPID0_OFFSET); + data[11] = axienet_ior(lp, XAE_TPID1_OFFSET); + data[12] = axienet_ior(lp, XAE_PPST_OFFSET); + data[13] = axienet_ior(lp, XAE_RCW0_OFFSET); + data[14] = axienet_ior(lp, XAE_RCW1_OFFSET); + data[15] = axienet_ior(lp, XAE_TC_OFFSET); + data[16] = axienet_ior(lp, XAE_FCC_OFFSET); + data[17] = axienet_ior(lp, XAE_EMMC_OFFSET); + data[18] = axienet_ior(lp, XAE_PHYC_OFFSET); + data[19] = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + data[20] = axienet_ior(lp, XAE_MDIO_MCR_OFFSET); + data[21] = axienet_ior(lp, XAE_MDIO_MWD_OFFSET); + data[22] = axienet_ior(lp, XAE_MDIO_MRD_OFFSET); + data[23] = axienet_ior(lp, XAE_MDIO_MIS_OFFSET); + data[24] = axienet_ior(lp, XAE_MDIO_MIP_OFFSET); + data[25] = axienet_ior(lp, XAE_MDIO_MIE_OFFSET); + data[26] = axienet_ior(lp, XAE_MDIO_MIC_OFFSET); + data[27] = axienet_ior(lp, XAE_UAW0_OFFSET); + data[28] = axienet_ior(lp, XAE_UAW1_OFFSET); + data[29] = axienet_ior(lp, XAE_FMI_OFFSET); + data[30] = axienet_ior(lp, XAE_AF0_OFFSET); + data[31] = axienet_ior(lp, XAE_AF1_OFFSET); +} + +/** + * axienet_ethtools_get_pauseparam - Get the pause parameter setting for + * Tx and Rx paths. + * @ndev: Pointer to net_device structure + * @epauseparm: Pointer to ethtool_pauseparam structure. + * + * This implements ethtool command for getting axi ethernet pause frame + * setting. Issue "ethtool -a ethX" to execute this function. + */ +static void +axienet_ethtools_get_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *epauseparm) +{ + u32 regval; + struct axienet_local *lp = netdev_priv(ndev); + epauseparm->autoneg = 0; + regval = axienet_ior(lp, XAE_FCC_OFFSET); + epauseparm->tx_pause = regval & XAE_FCC_FCTX_MASK; + epauseparm->rx_pause = regval & XAE_FCC_FCRX_MASK; +} + +/** + * axienet_ethtools_set_pauseparam - Set device pause parameter(flow control) + * settings. + * @ndev: Pointer to net_device structure + * @epauseparam:Pointer to ethtool_pauseparam structure + * + * This implements ethtool command for enabling flow control on Rx and Tx + * paths. Issue "ethtool -A ethX tx on|off" under linux prompt to execute this + * function. + */ +static int +axienet_ethtools_set_pauseparam(struct net_device *ndev, + struct ethtool_pauseparam *epauseparm) +{ + u32 regval = 0; + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) { + printk(KERN_ERR "%s: Please stop netif before applying " + "configruation\n", ndev->name); + return -EFAULT; + } + + regval = axienet_ior(lp, XAE_FCC_OFFSET); + if (epauseparm->tx_pause) + regval |= XAE_FCC_FCTX_MASK; + else + regval &= ~XAE_FCC_FCTX_MASK; + if (epauseparm->rx_pause) + regval |= XAE_FCC_FCRX_MASK; + else + regval &= ~XAE_FCC_FCRX_MASK; + axienet_iow(lp, XAE_FCC_OFFSET, regval); + + return 0; +} + +/** + * axienet_ethtools_get_coalesce - Get DMA interrupt coalescing count. + * @ndev: Pointer to net_device structure + * @ecoalesce: Pointer to ethtool_coalesce structure + * + * This implements ethtool command for getting the DMA interrupt coalescing + * count on Tx and Rx paths. Issue "ethtool -c ethX" under linux prompt to + * execute this function. + */ +static int axienet_ethtools_get_coalesce(struct net_device *ndev, + struct ethtool_coalesce *ecoalesce) +{ + u32 regval = 0; + struct axienet_local *lp = netdev_priv(ndev); + regval = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + ecoalesce->rx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK) + >> XAXIDMA_COALESCE_SHIFT; + regval = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + ecoalesce->tx_max_coalesced_frames = (regval & XAXIDMA_COALESCE_MASK) + >> XAXIDMA_COALESCE_SHIFT; + return 0; +} + +/** + * axienet_ethtools_set_coalesce - Set DMA interrupt coalescing count. + * @ndev: Pointer to net_device structure + * @ecoalesce: Pointer to ethtool_coalesce structure + * + * This implements ethtool command for setting the DMA interrupt coalescing + * count on Tx and Rx paths. Issue "ethtool -C ethX rx-frames 5" under linux + * prompt to execute this function. + */ +static int axienet_ethtools_set_coalesce(struct net_device *ndev, + struct ethtool_coalesce *ecoalesce) +{ + struct axienet_local *lp = netdev_priv(ndev); + + if (netif_running(ndev)) { + printk(KERN_ERR "%s: Please stop netif before applying " + "configruation\n", ndev->name); + return -EFAULT; + } + + if ((ecoalesce->rx_coalesce_usecs) || + (ecoalesce->rx_coalesce_usecs_irq) || + (ecoalesce->rx_max_coalesced_frames_irq) || + (ecoalesce->tx_coalesce_usecs) || + (ecoalesce->tx_coalesce_usecs_irq) || + (ecoalesce->tx_max_coalesced_frames_irq) || + (ecoalesce->stats_block_coalesce_usecs) || + (ecoalesce->use_adaptive_rx_coalesce) || + (ecoalesce->use_adaptive_tx_coalesce) || + (ecoalesce->pkt_rate_low) || + (ecoalesce->rx_coalesce_usecs_low) || + (ecoalesce->rx_max_coalesced_frames_low) || + (ecoalesce->tx_coalesce_usecs_low) || + (ecoalesce->tx_max_coalesced_frames_low) || + (ecoalesce->pkt_rate_high) || + (ecoalesce->rx_coalesce_usecs_high) || + (ecoalesce->rx_max_coalesced_frames_high) || + (ecoalesce->tx_coalesce_usecs_high) || + (ecoalesce->tx_max_coalesced_frames_high) || + (ecoalesce->rate_sample_interval)) + return -EOPNOTSUPP; + if (ecoalesce->rx_max_coalesced_frames) + lp->coalesce_count_rx = ecoalesce->rx_max_coalesced_frames; + if (ecoalesce->tx_max_coalesced_frames) + lp->coalesce_count_tx = ecoalesce->tx_max_coalesced_frames; + + return 0; +} + +static struct ethtool_ops axienet_ethtool_ops = { + .get_settings = axienet_ethtools_get_settings, + .set_settings = axienet_ethtools_set_settings, + .get_drvinfo = axienet_ethtools_get_drvinfo, + .get_regs_len = axienet_ethtools_get_regs_len, + .get_regs = axienet_ethtools_get_regs, + .get_link = ethtool_op_get_link, + .get_pauseparam = axienet_ethtools_get_pauseparam, + .set_pauseparam = axienet_ethtools_set_pauseparam, + .get_coalesce = axienet_ethtools_get_coalesce, + .set_coalesce = axienet_ethtools_set_coalesce, +}; + +/** + * axienet_dma_err_handler - Tasklet handler for Axi DMA Error + * @data: Data passed + * + * Resets the Axi DMA and Axi Ethernet devices, and reconfigures the + * Tx/Rx BDs. + */ +static void axienet_dma_err_handler(unsigned long data) +{ + u32 axienet_status; + u32 cr, i; + int mdio_mcreg; + struct axienet_local *lp = (struct axienet_local *) data; + struct net_device *ndev = lp->ndev; + struct axidma_bd *cur_p; + + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + mdio_mcreg = axienet_ior(lp, XAE_MDIO_MC_OFFSET); + axienet_mdio_wait_until_ready(lp); + /* Disable the MDIO interface till Axi Ethernet Reset is completed. + * When we do an Axi Ethernet reset, it resets the complete core + * including the MDIO. So if MDIO is not disabled when the reset + * process is started, MDIO will be broken afterwards. */ + axienet_iow(lp, XAE_MDIO_MC_OFFSET, (mdio_mcreg & + ~XAE_MDIO_MC_MDIOEN_MASK)); + + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_TX_CR_OFFSET); + __axienet_device_reset(lp, &ndev->dev, XAXIDMA_RX_CR_OFFSET); + + axienet_iow(lp, XAE_MDIO_MC_OFFSET, mdio_mcreg); + axienet_mdio_wait_until_ready(lp); + + for (i = 0; i < TX_BD_NUM; i++) { + cur_p = &lp->tx_bd_v[i]; + if (cur_p->phys) + dma_unmap_single(ndev->dev.parent, cur_p->phys, + (cur_p->cntrl & + XAXIDMA_BD_CTRL_LENGTH_MASK), + DMA_TO_DEVICE); + if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff *) cur_p->app4); + cur_p->phys = 0; + cur_p->cntrl = 0; + cur_p->status = 0; + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; + cur_p->sw_id_offset = 0; + } + + for (i = 0; i < RX_BD_NUM; i++) { + cur_p = &lp->rx_bd_v[i]; + cur_p->status = 0; + cur_p->app0 = 0; + cur_p->app1 = 0; + cur_p->app2 = 0; + cur_p->app3 = 0; + cur_p->app4 = 0; + } + + lp->tx_bd_ci = 0; + lp->tx_bd_tail = 0; + lp->rx_bd_ci = 0; + + /* Start updating the Rx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = ((cr & ~XAXIDMA_COALESCE_MASK) | + (XAXIDMA_DFT_RX_THRESHOLD << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = ((cr & ~XAXIDMA_DELAY_MASK) | + (XAXIDMA_DFT_RX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Finally write to the Rx channel control register */ + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, cr); + + /* Start updating the Tx channel control register */ + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + /* Update the interrupt coalesce count */ + cr = (((cr & ~XAXIDMA_COALESCE_MASK)) | + (XAXIDMA_DFT_TX_THRESHOLD << XAXIDMA_COALESCE_SHIFT)); + /* Update the delay timer count */ + cr = (((cr & ~XAXIDMA_DELAY_MASK)) | + (XAXIDMA_DFT_TX_WAITBOUND << XAXIDMA_DELAY_SHIFT)); + /* Enable coalesce, delay timer and error interrupts */ + cr |= XAXIDMA_IRQ_ALL_MASK; + /* Finally write to the Tx channel control register */ + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, cr); + + /* Populate the tail pointer and bring the Rx Axi DMA engine out of + * halted state. This will make the Rx side ready for reception.*/ + axienet_dma_out32(lp, XAXIDMA_RX_CDESC_OFFSET, lp->rx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_RX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_RX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + axienet_dma_out32(lp, XAXIDMA_RX_TDESC_OFFSET, lp->rx_bd_p + + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + + /* Write to the RS (Run-stop) bit in the Tx channel control register. + * Tx channel is now ready to run. But only after we write to the + * tail pointer register that the Tx channel will start transmitting */ + axienet_dma_out32(lp, XAXIDMA_TX_CDESC_OFFSET, lp->tx_bd_p); + cr = axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET); + axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, + cr | XAXIDMA_CR_RUNSTOP_MASK); + + axienet_status = axienet_ior(lp, XAE_RCW1_OFFSET); + axienet_status &= ~XAE_RCW1_RX_MASK; + axienet_iow(lp, XAE_RCW1_OFFSET, axienet_status); + + axienet_status = axienet_ior(lp, XAE_IP_OFFSET); + if (axienet_status & XAE_INT_RXRJECT_MASK) + axienet_iow(lp, XAE_IS_OFFSET, XAE_INT_RXRJECT_MASK); + axienet_iow(lp, XAE_FCC_OFFSET, XAE_FCC_FCRX_MASK); + + /* Sync default options with HW but leave receiver and + * transmitter disabled.*/ + axienet_setoptions(ndev, lp->options & + ~(XAE_OPTION_TXEN | XAE_OPTION_RXEN)); + axienet_set_mac_address(ndev, NULL); + axienet_set_multicast_list(ndev); + axienet_setoptions(ndev, lp->options); +} + +/** + * axienet_of_probe - Axi Ethernet probe function. + * @op: Pointer to platform device structure. + * @match: Pointer to device id structure + * + * returns: 0, on success + * Non-zero error value on failure. + * + * This is the probe routine for Axi Ethernet driver. This is called before + * any other driver routines are invoked. It allocates and sets up the Ethernet + * device. Parses through device tree and populates fields of + * axienet_local. It registers the Ethernet device. + */ +static int __devinit axienet_of_probe(struct platform_device *op) +{ + __be32 *p; + int size, ret = 0; + struct device_node *np; + struct axienet_local *lp; + struct net_device *ndev; + const void *addr; + + ndev = alloc_etherdev(sizeof(*lp)); + if (!ndev) { + dev_err(&op->dev, "could not allocate device.\n"); + return -ENOMEM; + } + + ether_setup(ndev); + dev_set_drvdata(&op->dev, ndev); + + SET_NETDEV_DEV(ndev, &op->dev); + ndev->flags &= ~IFF_MULTICAST; /* clear multicast */ + ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST; + ndev->netdev_ops = &axienet_netdev_ops; + ndev->ethtool_ops = &axienet_ethtool_ops; + + lp = netdev_priv(ndev); + lp->ndev = ndev; + lp->dev = &op->dev; + lp->options = XAE_OPTION_DEFAULTS; + /* Map device registers */ + lp->regs = of_iomap(op->dev.of_node, 0); + if (!lp->regs) { + dev_err(&op->dev, "could not map Axi Ethernet regs.\n"); + goto nodev; + } + /* Setup checksum offload, but default to off if not specified */ + lp->features = 0; + + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,txcsum", NULL); + if (p) { + switch (be32_to_cpup(p)) { + case 1: + lp->csum_offload_on_tx_path = + XAE_FEATURE_PARTIAL_TX_CSUM; + lp->features |= XAE_FEATURE_PARTIAL_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + break; + case 2: + lp->csum_offload_on_tx_path = + XAE_FEATURE_FULL_TX_CSUM; + lp->features |= XAE_FEATURE_FULL_TX_CSUM; + /* Can checksum TCP/UDP over IPv4. */ + ndev->features |= NETIF_F_IP_CSUM; + break; + default: + lp->csum_offload_on_tx_path = XAE_NO_CSUM_OFFLOAD; + } + } + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL); + if (p) { + switch (be32_to_cpup(p)) { + case 1: + lp->csum_offload_on_rx_path = + XAE_FEATURE_PARTIAL_RX_CSUM; + lp->features |= XAE_FEATURE_PARTIAL_RX_CSUM; + break; + case 2: + lp->csum_offload_on_rx_path = + XAE_FEATURE_FULL_RX_CSUM; + lp->features |= XAE_FEATURE_FULL_RX_CSUM; + break; + default: + lp->csum_offload_on_rx_path = XAE_NO_CSUM_OFFLOAD; + } + } + /* For supporting jumbo frames, the Axi Ethernet hardware must have + * a larger Rx/Tx Memory. Typically, the size must be more than or + * equal to 16384 bytes, so that we can enable jumbo option and start + * supporting jumbo frames. Here we check for memory allocated for + * Rx/Tx in the hardware from the device-tree and accordingly set + * flags. */ + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,rxmem", NULL); + if (p) { + if ((be32_to_cpup(p)) >= 0x4000) + lp->jumbo_support = 1; + } + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,temac-type", + NULL); + if (p) + lp->temac_type = be32_to_cpup(p); + p = (__be32 *) of_get_property(op->dev.of_node, "xlnx,phy-type", NULL); + if (p) + lp->phy_type = be32_to_cpup(p); + + /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */ + np = of_parse_phandle(op->dev.of_node, "axistream-connected", 0); + if (!np) { + dev_err(&op->dev, "could not find DMA node\n"); + goto err_iounmap; + } + lp->dma_regs = of_iomap(np, 0); + if (lp->dma_regs) { + dev_dbg(&op->dev, "MEM base: %p\n", lp->dma_regs); + } else { + dev_err(&op->dev, "unable to map DMA registers\n"); + of_node_put(np); + } + lp->rx_irq = irq_of_parse_and_map(np, 1); + lp->tx_irq = irq_of_parse_and_map(np, 0); + of_node_put(np); + if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) { + dev_err(&op->dev, "could not determine irqs\n"); + ret = -ENOMEM; + goto err_iounmap_2; + } + + /* Retrieve the MAC address */ + addr = of_get_property(op->dev.of_node, "local-mac-address", &size); + if ((!addr) || (size != 6)) { + dev_err(&op->dev, "could not find MAC address\n"); + ret = -ENODEV; + goto err_iounmap_2; + } + axienet_set_mac_address(ndev, (void *) addr); + + lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; + lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD; + + lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0); + ret = axienet_mdio_setup(lp, op->dev.of_node); + if (ret) + dev_warn(&op->dev, "error registering MDIO bus\n"); + + ret = register_netdev(lp->ndev); + if (ret) { + dev_err(lp->dev, "register_netdev() error (%i)\n", ret); + goto err_iounmap_2; + } + + tasklet_init(&lp->dma_err_tasklet, axienet_dma_err_handler, + (unsigned long) lp); + tasklet_disable(&lp->dma_err_tasklet); + + return 0; + +err_iounmap_2: + if (lp->dma_regs) + iounmap(lp->dma_regs); +err_iounmap: + iounmap(lp->regs); +nodev: + free_netdev(ndev); + ndev = NULL; + return ret; +} + +static int __devexit axienet_of_remove(struct platform_device *op) +{ + struct net_device *ndev = dev_get_drvdata(&op->dev); + struct axienet_local *lp = netdev_priv(ndev); + + axienet_mdio_teardown(lp); + unregister_netdev(ndev); + + if (lp->phy_node) + of_node_put(lp->phy_node); + lp->phy_node = NULL; + + dev_set_drvdata(&op->dev, NULL); + + iounmap(lp->regs); + if (lp->dma_regs) + iounmap(lp->dma_regs); + free_netdev(ndev); + + return 0; +} + +static struct platform_driver axienet_of_driver = { + .probe = axienet_of_probe, + .remove = __devexit_p(axienet_of_remove), + .driver = { + .owner = THIS_MODULE, + .name = "xilinx_axienet", + .of_match_table = axienet_of_match, + }, +}; + +static int __init axienet_init(void) +{ + return platform_driver_register(&axienet_of_driver); +} + +static void __exit axienet_exit(void) +{ + platform_driver_unregister(&axienet_of_driver); +} + +module_init(axienet_init); +module_exit(axienet_exit); + +MODULE_DESCRIPTION("Xilinx Axi Ethernet driver"); +MODULE_AUTHOR("Xilinx"); +MODULE_LICENSE("GPL"); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c new file mode 100644 index 00000000000..d70b6e79f6c --- /dev/null +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_mdio.c @@ -0,0 +1,238 @@ +/* + * MDIO bus driver for the Xilinx Axi Ethernet device + * + * Copyright (c) 2009 Secret Lab Technologies, Ltd. + * Copyright (c) 2010 Xilinx, Inc. All rights reserved. + * Copyright (c) 2012 Daniel Borkmann, + * Copyright (c) 2012 Ariane Keller, + */ + +#include +#include +#include + +#include "xilinx_axienet.h" + +#define MAX_MDIO_FREQ 2500000 /* 2.5 MHz */ +#define DEFAULT_CLOCK_DIVISOR XAE_MDIO_DIV_DFT + +/* Wait till MDIO interface is ready to accept a new transaction.*/ +int axienet_mdio_wait_until_ready(struct axienet_local *lp) +{ + long end = jiffies + 2; + while (!(axienet_ior(lp, XAE_MDIO_MCR_OFFSET) & + XAE_MDIO_MCR_READY_MASK)) { + if (end - jiffies <= 0) { + WARN_ON(1); + return -ETIMEDOUT; + } + udelay(1); + } + return 0; +} + +/** + * axienet_mdio_read - MDIO interface read function + * @bus: Pointer to mii bus structure + * @phy_id: Address of the PHY device + * @reg: PHY register to read + * + * returns: The register contents on success, -ETIMEDOUT on a timeout + * + * Reads the contents of the requested register from the requested PHY + * address by first writing the details into MCR register. After a while + * the register MRD is read to obtain the PHY register content. + */ +static int axienet_mdio_read(struct mii_bus *bus, int phy_id, int reg) +{ + u32 rc; + int ret; + struct axienet_local *lp = bus->priv; + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + axienet_iow(lp, XAE_MDIO_MCR_OFFSET, + (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & + XAE_MDIO_MCR_PHYAD_MASK) | + ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & + XAE_MDIO_MCR_REGAD_MASK) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_READ_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + rc = axienet_ior(lp, XAE_MDIO_MRD_OFFSET) & 0x0000FFFF; + + dev_dbg(lp->dev, "axienet_mdio_read(phy_id=%i, reg=%x) == %x\n", + phy_id, reg, rc); + + return rc; +} + +/** + * axienet_mdio_write - MDIO interface write function + * @bus: Pointer to mii bus structure + * @phy_id: Address of the PHY device + * @reg: PHY register to write to + * @val: Value to be written into the register + * + * returns: 0 on success, -ETIMEDOUT on a timeout + * + * Writes the value to the requested register by first writing the value + * into MWD register. The the MCR register is then appropriately setup + * to finish the write operation. + */ +static int axienet_mdio_write(struct mii_bus *bus, int phy_id, int reg, + u16 val) +{ + int ret; + struct axienet_local *lp = bus->priv; + + dev_dbg(lp->dev, "axienet_mdio_write(phy_id=%i, reg=%x, val=%x)\n", + phy_id, reg, val); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + axienet_iow(lp, XAE_MDIO_MWD_OFFSET, (u32) val); + axienet_iow(lp, XAE_MDIO_MCR_OFFSET, + (((phy_id << XAE_MDIO_MCR_PHYAD_SHIFT) & + XAE_MDIO_MCR_PHYAD_MASK) | + ((reg << XAE_MDIO_MCR_REGAD_SHIFT) & + XAE_MDIO_MCR_REGAD_MASK) | + XAE_MDIO_MCR_INITIATE_MASK | + XAE_MDIO_MCR_OP_WRITE_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + return 0; +} + +/** + * axienet_mdio_setup - MDIO setup function + * @lp: Pointer to axienet local data structure. + * @np: Pointer to device node + * + * returns: 0 on success, -ETIMEDOUT on a timeout, -ENOMEM when + * mdiobus_alloc (to allocate memory for mii bus structure) fails. + * + * Sets up the MDIO interface by initializing the MDIO clock and enabling the + * MDIO interface in hardware. Register the MDIO interface. + **/ +int axienet_mdio_setup(struct axienet_local *lp, struct device_node *np) +{ + int ret; + u32 clk_div, host_clock; + u32 *property_p; + struct mii_bus *bus; + struct resource res; + struct device_node *np1; + + /* clk_div can be calculated by deriving it from the equation: + * fMDIO = fHOST / ((1 + clk_div) * 2) + * + * Where fMDIO <= 2500000, so we get: + * fHOST / ((1 + clk_div) * 2) <= 2500000 + * + * Then we get: + * 1 / ((1 + clk_div) * 2) <= (2500000 / fHOST) + * + * Then we get: + * 1 / (1 + clk_div) <= ((2500000 * 2) / fHOST) + * + * Then we get: + * 1 / (1 + clk_div) <= (5000000 / fHOST) + * + * So: + * (1 + clk_div) >= (fHOST / 5000000) + * + * And finally: + * clk_div >= (fHOST / 5000000) - 1 + * + * fHOST can be read from the flattened device tree as property + * "clock-frequency" from the CPU + */ + + np1 = of_find_node_by_name(NULL, "cpu"); + if (!np1) { + printk(KERN_WARNING "%s(): Could not find CPU device node.", + __func__); + printk(KERN_WARNING "Setting MDIO clock divisor to " + "default %d\n", DEFAULT_CLOCK_DIVISOR); + clk_div = DEFAULT_CLOCK_DIVISOR; + goto issue; + } + property_p = (u32 *) of_get_property(np1, "clock-frequency", NULL); + if (!property_p) { + printk(KERN_WARNING "%s(): Could not find CPU property: " + "clock-frequency.", __func__); + printk(KERN_WARNING "Setting MDIO clock divisor to " + "default %d\n", DEFAULT_CLOCK_DIVISOR); + clk_div = DEFAULT_CLOCK_DIVISOR; + goto issue; + } + + host_clock = be32_to_cpup(property_p); + clk_div = (host_clock / (MAX_MDIO_FREQ * 2)) - 1; + /* If there is any remainder from the division of + * fHOST / (MAX_MDIO_FREQ * 2), then we need to add + * 1 to the clock divisor or we will surely be above 2.5 MHz */ + if (host_clock % (MAX_MDIO_FREQ * 2)) + clk_div++; + + printk(KERN_DEBUG "%s(): Setting MDIO clock divisor to %u based " + "on %u Hz host clock.\n", __func__, clk_div, host_clock); + + of_node_put(np1); +issue: + axienet_iow(lp, XAE_MDIO_MC_OFFSET, + (((u32) clk_div) | XAE_MDIO_MC_MDIOEN_MASK)); + + ret = axienet_mdio_wait_until_ready(lp); + if (ret < 0) + return ret; + + bus = mdiobus_alloc(); + if (!bus) + return -ENOMEM; + + np1 = of_get_parent(lp->phy_node); + of_address_to_resource(np1, 0, &res); + snprintf(bus->id, MII_BUS_ID_SIZE, "%.8llx", + (unsigned long long) res.start); + + bus->priv = lp; + bus->name = "Xilinx Axi Ethernet MDIO"; + bus->read = axienet_mdio_read; + bus->write = axienet_mdio_write; + bus->parent = lp->dev; + bus->irq = lp->mdio_irqs; /* preallocated IRQ table */ + lp->mii_bus = bus; + + ret = of_mdiobus_register(bus, np1); + if (ret) { + mdiobus_free(bus); + return ret; + } + return 0; +} + +/** + * axienet_mdio_teardown - MDIO remove function + * @lp: Pointer to axienet local data structure. + * + * Unregisters the MDIO and frees any associate memory for mii bus. + */ +void axienet_mdio_teardown(struct axienet_local *lp) +{ + mdiobus_unregister(lp->mii_bus); + kfree(lp->mii_bus->irq); + mdiobus_free(lp->mii_bus); + lp->mii_bus = NULL; +} -- cgit v1.2.3-70-g09d2 From 9b28ecd66b391349d3492574500f978566195454 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 19 Jan 2012 15:37:22 +0000 Subject: net: usb: qmi_wwan: New driver for Huawei QMI based WWAN devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some WWAN LTE/3G devices based on chipsets from Qualcomm provide near standard CDC ECM interfaces in addition to the usual serial interfaces. The Huawei E392/E398 are examples of such devices. These typically cannot be fully configured using AT commands over a serial interface. It is necessary to speak the proprietary Qualcomm MSM Interface (QMI) protocol to the device to enable the ethernet proxy functionality. The devices embed the QMI protocol in CDC on the control interface, using standard CDC commands and notifications. The do not otherwise use CDC commands for the ethernet function. This driver does therefore not need access to any other aspects of the control interface than the descriptors attached to it. Another driver, cdc-wdm, will provide userspace access to the QMI protocol independently of this driver. To facilitate this, this driver avoids binding to the control interface, and uses only the associated data interface after parsing the common CDC functional descriptors on the control interface. You will want both the cdc-wdm and option drivers as companions to this driver, to have full access to all interfaces and protocols exported by the device. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 22 +++++ drivers/net/usb/Makefile | 1 + drivers/net/usb/qmi_wwan.c | 228 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/net/usb/qmi_wwan.c (limited to 'drivers') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 23357612793..4bad899fb38 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -398,6 +398,27 @@ config USB_NET_KALMIA To compile this driver as a module, choose M here: the module will be called kalmia. +config USB_NET_QMI_WWAN + tristate "QMI WWAN driver for Qualcomm MSM based 3G and LTE modems" + depends on USB_USBNET + help + Support WWAN LTE/3G devices based on Qualcomm Mobile Data Modem + (MDM) chipsets. Examples of such devices are + * Huawei E392/E398 + + This driver will only drive the ethernet part of the chips. + The devices require additional configuration to be usable. + Multiple management interfaces with linux drivers are + available: + + * option: AT commands on /dev/ttyUSBx + * cdc-wdm: Qualcomm MSM Interface (QMI) protocol on /dev/cdc-wdmx + + A modem manager with support for QMI is recommended. + + To compile this driver as a module, choose M here: the + module will be called qmi_wwan. + config USB_HSO tristate "Option USB High Speed Mobile Devices" depends on USB && RFKILL @@ -461,4 +482,5 @@ config USB_VL600 http://ubuntuforums.org/showpost.php?p=10589647&postcount=17 + endmenu diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index c203fa21f6b..a2e2d72c52a 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -29,4 +29,5 @@ obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o obj-$(CONFIG_USB_VL600) += lg-vl600.o +obj-$(CONFIG_USB_NET_QMI_WWAN) += qmi_wwan.o diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c new file mode 100644 index 00000000000..739e6de7abc --- /dev/null +++ b/drivers/net/usb/qmi_wwan.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2012 Bjørn Mork + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include + +/* The name of the CDC Device Management driver */ +#define DM_DRIVER "cdc_wdm" + +/* + * This driver supports wwan (3G/LTE/?) devices using a vendor + * specific management protocol called Qualcomm MSM Interface (QMI) - + * in addition to the more common AT commands over serial interface + * management + * + * QMI is wrapped in CDC, using CDC encapsulated commands on the + * control ("master") interface of a two-interface CDC Union + * resembling standard CDC ECM. The devices do not use the control + * interface for any other CDC messages. Most likely because the + * management protocol is used in place of the standard CDC + * notifications NOTIFY_NETWORK_CONNECTION and NOTIFY_SPEED_CHANGE + * + * Handling a protocol like QMI is out of the scope for any driver. + * It can be exported as a character device using the cdc-wdm driver, + * which will enable userspace applications ("modem managers") to + * handle it. This may be required to use the network interface + * provided by the driver. + * + * These devices may alternatively/additionally be configured using AT + * commands on any of the serial interfaces driven by the option driver + * + * This driver binds only to the data ("slave") interface to enable + * the cdc-wdm driver to bind to the control interface. It still + * parses the CDC functional descriptors on the control interface to + * a) verify that this is indeed a handled interface (CDC Union + * header lists it as slave) + * b) get MAC address and other ethernet config from the CDC Ethernet + * header + * c) enable user bind requests against the control interface, which + * is the common way to bind to CDC Ethernet Control Model type + * interfaces + * d) provide a hint to the user about which interface is the + * corresponding management interface + */ + +static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int status = -1; + struct usb_interface *control = NULL; + u8 *buf = intf->cur_altsetting->extra; + int len = intf->cur_altsetting->extralen; + struct usb_interface_descriptor *desc = &intf->cur_altsetting->desc; + struct usb_cdc_union_desc *cdc_union = NULL; + struct usb_cdc_ether_desc *cdc_ether = NULL; + u32 required = 1 << USB_CDC_HEADER_TYPE | 1 << USB_CDC_UNION_TYPE; + u32 found = 0; + + /* + * assume a data interface has no additional descriptors and + * that the control and data interface are numbered + * consecutively - this holds for the Huawei device at least + */ + if (len == 0 && desc->bInterfaceNumber > 0) { + control = usb_ifnum_to_if(dev->udev, desc->bInterfaceNumber - 1); + if (!control) + goto err; + + buf = control->cur_altsetting->extra; + len = control->cur_altsetting->extralen; + dev_dbg(&intf->dev, "guessing \"control\" => %s, \"data\" => this\n", + dev_name(&control->dev)); + } + + while (len > 3) { + struct usb_descriptor_header *h = (void *)buf; + + /* ignore any misplaced descriptors */ + if (h->bDescriptorType != USB_DT_CS_INTERFACE) + goto next_desc; + + /* buf[2] is CDC descriptor subtype */ + switch (buf[2]) { + case USB_CDC_HEADER_TYPE: + if (found & 1 << USB_CDC_HEADER_TYPE) { + dev_dbg(&intf->dev, "extra CDC header\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_header_desc)) { + dev_dbg(&intf->dev, "CDC header len %u\n", h->bLength); + goto err; + } + break; + case USB_CDC_UNION_TYPE: + if (found & 1 << USB_CDC_UNION_TYPE) { + dev_dbg(&intf->dev, "extra CDC union\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_union_desc)) { + dev_dbg(&intf->dev, "CDC union len %u\n", h->bLength); + goto err; + } + cdc_union = (struct usb_cdc_union_desc *)buf; + break; + case USB_CDC_ETHERNET_TYPE: + if (found & 1 << USB_CDC_ETHERNET_TYPE) { + dev_dbg(&intf->dev, "extra CDC ether\n"); + goto err; + } + if (h->bLength != sizeof(struct usb_cdc_ether_desc)) { + dev_dbg(&intf->dev, "CDC ether len %u\n", h->bLength); + goto err; + } + cdc_ether = (struct usb_cdc_ether_desc *)buf; + break; + } + + /* + * Remember which CDC functional descriptors we've seen. Works + * for all types we care about, of which USB_CDC_ETHERNET_TYPE + * (0x0f) is the highest numbered + */ + if (buf[2] < 32) + found |= 1 << buf[2]; + +next_desc: + len -= h->bLength; + buf += h->bLength; + } + + /* did we find all the required ones? */ + if ((found & required) != required) { + dev_err(&intf->dev, "CDC functional descriptors missing\n"); + goto err; + } + + /* give the user a helpful hint if trying to bind to the wrong interface */ + if (cdc_union && desc->bInterfaceNumber == cdc_union->bMasterInterface0) { + dev_err(&intf->dev, "leaving \"control\" interface for " DM_DRIVER " - try binding to %s instead!\n", + dev_name(&usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0)->dev)); + goto err; + } + + /* errors aren't fatal - we can live with the dynamic address */ + if (cdc_ether) { + dev->hard_mtu = le16_to_cpu(cdc_ether->wMaxSegmentSize); + usbnet_get_ethernet_addr(dev, cdc_ether->iMACAddress); + } + + /* success! point the user to the management interface */ + if (control) + dev_info(&intf->dev, "Use \"" DM_DRIVER "\" for QMI interface %s\n", + dev_name(&control->dev)); + + /* XXX: add a sysfs symlink somewhere to help management applications find it? */ + + /* collect bulk endpoints now that we know intf == "data" interface */ + status = usbnet_get_endpoints(dev, intf); + +err: + return status; +} + +/* stolen from cdc_ether.c */ +static int qmi_wwan_manage_power(struct usbnet *dev, int on) +{ + dev->intf->needs_remote_wakeup = on; + return 0; +} + +static const struct driver_info qmi_wwan_info = { + .description = "QMI speaking wwan device", + .flags = FLAG_WWAN, + .bind = qmi_wwan_bind, + .manage_power = qmi_wwan_manage_power, +}; + +#define HUAWEI_VENDOR_ID 0x12D1 + +static const struct usb_device_id products[] = { +{ + /* Huawei E392, E398 and possibly others sharing both device id and more... */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 8, /* NOTE: This is the *slave* interface of the CDC Union! */ + .driver_info = (unsigned long)&qmi_wwan_info, +}, { +}, /* END */ +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver qmi_wwan_driver = { + .name = "qmi_wwan", + .id_table = products, + .probe = usbnet_probe, + .disconnect = usbnet_disconnect, + .suspend = usbnet_suspend, + .resume = usbnet_resume, + .reset_resume = usbnet_resume, + .supports_autosuspend = 1, +}; + +static int __init qmi_wwan_init(void) +{ + return usb_register(&qmi_wwan_driver); +} +module_init(qmi_wwan_init); + +static void __exit qmi_wwan_exit(void) +{ + usb_deregister(&qmi_wwan_driver); +} +module_exit(qmi_wwan_exit); + +MODULE_AUTHOR("Bjørn Mork "); +MODULE_DESCRIPTION("Qualcomm MSM Interface (QMI) WWAN driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From fc74d8e01165b567922921d110b6d16320a61fa6 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 19 Jan 2012 10:50:06 -0800 Subject: drm/i915: Correct the bit number for the MI_FLUSH_ENABLE. Older specs claimed this was bit 11, but newer specs and the actual simulator code say it was bit 12. Regardless, we don't use MI_FLUSH, or try to enable it any more. Signed-off-by: Eric Anholt Reviewed-by: Kenneth Graunke Reviewed-by: Ben Widawsky [danvet: Anyone trying to use this bit, please read all the relevant discussions, it's epic.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c3afb783cb9..bbad7885348 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -391,7 +391,7 @@ #define MI_MODE 0x0209c # define VS_TIMER_DISPATCH (1 << 6) -# define MI_FLUSH_ENABLE (1 << 11) +# define MI_FLUSH_ENABLE (1 << 12) #define GFX_MODE 0x02520 #define GFX_MODE_GEN7 0x0229c -- cgit v1.2.3-70-g09d2 From 02b619555ad68884bacfbe41893245394cb44885 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:15:52 +0000 Subject: infiniband: Convert dst_fetch_ha() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller --- drivers/infiniband/core/addr.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/addr.c b/drivers/infiniband/core/addr.c index 1612cfd50f3..6ef660c1332 100644 --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -178,22 +178,26 @@ static void queue_req(struct addr_req *req) mutex_unlock(&lock); } -static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *addr) +static int dst_fetch_ha(struct dst_entry *dst, struct rdma_dev_addr *dev_addr, void *daddr) { struct neighbour *n; int ret; + n = dst_neigh_lookup(dst, daddr); + rcu_read_lock(); - n = dst_get_neighbour_noref(dst); if (!n || !(n->nud_state & NUD_VALID)) { if (n) neigh_event_send(n, NULL); ret = -ENODATA; } else { - ret = rdma_copy_addr(addr, dst->dev, n->ha); + ret = rdma_copy_addr(dev_addr, dst->dev, n->ha); } rcu_read_unlock(); + if (n) + neigh_release(n); + return ret; } @@ -232,7 +236,7 @@ static int addr4_resolve(struct sockaddr_in *src_in, goto put; } - ret = dst_fetch_ha(&rt->dst, addr); + ret = dst_fetch_ha(&rt->dst, addr, &fl4.daddr); put: ip_rt_put(rt); out: @@ -280,7 +284,7 @@ static int addr6_resolve(struct sockaddr_in6 *src_in, goto put; } - ret = dst_fetch_ha(dst, addr); + ret = dst_fetch_ha(dst, addr, &fl6.daddr); put: dst_release(dst); return ret; -- cgit v1.2.3-70-g09d2 From 64b7007eb99b78cbdd6cca7a98e12794201b9725 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:15:57 +0000 Subject: infiniband: cxgb4: Convert import_ep() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller Signed-off-by: Steve Wise Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 0668bb3472d..0cf61554f17 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1562,11 +1562,11 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, struct neighbour *n; int err, step; - rcu_read_lock(); - n = dst_get_neighbour_noref(dst); - err = -ENODEV; + n = dst_neigh_lookup(dst, &peer_ip); if (!n) - goto out; + return -ENODEV; + + rcu_read_lock(); err = -ENOMEM; if (n->dev->flags & IFF_LOOPBACK) { struct net_device *pdev; @@ -1614,6 +1614,8 @@ static int import_ep(struct c4iw_ep *ep, __be32 peer_ip, struct dst_entry *dst, out: rcu_read_unlock(); + neigh_release(n); + return err; } -- cgit v1.2.3-70-g09d2 From e55684fadbc5c9c69cad1b3bae228c8374b99b85 Mon Sep 17 00:00:00 2001 From: David Miller Date: Tue, 24 Jan 2012 13:16:03 +0000 Subject: infiniband: nes: Convert nes_addr_resolve_neigh() over to dst_neigh_lookup(). Now we must provide the IP destination address, and a reference has to be dropped when we're done with the entry. Signed-off-by: David S. Miller --- drivers/infiniband/hw/nes/nes_cm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 425065b36b8..fc5192ee928 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c @@ -1348,8 +1348,9 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi else netdev = nesvnic->netdev; + neigh = dst_neigh_lookup(&rt->dst, &dst_ip); + rcu_read_lock(); - neigh = dst_get_neighbour_noref(&rt->dst); if (neigh) { if (neigh->nud_state & NUD_VALID) { nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" @@ -1360,8 +1361,7 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi if (!memcmp(nesadapter->arp_table[arpindex].mac_addr, neigh->ha, ETH_ALEN)) { /* Mac address same as in nes_arp_table */ - ip_rt_put(rt); - return rc; + goto out; } nes_manage_arp_cache(nesvnic->netdev, @@ -1377,7 +1377,12 @@ static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpi neigh_event_send(neigh, NULL); } } +out: rcu_read_unlock(); + + if (neigh) + neigh_release(neigh); + ip_rt_put(rt); return rc; } -- cgit v1.2.3-70-g09d2 From 65a4a573b74f8f27e33a99c21a5a5d2fc4d82a1a Mon Sep 17 00:00:00 2001 From: Kim Phillips Date: Wed, 18 Jan 2012 18:34:34 -0600 Subject: crypto: caam - fix gcc 4.6 warning drivers/crypto/caam/ctrl.c: In function 'caam_probe': drivers/crypto/caam/ctrl.c:49:6: warning: unused variable 'd' [-Wunused-variable] Signed-off-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/ctrl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 8ae3ba2a160..c5f61c55d92 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -46,7 +46,7 @@ static int caam_remove(struct platform_device *pdev) /* Probe routine for CAAM top (controller) level */ static int caam_probe(struct platform_device *pdev) { - int d, ring, rspec; + int ring, rspec; struct device *dev; struct device_node *nprop, *np; struct caam_ctrl __iomem *ctrl; -- cgit v1.2.3-70-g09d2 From feefe73fcbb4dfc952d4185d80435fb8e053e2a7 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 3 Jan 2012 15:52:42 -0600 Subject: gpio: pxa: explicitly include mach/irqs.h In preparation to make mach/irqs.h optional and remove from asm/irq.h, directly include mach/irq.h to get MMP_GPIO_TO_IRQ and PXA_GPIO_TO_IRQ. Signed-off-by: Rob Herring --- drivers/gpio/gpio-pxa.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index b2d3ee1d183..5689ce62fd8 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c @@ -22,6 +22,8 @@ #include #include +#include + /* * We handle the GPIOs by banks, each bank covers up to 32 GPIOs with * one set of registers. The register offsets are organized below: -- cgit v1.2.3-70-g09d2 From 0f55239348aa85021d8bf8b63d84a796fcc142a4 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Tue, 17 Jan 2012 13:10:25 -0600 Subject: sh: intc: remove dependency on NR_IRQS SH intc has a compile time dependency on NR_IRQS. Make this dependency a local define so that shmobile (and ARM in general) can have run-time NR_IRQS setting. Signed-off-by: Rob Herring --- drivers/sh/intc/balancing.c | 2 +- drivers/sh/intc/core.c | 2 +- drivers/sh/intc/handle.c | 2 +- drivers/sh/intc/virq.c | 2 +- include/linux/sh_intc.h | 6 ++++++ 5 files changed, 10 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/sh/intc/balancing.c b/drivers/sh/intc/balancing.c index cec7a96f2c0..bc780807ccb 100644 --- a/drivers/sh/intc/balancing.c +++ b/drivers/sh/intc/balancing.c @@ -9,7 +9,7 @@ */ #include "internals.h" -static unsigned long dist_handle[NR_IRQS]; +static unsigned long dist_handle[INTC_NR_IRQS]; void intc_balancing_enable(unsigned int irq) { diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index e53e449b4ec..2fde8970dfd 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c @@ -42,7 +42,7 @@ unsigned int nr_intc_controllers; * - this needs to be at least 2 for 5-bit priorities on 7780 */ static unsigned int default_prio_level = 2; /* 2 - 16 */ -static unsigned int intc_prio_level[NR_IRQS]; /* for now */ +static unsigned int intc_prio_level[INTC_NR_IRQS]; /* for now */ unsigned int intc_get_dfl_prio_level(void) { diff --git a/drivers/sh/intc/handle.c b/drivers/sh/intc/handle.c index 057ce56829b..f461d5300b8 100644 --- a/drivers/sh/intc/handle.c +++ b/drivers/sh/intc/handle.c @@ -13,7 +13,7 @@ #include #include "internals.h" -static unsigned long ack_handle[NR_IRQS]; +static unsigned long ack_handle[INTC_NR_IRQS]; static intc_enum __init intc_grp_id(struct intc_desc *desc, intc_enum enum_id) diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c index c7ec49ffd9f..93cec21e788 100644 --- a/drivers/sh/intc/virq.c +++ b/drivers/sh/intc/virq.c @@ -17,7 +17,7 @@ #include #include "internals.h" -static struct intc_map_entry intc_irq_xlate[NR_IRQS]; +static struct intc_map_entry intc_irq_xlate[INTC_NR_IRQS]; struct intc_virq_list { unsigned int irq; diff --git a/include/linux/sh_intc.h b/include/linux/sh_intc.h index e1a2ac5c931..6aed0805927 100644 --- a/include/linux/sh_intc.h +++ b/include/linux/sh_intc.h @@ -3,6 +3,12 @@ #include +#ifdef CONFIG_SUPERH +#define INTC_NR_IRQS 512 +#else +#define INTC_NR_IRQS 1024 +#endif + /* * Convert back and forth between INTEVT and IRQ values. */ -- cgit v1.2.3-70-g09d2 From afd12939a09ca8f96cf8349c913dc143471c9b3c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Thu, 5 Jan 2012 00:34:05 +0000 Subject: e1000e: cleanup Rx checksum offload code 1) cleanup whitespace in e1000_rx_checksum() function header comment 2) do not check hardware checksum when Rx checksum is disabled 3) reduce duplicated calls to le16_to_cpu() by just using it within e1000_rx_checksum() instead of in each call to the function v2: use swab16 instead of le16_to_cpu & htons and corrected type for the passed-in csum Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 3911401ed65..263bf5f02eb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -487,22 +487,27 @@ static void e1000_receive_skb(struct e1000_adapter *adapter, /** * e1000_rx_checksum - Receive Checksum Offload - * @adapter: board private structure - * @status_err: receive descriptor status and error fields - * @csum: receive descriptor csum field - * @sk_buff: socket buffer with received data + * @adapter: board private structure + * @status_err: receive descriptor status and error fields + * @csum: receive descriptor csum field + * @sk_buff: socket buffer with received data **/ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, - u32 csum, struct sk_buff *skb) + __le16 csum, struct sk_buff *skb) { u16 status = (u16)status_err; u8 errors = (u8)(status_err >> 24); skb_checksum_none_assert(skb); + /* Rx checksum disabled */ + if (!(adapter->netdev->features & NETIF_F_RXCSUM)) + return; + /* Ignore Checksum bit is set */ if (status & E1000_RXD_STAT_IXSM) return; + /* TCP/UDP checksum error bit is set */ if (errors & E1000_RXD_ERR_TCPE) { /* let the stack verify checksum errors */ @@ -524,7 +529,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * Hardware complements the payload checksum, so we undo it * and then put the value in host order for further stack use. */ - __sum16 sum = (__force __sum16)htons(csum); + __sum16 sum = (__force __sum16)swab16((__force u16)csum); skb->csum = csum_unfold(~sum); skb->ip_summed = CHECKSUM_COMPLETE; } @@ -957,8 +962,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, /* Receive Checksum Offload */ e1000_rx_checksum(adapter, staterr, - le16_to_cpu(rx_desc->wb.lower.hi_dword. - csum_ip.csum), skb); + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); e1000_receive_skb(adapter, netdev, skb, staterr, rx_desc->wb.upper.vlan); @@ -1318,8 +1322,8 @@ copydone: total_rx_bytes += skb->len; total_rx_packets++; - e1000_rx_checksum(adapter, staterr, le16_to_cpu( - rx_desc->wb.lower.hi_dword.csum_ip.csum), skb); + e1000_rx_checksum(adapter, staterr, + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); if (rx_desc->wb.upper.header_status & cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) @@ -1491,8 +1495,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, /* Receive Checksum Offload XXX recompute due to CRC strip? */ e1000_rx_checksum(adapter, staterr, - le16_to_cpu(rx_desc->wb.lower.hi_dword. - csum_ip.csum), skb); + rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; -- cgit v1.2.3-70-g09d2 From 70495a500d787c0c90a136acf454cb7d0eecd82e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 11 Jan 2012 01:26:50 +0000 Subject: e1000e: add Receive Packet Steering (RPS) support Enable RPS by default. Disallow jumbo frames when both receive checksum and receive hashing are enabled because the hardware cannot do both IP payload checksum (enabled when receive checksum is enabled when using packet split which is used for jumbo frames) and provide RSS hash at the same time. v2: added ethtool command to query flow hashing behavior per Ben Hutchings and changed the type of rsskey to cleanup the setting of the register array and avoid unnecessary casts (as pointed out by Joe Perches). The long error messages are not changed since there is nothing in the kernel ./Documentation that suggests the preferred method for dealing with long messages other than to never break strings; leaving them as-is for now. Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/defines.h | 8 +++ drivers/net/ethernet/intel/e1000e/ethtool.c | 48 +++++++++++++++ drivers/net/ethernet/intel/e1000e/hw.h | 5 ++ drivers/net/ethernet/intel/e1000e/netdev.c | 90 +++++++++++++++++++++++++++-- 4 files changed, 145 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index c516a7440be..c73795f4653 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -126,6 +126,13 @@ E1000_RXDEXT_STATERR_CXE | \ E1000_RXDEXT_STATERR_RXE) +#define E1000_MRQC_RSS_FIELD_MASK 0xFFFF0000 +#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000 +#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP_EX 0x00040000 +#define E1000_MRQC_RSS_FIELD_IPV6 0x00100000 +#define E1000_MRQC_RSS_FIELD_IPV6_TCP 0x00200000 + #define E1000_RXDPS_HDRSTAT_HDRSP 0x00008000 /* Management Control */ @@ -326,6 +333,7 @@ /* Receive Checksum Control */ #define E1000_RXCSUM_TUOFL 0x00000200 /* TCP / UDP checksum offload */ #define E1000_RXCSUM_IPPCSE 0x00001000 /* IP payload checksum enable */ +#define E1000_RXCSUM_PCSD 0x00002000 /* packet checksum disabled */ /* Header split receive */ #define E1000_RFCTL_NFSW_DIS 0x00000040 diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index fb2c28e799a..0a3137a791e 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1955,6 +1955,53 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset, } } +static int e1000_get_rxnfc(struct net_device *netdev, + struct ethtool_rxnfc *info, u32 *rule_locs) +{ + info->data = 0; + + switch (info->cmd) { + case ETHTOOL_GRXFH: { + struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_hw *hw = &adapter->hw; + u32 mrqc = er32(MRQC); + + if (!(mrqc & E1000_MRQC_RSS_FIELD_MASK)) + return 0; + + switch (info->flow_type) { + case TCP_V4_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP) + info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fall through */ + case UDP_V4_FLOW: + case SCTP_V4_FLOW: + case AH_ESP_V4_FLOW: + case IPV4_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV4) + info->data |= RXH_IP_SRC | RXH_IP_DST; + break; + case TCP_V6_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP) + info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; + /* fall through */ + case UDP_V6_FLOW: + case SCTP_V6_FLOW: + case AH_ESP_V6_FLOW: + case IPV6_FLOW: + if (mrqc & E1000_MRQC_RSS_FIELD_IPV6) + info->data |= RXH_IP_SRC | RXH_IP_DST; + break; + default: + break; + } + return 0; + } + default: + return -EOPNOTSUPP; + } +} + static const struct ethtool_ops e1000_ethtool_ops = { .get_settings = e1000_get_settings, .set_settings = e1000_set_settings, @@ -1981,6 +2028,7 @@ static const struct ethtool_ops e1000_ethtool_ops = { .get_sset_count = e1000e_get_sset_count, .get_coalesce = e1000_get_coalesce, .set_coalesce = e1000_set_coalesce, + .get_rxnfc = e1000_get_rxnfc, }; void e1000e_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 29670397079..93c349ee565 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -204,6 +204,7 @@ enum e1e_registers { E1000_WUC = 0x05800, /* Wakeup Control - RW */ E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */ E1000_WUS = 0x05810, /* Wakeup Status - RO */ + E1000_MRQC = 0x05818, /* Multiple Receive Control - RW */ E1000_MANC = 0x05820, /* Management Control - RW */ E1000_FFLT = 0x05F00, /* Flexible Filter Length Table - RW Array */ E1000_HOST_IF = 0x08800, /* Host Interface */ @@ -219,6 +220,10 @@ enum e1e_registers { E1000_SWSM = 0x05B50, /* SW Semaphore */ E1000_FWSM = 0x05B54, /* FW Semaphore */ E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */ + E1000_RETA_BASE = 0x05C00, /* Redirection Table - RW */ +#define E1000_RETA(_n) (E1000_RETA_BASE + ((_n) * 4)) + E1000_RSSRK_BASE = 0x05C80, /* RSS Random Key - RW */ +#define E1000_RSSRK(_n) (E1000_RSSRK_BASE + ((_n) * 4)) E1000_FFLT_DBG = 0x05F04, /* Debug Register */ E1000_PCH_RAICC_BASE = 0x05F50, /* Receive Address Initial CRC */ #define E1000_PCH_RAICC(_n) (E1000_PCH_RAICC_BASE + ((_n) * 4)) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 263bf5f02eb..b196d79e108 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -845,6 +845,13 @@ check_page: } } +static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss, + struct sk_buff *skb) +{ + if (netdev->features & NETIF_F_RXHASH) + skb->rxhash = le32_to_cpu(rss); +} + /** * e1000_clean_rx_irq - Send received data up the network stack; legacy * @adapter: board private structure @@ -964,6 +971,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + e1000_receive_skb(adapter, netdev, skb, staterr, rx_desc->wb.upper.vlan); @@ -1325,6 +1334,8 @@ copydone: e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + if (rx_desc->wb.upper.header_status & cpu_to_le16(E1000_RXDPS_HDRSTAT_HDRSP)) adapter->rx_hdr_split++; @@ -1497,6 +1508,8 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, e1000_rx_checksum(adapter, staterr, rx_desc->wb.lower.hi_dword.csum_ip.csum, skb); + e1000_rx_hash(netdev, rx_desc->wb.lower.hi_dword.rss, skb); + /* probably a little skewed due to removing CRC */ total_rx_bytes += skb->len; total_rx_packets++; @@ -3271,6 +3284,42 @@ static void e1000e_set_rx_mode(struct net_device *netdev) e1000e_vlan_strip_disable(adapter); } +static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) +{ + struct e1000_hw *hw = &adapter->hw; + u32 mrqc, rxcsum; + int i; + static const u32 rsskey[10] = { + 0xda565a6d, 0xc20e5b25, 0x3d256741, 0xb08fa343, 0xcb2bcad0, + 0xb4307bae, 0xa32dcb77, 0x0cf23080, 0x3bb7426a, 0xfa01acbe + }; + + /* Fill out hash function seed */ + for (i = 0; i < 10; i++) + ew32(RSSRK(i), rsskey[i]); + + /* Direct all traffic to queue 0 */ + for (i = 0; i < 32; i++) + ew32(RETA(i), 0); + + /* + * Disable raw packet checksumming so that RSS hash is placed in + * descriptor on writeback. + */ + rxcsum = er32(RXCSUM); + rxcsum |= E1000_RXCSUM_PCSD; + + ew32(RXCSUM, rxcsum); + + mrqc = (E1000_MRQC_RSS_FIELD_IPV4 | + E1000_MRQC_RSS_FIELD_IPV4_TCP | + E1000_MRQC_RSS_FIELD_IPV6 | + E1000_MRQC_RSS_FIELD_IPV6_TCP | + E1000_MRQC_RSS_FIELD_IPV6_TCP_EX); + + ew32(MRQC, mrqc); +} + /** * e1000_configure - configure the hardware for Rx and Tx * @adapter: private board structure @@ -3283,6 +3332,9 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000_init_manageability_pt(adapter); e1000_configure_tx(adapter); + + if (adapter->netdev->features & NETIF_F_RXHASH) + e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), @@ -5168,10 +5220,22 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; /* Jumbo frame support */ - if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && - !(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { - e_err("Jumbo Frames not supported.\n"); - return -EINVAL; + if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) { + if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) { + e_err("Jumbo Frames not supported.\n"); + return -EINVAL; + } + + /* + * IP payload checksum (enabled with jumbos/packet-split when + * Rx checksum is enabled) and generation of RSS hash is + * mutually exclusive in the hardware. + */ + if ((netdev->features & NETIF_F_RXCSUM) && + (netdev->features & NETIF_F_RXHASH)) { + e_err("Jumbo frames cannot be enabled when both receive checksum offload and receive hashing are enabled. Disable one of the receive offload features before enabling jumbos.\n"); + return -EINVAL; + } } /* Supported frame sizes */ @@ -5934,7 +5998,7 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter) } static int e1000_set_features(struct net_device *netdev, - netdev_features_t features) + netdev_features_t features) { struct e1000_adapter *adapter = netdev_priv(netdev); netdev_features_t changed = features ^ netdev->features; @@ -5943,9 +6007,22 @@ static int e1000_set_features(struct net_device *netdev, adapter->flags |= FLAG_TSO_FORCE; if (!(changed & (NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_TX | - NETIF_F_RXCSUM))) + NETIF_F_RXCSUM | NETIF_F_RXHASH))) return 0; + /* + * IP payload checksum (enabled with jumbos/packet-split when Rx + * checksum is enabled) and generation of RSS hash is mutually + * exclusive in the hardware. + */ + if (adapter->rx_ps_pages && + (features & NETIF_F_RXCSUM) && (features & NETIF_F_RXHASH)) { + e_err("Enabling both receive checksum offload and receive hashing is not possible with jumbo frames. Disable jumbos or enable only one of the receive offload features.\n"); + return -EINVAL; + } + + netdev->features = features; + if (netif_running(netdev)) e1000e_reinit_locked(adapter); else @@ -6136,6 +6213,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, NETIF_F_HW_VLAN_TX | NETIF_F_TSO | NETIF_F_TSO6 | + NETIF_F_RXHASH | NETIF_F_RXCSUM | NETIF_F_HW_CSUM); -- cgit v1.2.3-70-g09d2 From 7ee913562fb7937595ba97f9b9adbf294b657d5b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:35 +0000 Subject: e1000e: re-enable alternate MAC address for all devices which support it Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/lib.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c index 0893ab107ad..78e3f4c0c36 100644 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ b/drivers/net/ethernet/intel/e1000e/lib.c @@ -187,11 +187,8 @@ s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) if (ret_val) goto out; - /* Check for LOM (vs. NIC) or one of two valid mezzanine cards */ - if (!((nvm_data & NVM_COMPAT_LOM) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_DUAL) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES_QUAD) || - (hw->adapter->pdev->device == E1000_DEV_ID_82571EB_SERDES))) + /* not supported on older hardware or 82573 */ + if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) goto out; ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, -- cgit v1.2.3-70-g09d2 From c5083cf6d286e4d3485eaf7904e5d60a2d9df6f5 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:40 +0000 Subject: e1000e: convert head, tail and itr_register offsets to __iomem pointers The Tx/Rx head and tail registers and itr_register are always at known addresses based on the __iomem address at which the PCI region (from BAR 0) is mapped and known offsets within the region for each of these registers. Store and use the full address rather than just the region offset to reduce unnecessary address calculations. Also, change current u8 __iomem pointers to void __iomem pointers. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 6 ++-- drivers/net/ethernet/intel/e1000e/hw.h | 4 +-- drivers/net/ethernet/intel/e1000e/netdev.c | 53 +++++++++++++++--------------- 3 files changed, 31 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index f478a22ed57..f6ac1975166 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -242,8 +242,8 @@ struct e1000_ring { u16 next_to_use; u16 next_to_clean; - u16 head; - u16 tail; + void __iomem *head; + void __iomem *tail; /* array of buffer information structs */ struct e1000_buffer *buffer_info; @@ -251,7 +251,7 @@ struct e1000_ring { char name[IFNAMSIZ + 5]; u32 ims_val; u32 itr_val; - u16 itr_register; + void __iomem *itr_register; int set_itr; struct sk_buff *rx_skb_top; diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index 93c349ee565..a15da4712f8 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -969,8 +969,8 @@ struct e1000_dev_spec_ich8lan { struct e1000_hw { struct e1000_adapter *adapter; - u8 __iomem *hw_addr; - u8 __iomem *flash_address; + void __iomem *hw_addr; + void __iomem *flash_address; struct e1000_mac_info mac; struct e1000_fc_info fc; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index b196d79e108..462bdeec90e 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -550,7 +550,7 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err, * which has bit 24 set while ME is accessing Host CSR registers, wait * if it is set and try again a number of times. **/ -static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, +static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail, unsigned int i) { unsigned int j = 0; @@ -569,10 +569,9 @@ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, u8 __iomem * tail, static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) { - u8 __iomem *tail = (adapter->hw.hw_addr + adapter->rx_ring->tail); struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, tail, i)) { + if (e1000e_update_tail_wa(hw, adapter->rx_ring->tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); @@ -582,10 +581,9 @@ static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) { - u8 __iomem *tail = (adapter->hw.hw_addr + adapter->tx_ring->tail); struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, tail, i)) { + if (e1000e_update_tail_wa(hw, adapter->tx_ring->tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); @@ -651,7 +649,7 @@ map_skb: if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + rx_ring->tail); + writel(i, rx_ring->tail); } i++; if (i == rx_ring->count) @@ -754,8 +752,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i << 1); else - writel(i << 1, - adapter->hw.hw_addr + rx_ring->tail); + writel(i << 1, rx_ring->tail); } i++; @@ -841,7 +838,7 @@ check_page: if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_rdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + rx_ring->tail); + writel(i, rx_ring->tail); } } @@ -1076,8 +1073,8 @@ static void e1000_print_hw_hang(struct work_struct *work) "PHY 1000BASE-T Status <%x>\n" "PHY Extended Status <%x>\n" "PCI Status <%x>\n", - readl(adapter->hw.hw_addr + tx_ring->head), - readl(adapter->hw.hw_addr + tx_ring->tail), + readl(tx_ring->head), + readl(tx_ring->tail), tx_ring->next_to_use, tx_ring->next_to_clean, tx_ring->buffer_info[eop].time_stamp, @@ -1617,8 +1614,8 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) rx_ring->next_to_use = 0; adapter->flags2 &= ~FLAG2_IS_DISCARDING; - writel(0, adapter->hw.hw_addr + rx_ring->head); - writel(0, adapter->hw.hw_addr + rx_ring->tail); + writel(0, rx_ring->head); + writel(0, rx_ring->tail); } static void e1000e_downshift_workaround(struct work_struct *work) @@ -1814,7 +1811,7 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data) */ if (adapter->rx_ring->set_itr) { writel(1000000000 / (adapter->rx_ring->itr_val * 256), - adapter->hw.hw_addr + adapter->rx_ring->itr_register); + adapter->rx_ring->itr_register); adapter->rx_ring->set_itr = 0; } @@ -1855,9 +1852,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) adapter->eiac_mask |= rx_ring->ims_val; if (rx_ring->itr_val) writel(1000000000 / (rx_ring->itr_val * 256), - hw->hw_addr + rx_ring->itr_register); + rx_ring->itr_register); else - writel(1, hw->hw_addr + rx_ring->itr_register); + writel(1, rx_ring->itr_register); ivar = E1000_IVAR_INT_ALLOC_VALID | vector; /* Configure Tx vector */ @@ -1865,9 +1862,9 @@ static void e1000_configure_msix(struct e1000_adapter *adapter) vector++; if (tx_ring->itr_val) writel(1000000000 / (tx_ring->itr_val * 256), - hw->hw_addr + tx_ring->itr_register); + tx_ring->itr_register); else - writel(1, hw->hw_addr + tx_ring->itr_register); + writel(1, tx_ring->itr_register); adapter->eiac_mask |= tx_ring->ims_val; ivar |= ((E1000_IVAR_INT_ALLOC_VALID | vector) << 8); @@ -1982,7 +1979,8 @@ static int e1000_request_msix(struct e1000_adapter *adapter) netdev); if (err) goto out; - adapter->rx_ring->itr_register = E1000_EITR_82574(vector); + adapter->rx_ring->itr_register = adapter->hw.hw_addr + + E1000_EITR_82574(vector); adapter->rx_ring->itr_val = adapter->itr; vector++; @@ -1997,7 +1995,8 @@ static int e1000_request_msix(struct e1000_adapter *adapter) netdev); if (err) goto out; - adapter->tx_ring->itr_register = E1000_EITR_82574(vector); + adapter->tx_ring->itr_register = adapter->hw.hw_addr + + E1000_EITR_82574(vector); adapter->tx_ring->itr_val = adapter->itr; vector++; @@ -2288,8 +2287,8 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) tx_ring->next_to_use = 0; tx_ring->next_to_clean = 0; - writel(0, adapter->hw.hw_addr + tx_ring->head); - writel(0, adapter->hw.hw_addr + tx_ring->tail); + writel(0, tx_ring->head); + writel(0, tx_ring->tail); } /** @@ -2773,8 +2772,8 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) ew32(TDLEN, tdlen); ew32(TDH, 0); ew32(TDT, 0); - tx_ring->head = E1000_TDH; - tx_ring->tail = E1000_TDT; + tx_ring->head = adapter->hw.hw_addr + E1000_TDH; + tx_ring->tail = adapter->hw.hw_addr + E1000_TDT; /* Set the default values for the Tx Inter Packet Gap timer */ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ @@ -3088,8 +3087,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) ew32(RDLEN, rdlen); ew32(RDH, 0); ew32(RDT, 0); - rx_ring->head = E1000_RDH; - rx_ring->tail = E1000_RDT; + rx_ring->head = adapter->hw.hw_addr + E1000_RDH; + rx_ring->tail = adapter->hw.hw_addr + E1000_RDT; /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = er32(RXCSUM); @@ -4914,7 +4913,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) e1000e_update_tdt_wa(adapter, i); else - writel(i, adapter->hw.hw_addr + tx_ring->tail); + writel(i, tx_ring->tail); /* * we need this if more than one processor can write to our tail -- cgit v1.2.3-70-g09d2 From 55aa69854a93d7aaf123a882b0b1f93c86cf3c7e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:45 +0000 Subject: e1000e: pass pointer to ring struct instead of adapter struct For ring-specific functions, pass a pointer to the ring struct instead of a pointer to the adapter struct. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 21 +-- drivers/net/ethernet/intel/e1000e/ethtool.c | 10 +- drivers/net/ethernet/intel/e1000e/netdev.c | 232 ++++++++++++++-------------- 3 files changed, 136 insertions(+), 127 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index f6ac1975166..db604cdd998 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -234,6 +234,7 @@ struct e1000_buffer { }; struct e1000_ring { + struct e1000_adapter *adapter; /* back pointer to adapter */ void *desc; /* pointer to ring memory */ dma_addr_t dma; /* phys address of ring */ unsigned int size; /* length of ring in bytes */ @@ -334,11 +335,10 @@ struct e1000_adapter { /* * Rx */ - bool (*clean_rx) (struct e1000_adapter *adapter, - int *work_done, int work_to_do) - ____cacheline_aligned_in_smp; - void (*alloc_rx_buf) (struct e1000_adapter *adapter, - int cleaned_count, gfp_t gfp); + bool (*clean_rx) (struct e1000_ring *ring, int *work_done, + int work_to_do) ____cacheline_aligned_in_smp; + void (*alloc_rx_buf) (struct e1000_ring *ring, int cleaned_count, + gfp_t gfp); struct e1000_ring *rx_ring; u32 rx_int_delay; @@ -398,6 +398,9 @@ struct e1000_adapter { bool idle_check; int phy_hang_count; + + u16 tx_ring_count; + u16 rx_ring_count; }; struct e1000_info { @@ -492,10 +495,10 @@ extern void e1000e_down(struct e1000_adapter *adapter); extern void e1000e_reinit_locked(struct e1000_adapter *adapter); extern void e1000e_reset(struct e1000_adapter *adapter); extern void e1000e_power_up_phy(struct e1000_adapter *adapter); -extern int e1000e_setup_rx_resources(struct e1000_adapter *adapter); -extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter); -extern void e1000e_free_rx_resources(struct e1000_adapter *adapter); -extern void e1000e_free_tx_resources(struct e1000_adapter *adapter); +extern int e1000e_setup_rx_resources(struct e1000_ring *ring); +extern int e1000e_setup_tx_resources(struct e1000_ring *ring); +extern void e1000e_free_rx_resources(struct e1000_ring *ring); +extern void e1000e_free_tx_resources(struct e1000_ring *ring); extern struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats); diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 0a3137a791e..01c73aee7fd 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -656,10 +656,10 @@ static int e1000_set_ringparam(struct net_device *netdev, if (netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ - err = e1000e_setup_rx_resources(adapter); + err = e1000e_setup_rx_resources(rx_ring); if (err) goto err_setup_rx; - err = e1000e_setup_tx_resources(adapter); + err = e1000e_setup_tx_resources(tx_ring); if (err) goto err_setup_tx; @@ -669,8 +669,8 @@ static int e1000_set_ringparam(struct net_device *netdev, */ adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; - e1000e_free_rx_resources(adapter); - e1000e_free_tx_resources(adapter); + e1000e_free_rx_resources(adapter->rx_ring); + e1000e_free_tx_resources(adapter->tx_ring); kfree(tx_old); kfree(rx_old); adapter->rx_ring = rx_ring; @@ -683,7 +683,7 @@ static int e1000_set_ringparam(struct net_device *netdev, clear_bit(__E1000_RESETTING, &adapter->state); return 0; err_setup_tx: - e1000e_free_rx_resources(adapter); + e1000e_free_rx_resources(rx_ring); err_setup_rx: adapter->rx_ring = rx_old; adapter->tx_ring = tx_old; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 462bdeec90e..ffe4583994d 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -567,11 +567,12 @@ static inline s32 e1000e_update_tail_wa(struct e1000_hw *hw, void __iomem *tail, return 0; } -static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) +static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i) { + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, adapter->rx_ring->tail, i)) { + if (e1000e_update_tail_wa(hw, rx_ring->tail, i)) { u32 rctl = er32(RCTL); ew32(RCTL, rctl & ~E1000_RCTL_EN); e_err("ME firmware caused invalid RDT - resetting\n"); @@ -579,11 +580,12 @@ static void e1000e_update_rdt_wa(struct e1000_adapter *adapter, unsigned int i) } } -static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) +static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i) { + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_hw *hw = &adapter->hw; - if (e1000e_update_tail_wa(hw, adapter->tx_ring->tail, i)) { + if (e1000e_update_tail_wa(hw, tx_ring->tail, i)) { u32 tctl = er32(TCTL); ew32(TCTL, tctl & ~E1000_TCTL_EN); e_err("ME firmware caused invalid TDT - resetting\n"); @@ -593,14 +595,14 @@ static void e1000e_update_tdt_wa(struct e1000_adapter *adapter, unsigned int i) /** * e1000_alloc_rx_buffers - Replace used receive buffers - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, +static void e1000_alloc_rx_buffers(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc; struct e1000_buffer *buffer_info; struct sk_buff *skb; @@ -647,7 +649,7 @@ map_skb: */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i); + e1000e_update_rdt_wa(rx_ring, i); else writel(i, rx_ring->tail); } @@ -662,15 +664,15 @@ map_skb: /** * e1000_alloc_rx_buffers_ps - Replace used receive buffers; packet split - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, +static void e1000_alloc_rx_buffers_ps(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union e1000_rx_desc_packet_split *rx_desc; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info; struct e1000_ps_page *ps_page; struct sk_buff *skb; @@ -750,7 +752,7 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i << 1); + e1000e_update_rdt_wa(rx_ring, i << 1); else writel(i << 1, rx_ring->tail); } @@ -767,17 +769,17 @@ no_buffers: /** * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers - * @adapter: address of board private structure + * @rx_ring: Rx descriptor ring * @cleaned_count: number of buffers to allocate this pass **/ -static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter, +static void e1000_alloc_jumbo_rx_buffers(struct e1000_ring *rx_ring, int cleaned_count, gfp_t gfp) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; union e1000_rx_desc_extended *rx_desc; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info; struct sk_buff *skb; unsigned int i; @@ -836,7 +838,7 @@ check_page: * such as IA-64). */ wmb(); if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_rdt_wa(adapter, i); + e1000e_update_rdt_wa(rx_ring, i); else writel(i, rx_ring->tail); } @@ -850,19 +852,19 @@ static inline void e1000_rx_hash(struct net_device *netdev, __le32 rss, } /** - * e1000_clean_rx_irq - Send received data up the network stack; legacy - * @adapter: board private structure + * e1000_clean_rx_irq - Send received data up the network stack + * @rx_ring: Rx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_rx_irq(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_rx_irq(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_hw *hw = &adapter->hw; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc, *next_rxd; struct e1000_buffer *buffer_info, *next_buffer; u32 length, staterr; @@ -978,7 +980,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -993,16 +995,18 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; return cleaned; } -static void e1000_put_txbuf(struct e1000_adapter *adapter, - struct e1000_buffer *buffer_info) +static void e1000_put_txbuf(struct e1000_ring *tx_ring, + struct e1000_buffer *buffer_info) { + struct e1000_adapter *adapter = tx_ring->adapter; + if (buffer_info->dma) { if (buffer_info->mapped_as_page) dma_unmap_page(&adapter->pdev->dev, buffer_info->dma, @@ -1090,16 +1094,16 @@ static void e1000_print_hw_hang(struct work_struct *work) /** * e1000_clean_tx_irq - Reclaim resources after transmit completes - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) +static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring) { + struct e1000_adapter *adapter = tx_ring->adapter; struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; - struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_tx_desc *tx_desc, *eop_desc; struct e1000_buffer *buffer_info; unsigned int i, eop; @@ -1129,7 +1133,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) } } - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); tx_desc->upper.data = 0; i++; @@ -1183,19 +1187,19 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter) /** * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ -static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_rx_irq_ps(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_hw *hw = &adapter->hw; union e1000_rx_desc_packet_split *rx_desc, *next_rxd; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; struct e1000_buffer *buffer_info, *next_buffer; struct e1000_ps_page *ps_page; struct sk_buff *skb; @@ -1346,7 +1350,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (cleaned_count >= E1000_RX_BUFFER_WRITE) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -1361,7 +1365,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1387,13 +1391,12 @@ static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb, * the return value indicates whether actual cleaning was done, there * is no guarantee that everything was cleaned **/ - -static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter, - int *work_done, int work_to_do) +static bool e1000_clean_jumbo_rx_irq(struct e1000_ring *rx_ring, int *work_done, + int work_to_do) { + struct e1000_adapter *adapter = rx_ring->adapter; struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; union e1000_rx_desc_extended *rx_desc, *next_rxd; struct e1000_buffer *buffer_info, *next_buffer; u32 length, staterr; @@ -1526,7 +1529,7 @@ next_desc: /* return some buffers to hardware, one at a time is too slow */ if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, cleaned_count, + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); cleaned_count = 0; } @@ -1541,7 +1544,7 @@ next_desc: cleaned_count = e1000_desc_unused(rx_ring); if (cleaned_count) - adapter->alloc_rx_buf(adapter, cleaned_count, GFP_ATOMIC); + adapter->alloc_rx_buf(rx_ring, cleaned_count, GFP_ATOMIC); adapter->total_rx_bytes += total_rx_bytes; adapter->total_rx_packets += total_rx_packets; @@ -1550,11 +1553,11 @@ next_desc: /** * e1000_clean_rx_ring - Free Rx Buffers per Queue - * @adapter: board private structure + * @rx_ring: Rx descriptor ring **/ -static void e1000_clean_rx_ring(struct e1000_adapter *adapter) +static void e1000_clean_rx_ring(struct e1000_ring *rx_ring) { - struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_buffer *buffer_info; struct e1000_ps_page *ps_page; struct pci_dev *pdev = adapter->pdev; @@ -1794,7 +1797,7 @@ static irqreturn_t e1000_intr_msix_tx(int irq, void *data) adapter->total_tx_bytes = 0; adapter->total_tx_packets = 0; - if (!e1000_clean_tx_irq(adapter)) + if (!e1000_clean_tx_irq(tx_ring)) /* Ring was not completely cleaned, so fire another interrupt */ ew32(ICS, tx_ring->ims_val); @@ -1805,14 +1808,15 @@ static irqreturn_t e1000_intr_msix_rx(int irq, void *data) { struct net_device *netdev = data; struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_ring *rx_ring = adapter->rx_ring; /* Write the ITR value calculated at the end of the * previous interrupt. */ - if (adapter->rx_ring->set_itr) { - writel(1000000000 / (adapter->rx_ring->itr_val * 256), - adapter->rx_ring->itr_register); - adapter->rx_ring->set_itr = 0; + if (rx_ring->set_itr) { + writel(1000000000 / (rx_ring->itr_val * 256), + rx_ring->itr_register); + rx_ring->set_itr = 0; } if (napi_schedule_prep(&adapter->napi)) { @@ -2177,13 +2181,13 @@ static int e1000_alloc_ring_dma(struct e1000_adapter *adapter, /** * e1000e_setup_tx_resources - allocate Tx resources (Descriptors) - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * Return 0 on success, negative on failure **/ -int e1000e_setup_tx_resources(struct e1000_adapter *adapter) +int e1000e_setup_tx_resources(struct e1000_ring *tx_ring) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; int err = -ENOMEM, size; size = sizeof(struct e1000_buffer) * tx_ring->count; @@ -2211,13 +2215,13 @@ err: /** * e1000e_setup_rx_resources - allocate Rx resources (Descriptors) - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * Returns 0 on success, negative on failure **/ -int e1000e_setup_rx_resources(struct e1000_adapter *adapter) +int e1000e_setup_rx_resources(struct e1000_ring *rx_ring) { - struct e1000_ring *rx_ring = adapter->rx_ring; + struct e1000_adapter *adapter = rx_ring->adapter; struct e1000_buffer *buffer_info; int i, size, desc_len, err = -ENOMEM; @@ -2264,18 +2268,18 @@ err: /** * e1000_clean_tx_ring - Free Tx Buffers - * @adapter: board private structure + * @tx_ring: Tx descriptor ring **/ -static void e1000_clean_tx_ring(struct e1000_adapter *adapter) +static void e1000_clean_tx_ring(struct e1000_ring *tx_ring) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_buffer *buffer_info; unsigned long size; unsigned int i; for (i = 0; i < tx_ring->count; i++) { buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); } netdev_reset_queue(adapter->netdev); @@ -2293,16 +2297,16 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) /** * e1000e_free_tx_resources - Free Tx Resources per Queue - * @adapter: board private structure + * @tx_ring: Tx descriptor ring * * Free all transmit software resources **/ -void e1000e_free_tx_resources(struct e1000_adapter *adapter) +void e1000e_free_tx_resources(struct e1000_ring *tx_ring) { + struct e1000_adapter *adapter = tx_ring->adapter; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *tx_ring = adapter->tx_ring; - e1000_clean_tx_ring(adapter); + e1000_clean_tx_ring(tx_ring); vfree(tx_ring->buffer_info); tx_ring->buffer_info = NULL; @@ -2314,18 +2318,17 @@ void e1000e_free_tx_resources(struct e1000_adapter *adapter) /** * e1000e_free_rx_resources - Free Rx Resources - * @adapter: board private structure + * @rx_ring: Rx descriptor ring * * Free all receive software resources **/ - -void e1000e_free_rx_resources(struct e1000_adapter *adapter) +void e1000e_free_rx_resources(struct e1000_ring *rx_ring) { + struct e1000_adapter *adapter = rx_ring->adapter; struct pci_dev *pdev = adapter->pdev; - struct e1000_ring *rx_ring = adapter->rx_ring; int i; - e1000_clean_rx_ring(adapter); + e1000_clean_rx_ring(rx_ring); for (i = 0; i < rx_ring->count; i++) kfree(rx_ring->buffer_info[i].ps_pages); @@ -2479,13 +2482,19 @@ set_itr_now: **/ static int __devinit e1000_alloc_queues(struct e1000_adapter *adapter) { - adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + int size = sizeof(struct e1000_ring); + + adapter->tx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->tx_ring) goto err; + adapter->tx_ring->count = adapter->tx_ring_count; + adapter->tx_ring->adapter = adapter; - adapter->rx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL); + adapter->rx_ring = kzalloc(size, GFP_KERNEL); if (!adapter->rx_ring) goto err; + adapter->rx_ring->count = adapter->rx_ring_count; + adapter->rx_ring->adapter = adapter; return 0; err: @@ -2513,10 +2522,10 @@ static int e1000_clean(struct napi_struct *napi, int budget) !(adapter->rx_ring->ims_val & adapter->tx_ring->ims_val)) goto clean_rx; - tx_cleaned = e1000_clean_tx_irq(adapter); + tx_cleaned = e1000_clean_tx_irq(adapter->tx_ring); clean_rx: - adapter->clean_rx(adapter, &work_done, budget); + adapter->clean_rx(adapter->rx_ring, &work_done, budget); if (!tx_cleaned) work_done = budget; @@ -3325,6 +3334,8 @@ static void e1000e_setup_rss_hash(struct e1000_adapter *adapter) **/ static void e1000_configure(struct e1000_adapter *adapter) { + struct e1000_ring *rx_ring = adapter->rx_ring; + e1000e_set_rx_mode(adapter->netdev); e1000_restore_vlan(adapter); @@ -3336,8 +3347,7 @@ static void e1000_configure(struct e1000_adapter *adapter) e1000e_setup_rss_hash(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring), - GFP_KERNEL); + adapter->alloc_rx_buf(rx_ring, e1000_desc_unused(rx_ring), GFP_KERNEL); } /** @@ -3647,8 +3657,8 @@ void e1000e_down(struct e1000_adapter *adapter) spin_unlock(&adapter->stats64_lock); e1000e_flush_descriptors(adapter); - e1000_clean_tx_ring(adapter); - e1000_clean_rx_ring(adapter); + e1000_clean_tx_ring(adapter->tx_ring); + e1000_clean_rx_ring(adapter->rx_ring); adapter->link_speed = 0; adapter->link_duplex = 0; @@ -3688,6 +3698,8 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter) adapter->rx_ps_bsize0 = 128; adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN; adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN; + adapter->tx_ring_count = E1000_DEFAULT_TXD; + adapter->rx_ring_count = E1000_DEFAULT_RXD; spin_lock_init(&adapter->stats64_lock); @@ -3846,12 +3858,12 @@ static int e1000_open(struct net_device *netdev) netif_carrier_off(netdev); /* allocate transmit descriptors */ - err = e1000e_setup_tx_resources(adapter); + err = e1000e_setup_tx_resources(adapter->tx_ring); if (err) goto err_setup_tx; /* allocate receive descriptors */ - err = e1000e_setup_rx_resources(adapter); + err = e1000e_setup_rx_resources(adapter->rx_ring); if (err) goto err_setup_rx; @@ -3927,9 +3939,9 @@ static int e1000_open(struct net_device *netdev) err_req_irq: e1000e_release_hw_control(adapter); e1000_power_down_phy(adapter); - e1000e_free_rx_resources(adapter); + e1000e_free_rx_resources(adapter->rx_ring); err_setup_rx: - e1000e_free_tx_resources(adapter); + e1000e_free_tx_resources(adapter->tx_ring); err_setup_tx: e1000e_reset(adapter); pm_runtime_put_sync(&pdev->dev); @@ -3965,8 +3977,8 @@ static int e1000_close(struct net_device *netdev) } e1000_power_down_phy(adapter); - e1000e_free_tx_resources(adapter); - e1000e_free_rx_resources(adapter); + e1000e_free_tx_resources(adapter->tx_ring); + e1000e_free_rx_resources(adapter->rx_ring); /* * kill manageability vlan ID if supported, but not if a vlan with @@ -4623,10 +4635,8 @@ link_up: #define E1000_TX_FLAGS_VLAN_MASK 0xffff0000 #define E1000_TX_FLAGS_VLAN_SHIFT 16 -static int e1000_tso(struct e1000_adapter *adapter, - struct sk_buff *skb) +static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb) { - struct e1000_ring *tx_ring = adapter->tx_ring; struct e1000_context_desc *context_desc; struct e1000_buffer *buffer_info; unsigned int i; @@ -4695,9 +4705,9 @@ static int e1000_tso(struct e1000_adapter *adapter, return 1; } -static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) +static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_context_desc *context_desc; struct e1000_buffer *buffer_info; unsigned int i; @@ -4758,12 +4768,11 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) #define E1000_MAX_PER_TXD 8192 #define E1000_MAX_TXD_PWR 12 -static int e1000_tx_map(struct e1000_adapter *adapter, - struct sk_buff *skb, unsigned int first, - unsigned int max_per_txd, unsigned int nr_frags, - unsigned int mss) +static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb, + unsigned int first, unsigned int max_per_txd, + unsigned int nr_frags, unsigned int mss) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct pci_dev *pdev = adapter->pdev; struct e1000_buffer *buffer_info; unsigned int len = skb_headlen(skb); @@ -4849,16 +4858,15 @@ dma_error: i += tx_ring->count; i--; buffer_info = &tx_ring->buffer_info[i]; - e1000_put_txbuf(adapter, buffer_info); + e1000_put_txbuf(tx_ring, buffer_info); } return 0; } -static void e1000_tx_queue(struct e1000_adapter *adapter, - int tx_flags, int count) +static void e1000_tx_queue(struct e1000_ring *tx_ring, int tx_flags, int count) { - struct e1000_ring *tx_ring = adapter->tx_ring; + struct e1000_adapter *adapter = tx_ring->adapter; struct e1000_tx_desc *tx_desc = NULL; struct e1000_buffer *buffer_info; u32 txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; @@ -4911,7 +4919,7 @@ static void e1000_tx_queue(struct e1000_adapter *adapter, tx_ring->next_to_use = i; if (adapter->flags2 & FLAG2_PCIM2PCI_ARBITER_WA) - e1000e_update_tdt_wa(adapter, i); + e1000e_update_tdt_wa(tx_ring, i); else writel(i, tx_ring->tail); @@ -4961,11 +4969,11 @@ static int e1000_transfer_dhcp_info(struct e1000_adapter *adapter, return 0; } -static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) +static int __e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) { - struct e1000_adapter *adapter = netdev_priv(netdev); + struct e1000_adapter *adapter = tx_ring->adapter; - netif_stop_queue(netdev); + netif_stop_queue(adapter->netdev); /* * Herbert's original patch had: * smp_mb__after_netif_stop_queue(); @@ -4977,22 +4985,20 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size) * We need to check again in a case another CPU has just * made room available. */ - if (e1000_desc_unused(adapter->tx_ring) < size) + if (e1000_desc_unused(tx_ring) < size) return -EBUSY; /* A reprieve! */ - netif_start_queue(netdev); + netif_start_queue(adapter->netdev); ++adapter->restart_queue; return 0; } -static int e1000_maybe_stop_tx(struct net_device *netdev, int size) +static int e1000_maybe_stop_tx(struct e1000_ring *tx_ring, int size) { - struct e1000_adapter *adapter = netdev_priv(netdev); - - if (e1000_desc_unused(adapter->tx_ring) >= size) + if (e1000_desc_unused(tx_ring) >= size) return 0; - return __e1000_maybe_stop_tx(netdev, size); + return __e1000_maybe_stop_tx(tx_ring, size); } #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 ) @@ -5078,7 +5084,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, * need: count + 2 desc gap to keep tail from touching * head, otherwise try next time */ - if (e1000_maybe_stop_tx(netdev, count + 2)) + if (e1000_maybe_stop_tx(tx_ring, count + 2)) return NETDEV_TX_BUSY; if (vlan_tx_tag_present(skb)) { @@ -5088,7 +5094,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, first = tx_ring->next_to_use; - tso = e1000_tso(adapter, skb); + tso = e1000_tso(tx_ring, skb); if (tso < 0) { dev_kfree_skb_any(skb); return NETDEV_TX_OK; @@ -5096,7 +5102,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, if (tso) tx_flags |= E1000_TX_FLAGS_TSO; - else if (e1000_tx_csum(adapter, skb)) + else if (e1000_tx_csum(tx_ring, skb)) tx_flags |= E1000_TX_FLAGS_CSUM; /* @@ -5108,12 +5114,12 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb, tx_flags |= E1000_TX_FLAGS_IPV4; /* if count is 0 then mapping error has occurred */ - count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss); + count = e1000_tx_map(tx_ring, skb, first, max_per_txd, nr_frags, mss); if (count) { netdev_sent_queue(netdev, skb->len); - e1000_tx_queue(adapter, tx_flags, count); + e1000_tx_queue(tx_ring, tx_flags, count); /* Make sure there is space in the ring for the next send. */ - e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2); + e1000_maybe_stop_tx(tx_ring, MAX_SKB_FRAGS + 2); } else { dev_kfree_skb_any(skb); -- cgit v1.2.3-70-g09d2 From 508da4264add2eb13bd4d32bb896e79e6f8821fc Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:51 +0000 Subject: e1000e: re-factor ethtool get/set ring parameter Make it more like how igb does it, with some additional error checking. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 136 ++++++++++++++++------------ 1 file changed, 77 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 01c73aee7fd..ffb6c14cbbb 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -605,94 +605,112 @@ static void e1000_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_ring *tx_ring = adapter->tx_ring; - struct e1000_ring *rx_ring = adapter->rx_ring; ring->rx_max_pending = E1000_MAX_RXD; ring->tx_max_pending = E1000_MAX_TXD; - ring->rx_pending = rx_ring->count; - ring->tx_pending = tx_ring->count; + ring->rx_pending = adapter->rx_ring_count; + ring->tx_pending = adapter->tx_ring_count; } static int e1000_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct e1000_adapter *adapter = netdev_priv(netdev); - struct e1000_ring *tx_ring, *tx_old; - struct e1000_ring *rx_ring, *rx_old; - int err; + struct e1000_ring *temp_tx = NULL, *temp_rx = NULL; + int err = 0, size = sizeof(struct e1000_ring); + bool set_tx = false, set_rx = false; + u16 new_rx_count, new_tx_count; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; - while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) - usleep_range(1000, 2000); + new_rx_count = clamp_t(u32, ring->rx_pending, E1000_MIN_RXD, + E1000_MAX_RXD); + new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE); - if (netif_running(adapter->netdev)) - e1000e_down(adapter); + new_tx_count = clamp_t(u32, ring->tx_pending, E1000_MIN_TXD, + E1000_MAX_TXD); + new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE); - tx_old = adapter->tx_ring; - rx_old = adapter->rx_ring; + if ((new_tx_count == adapter->tx_ring_count) && + (new_rx_count == adapter->rx_ring_count)) + /* nothing to do */ + return 0; - err = -ENOMEM; - tx_ring = kmemdup(tx_old, sizeof(struct e1000_ring), GFP_KERNEL); - if (!tx_ring) - goto err_alloc_tx; + while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) + usleep_range(1000, 2000); - rx_ring = kmemdup(rx_old, sizeof(struct e1000_ring), GFP_KERNEL); - if (!rx_ring) - goto err_alloc_rx; + if (!netif_running(adapter->netdev)) { + /* Set counts now and allocate resources during open() */ + adapter->tx_ring->count = new_tx_count; + adapter->rx_ring->count = new_rx_count; + adapter->tx_ring_count = new_tx_count; + adapter->rx_ring_count = new_rx_count; + goto clear_reset; + } - adapter->tx_ring = tx_ring; - adapter->rx_ring = rx_ring; + set_tx = (new_tx_count != adapter->tx_ring_count); + set_rx = (new_rx_count != adapter->rx_ring_count); - rx_ring->count = max(ring->rx_pending, (u32)E1000_MIN_RXD); - rx_ring->count = min(rx_ring->count, (u32)(E1000_MAX_RXD)); - rx_ring->count = ALIGN(rx_ring->count, REQ_RX_DESCRIPTOR_MULTIPLE); + /* Allocate temporary storage for ring updates */ + if (set_tx) { + temp_tx = vmalloc(size); + if (!temp_tx) { + err = -ENOMEM; + goto free_temp; + } + } + if (set_rx) { + temp_rx = vmalloc(size); + if (!temp_rx) { + err = -ENOMEM; + goto free_temp; + } + } - tx_ring->count = max(ring->tx_pending, (u32)E1000_MIN_TXD); - tx_ring->count = min(tx_ring->count, (u32)(E1000_MAX_TXD)); - tx_ring->count = ALIGN(tx_ring->count, REQ_TX_DESCRIPTOR_MULTIPLE); + e1000e_down(adapter); - if (netif_running(adapter->netdev)) { - /* Try to get new resources before deleting old */ - err = e1000e_setup_rx_resources(rx_ring); + /* + * We can't just free everything and then setup again, because the + * ISRs in MSI-X mode get passed pointers to the Tx and Rx ring + * structs. First, attempt to allocate new resources... + */ + if (set_tx) { + memcpy(temp_tx, adapter->tx_ring, size); + temp_tx->count = new_tx_count; + err = e1000e_setup_tx_resources(temp_tx); if (err) - goto err_setup_rx; - err = e1000e_setup_tx_resources(tx_ring); + goto err_setup; + } + if (set_rx) { + memcpy(temp_rx, adapter->rx_ring, size); + temp_rx->count = new_rx_count; + err = e1000e_setup_rx_resources(temp_rx); if (err) - goto err_setup_tx; + goto err_setup_rx; + } - /* - * restore the old in order to free it, - * then add in the new - */ - adapter->rx_ring = rx_old; - adapter->tx_ring = tx_old; - e1000e_free_rx_resources(adapter->rx_ring); + /* ...then free the old resources and copy back any new ring data */ + if (set_tx) { e1000e_free_tx_resources(adapter->tx_ring); - kfree(tx_old); - kfree(rx_old); - adapter->rx_ring = rx_ring; - adapter->tx_ring = tx_ring; - err = e1000e_up(adapter); - if (err) - goto err_setup; + memcpy(adapter->tx_ring, temp_tx, size); + adapter->tx_ring_count = new_tx_count; + } + if (set_rx) { + e1000e_free_rx_resources(adapter->rx_ring); + memcpy(adapter->rx_ring, temp_rx, size); + adapter->rx_ring_count = new_rx_count; } - clear_bit(__E1000_RESETTING, &adapter->state); - return 0; -err_setup_tx: - e1000e_free_rx_resources(rx_ring); err_setup_rx: - adapter->rx_ring = rx_old; - adapter->tx_ring = tx_old; - kfree(rx_ring); -err_alloc_rx: - kfree(tx_ring); -err_alloc_tx: - e1000e_up(adapter); + if (err && set_tx) + e1000e_free_tx_resources(temp_tx); err_setup: + e1000e_up(adapter); +free_temp: + vfree(temp_tx); + vfree(temp_rx); +clear_reset: clear_bit(__E1000_RESETTING, &adapter->state); return err; } -- cgit v1.2.3-70-g09d2 From b6fbca2af36530ef307069cff0fe3b1f387c00a9 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:45:56 +0000 Subject: e1000e: default IntMode based on kernel config & available hardware support Based on a patch from Prabhakar Kushwaha , set appropriate default interrupt mode dependent on whether CONFIG_PCI_MSI is enabled in the kernel configuration and if the hardware supports MSI-X. Set the module parameter log message accordingly. Signed-off-by: Bruce Allan Cc: Jin Qing Cc: Prabhakar Kushwaha Cc: Jin Qing Cc: Kumar Gala Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/param.c | 48 ++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 20e93b08e7f..40664f5bfbd 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -113,11 +113,20 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); #define MAX_ITR 100000 #define MIN_ITR 100 -/* IntMode (Interrupt Mode) +/* + * IntMode (Interrupt Mode) + * + * Valid Range: varies depending on kernel configuration & hardware support + * + * legacy=0, MSI=1, MSI-X=2 * - * Valid Range: 0 - 2 + * When MSI/MSI-X support is enabled in kernel- + * Default Value: 2 (MSI-X) when supported by hardware, 1 (MSI) otherwise + * When MSI/MSI-X support is not enabled in kernel- + * Default Value: 0 (legacy) * - * Default Value: 2 (MSI-X) + * When a mode is specified that is not allowed/supported, it will be + * demoted to the most advanced interrupt mode available. */ E1000_PARAM(IntMode, "Interrupt Mode"); #define MAX_INTMODE 2 @@ -388,12 +397,33 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) static struct e1000_option opt = { .type = range_option, .name = "Interrupt Mode", - .err = "defaulting to 2 (MSI-X)", - .def = E1000E_INT_MODE_MSIX, - .arg = { .r = { .min = MIN_INTMODE, - .max = MAX_INTMODE } } +#ifndef CONFIG_PCI_MSI + .err = "defaulting to 0 (legacy)", + .def = E1000E_INT_MODE_LEGACY, + .arg = { .r = { .min = 0, + .max = 0 } } +#endif }; +#ifdef CONFIG_PCI_MSI + if (adapter->flags & FLAG_HAS_MSIX) { + opt.err = kstrdup("defaulting to 2 (MSI-X)", + GFP_KERNEL); + opt.def = E1000E_INT_MODE_MSIX; + opt.arg.r.max = E1000E_INT_MODE_MSIX; + } else { + opt.err = kstrdup("defaulting to 1 (MSI)", GFP_KERNEL); + opt.def = E1000E_INT_MODE_MSI; + opt.arg.r.max = E1000E_INT_MODE_MSI; + } + + if (!opt.err) { + dev_err(&adapter->pdev->dev, + "Failed to allocate memory\n"); + return; + } +#endif + if (num_IntMode > bd) { unsigned int int_mode = IntMode[bd]; e1000_validate_option(&int_mode, &opt, adapter); @@ -401,6 +431,10 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter) } else { adapter->int_mode = opt.def; } + +#ifdef CONFIG_PCI_MSI + kfree(opt.err); +#endif } { /* Smart Power Down */ static const struct e1000_option opt = { -- cgit v1.2.3-70-g09d2 From 56032be77c7eab50e2020247ffa35ca61850503f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:01 +0000 Subject: e1000e: always set transmit descriptor control registers the same The hardware erratum workaround where the TXDCTL register must be the same setting for both queues should always be done. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index ffe4583994d..6081dee5ce4 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2817,9 +2817,9 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) */ txdctl |= E1000_TXDCTL_DMA_BURST_ENABLE; ew32(TXDCTL(0), txdctl); - /* erratum work around: set txdctl the same for both queues */ - ew32(TXDCTL(1), txdctl); } + /* erratum work around: set txdctl the same for both queues */ + ew32(TXDCTL(1), er32(TXDCTL(0))); /* Program the Transmit Control Register */ tctl = er32(TCTL); -- cgit v1.2.3-70-g09d2 From 4d24136c8ea03ecfdb6b8256571da8b520b92d8b Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:06 +0000 Subject: e1000e: 82579: workaround for link drop issue When connected to certain switches, the 82579 PHY might drop link unexpectedly. Work around the issue by setting the Mean Square Error higher than the hardware default. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e2a80a283fd..1b69c2d6b41 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -145,6 +145,8 @@ #define I82579_EMI_ADDR 0x10 #define I82579_EMI_DATA 0x11 #define I82579_LPI_UPDATE_TIMER 0x4805 /* in 40ns units + 40 ns base value */ +#define I82579_MSE_THRESHOLD 0x084F /* Mean Square Error Threshold */ +#define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ /* Strapping Option Register - RO */ #define E1000_STRAP 0x0000C @@ -1669,6 +1671,26 @@ static s32 e1000_lv_phy_workarounds_ich8lan(struct e1000_hw *hw) /* Set MDIO slow mode before any other MDIO access */ ret_val = e1000_set_mdio_slow_mode_hv(hw); + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + goto out; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_THRESHOLD); + if (ret_val) + goto release; + /* set MSE higher to enable link to stay up when noise is high */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0034); + if (ret_val) + goto release; + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_ADDR, + I82579_MSE_LINK_DOWN); + if (ret_val) + goto release; + /* drop link after 5 times MSE threshold was reached */ + ret_val = hw->phy.ops.write_reg_locked(hw, I82579_EMI_DATA, 0x0005); +release: + hw->phy.ops.release(hw); + out: return ret_val; } -- cgit v1.2.3-70-g09d2 From 6a92f732f557401ca8cc0b16f8e8914c133cf6c6 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:12 +0000 Subject: e1000e: use default settings for Tx Inter Packet Gap timer Use the default hardware values for TIPG except for 80003es2lan(*). The code that is removed in this patch is either unnecessarily writing the TIPG register with the hardware default values for some devices (82571/2/3/4) or writing the wrong value for others (ICH/PCH LOMs). The only change in functionality is setting the correct default TIPG for the latter devices. (*) The correct value for 80003es2lan is already set properly in e1000_init_hw_80003es2lan() and e1000_cfg_kmrn_{10_100|1000}_80003es2lan(), and the unused flag FLAG_TIPG_MEDIUM_FOR_80003ESLAN is removed. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 3 +-- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 15 +-------------- 3 files changed, 3 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index e1159e54334..b3a235c8ed8 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -1502,8 +1502,7 @@ const struct e1000_info e1000_es2_info = { | FLAG_RX_NEEDS_RESTART /* errata */ | FLAG_TARC_SET_BIT_ZERO /* errata */ | FLAG_APME_CHECK_PORT_B - | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ - | FLAG_TIPG_MEDIUM_FOR_80003ESLAN, + | FLAG_DISABLE_FC_PAUSE_TIME, /* errata */ .flags2 = FLAG2_DMA_BURST, .pba = 38, .max_hw_frame_size = DEFAULT_JUMBO, diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index db604cdd998..4b3a27670a6 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -430,7 +430,7 @@ struct e1000_info { #define FLAG_HAS_SMART_POWER_DOWN (1 << 11) #define FLAG_IS_QUAD_PORT_A (1 << 12) #define FLAG_IS_QUAD_PORT (1 << 13) -#define FLAG_TIPG_MEDIUM_FOR_80003ESLAN (1 << 14) +/* reserved bit14 */ #define FLAG_APME_IN_WUC (1 << 15) #define FLAG_APME_IN_CTRL3 (1 << 16) #define FLAG_APME_CHECK_PORT_B (1 << 17) diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 6081dee5ce4..fb299905b1f 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2770,8 +2770,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_ring *tx_ring = adapter->tx_ring; u64 tdba; - u32 tdlen, tctl, tipg, tarc; - u32 ipgr1, ipgr2; + u32 tdlen, tctl, tarc; /* Setup the HW Tx Head and Tail descriptor pointers */ tdba = tx_ring->dma; @@ -2784,18 +2783,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) tx_ring->head = adapter->hw.hw_addr + E1000_TDH; tx_ring->tail = adapter->hw.hw_addr + E1000_TDT; - /* Set the default values for the Tx Inter Packet Gap timer */ - tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ - ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ - ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ - - if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) - ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ - - tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; - ew32(TIPG, tipg); - /* Set the Tx Interrupt Delay register */ ew32(TIDV, adapter->tx_int_delay); /* Tx irq moderation */ -- cgit v1.2.3-70-g09d2 From c550b121854eb1300148da1c2c8df6ed0dabdc66 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:17 +0000 Subject: e1000e: use hardware default values for Transmit Control register This code snippet is simply writing default values to the register which is unnecessary since the values are programmed into the register by default. There is a special case for 80003es2lan needing the Retransmit on Late Collision bit set but that is also done in e1000_init_hw_80003es2lan(). Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index fb299905b1f..89af6c02623 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2770,7 +2770,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) struct e1000_hw *hw = &adapter->hw; struct e1000_ring *tx_ring = adapter->tx_ring; u64 tdba; - u32 tdlen, tctl, tarc; + u32 tdlen, tarc; /* Setup the HW Tx Head and Tail descriptor pointers */ tdba = tx_ring->dma; @@ -2808,12 +2808,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* erratum work around: set txdctl the same for both queues */ ew32(TXDCTL(1), er32(TXDCTL(0))); - /* Program the Transmit Control Register */ - tctl = er32(TCTL); - tctl &= ~E1000_TCTL_CT; - tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | - (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); - if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { tarc = er32(TARC(0)); /* @@ -2845,8 +2839,6 @@ static void e1000_configure_tx(struct e1000_adapter *adapter) /* enable Report Status bit */ adapter->txd_cmd |= E1000_TXD_CMD_RS; - ew32(TCTL, tctl); - e1000e_config_collision_dist(hw); } -- cgit v1.2.3-70-g09d2 From d6cb17d5f8015717f6963d24d52b06292a4cb40a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:22 +0000 Subject: e1000e: 82574/82583 Tx hang workaround On 82574/82583, there is a hardware bug which might cause a Tx hang when the internal buffer is full. Setting this bit enables a hardware fix to work around the issue. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/82571.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index a3e65fd26e0..0609ac69bb3 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1227,6 +1227,10 @@ static void e1000_initialize_hw_bits_82571(struct e1000_hw *hw) case e1000_82572: reg |= (1 << 23) | (1 << 24) | (1 << 25) | (1 << 26); break; + case e1000_82574: + case e1000_82583: + reg |= (1 << 26); + break; default: break; } -- cgit v1.2.3-70-g09d2 From b93f9cf14e714c20ce9a544ed1a6070ee7604588 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 25 Jan 2012 15:39:34 -0800 Subject: drm/i915: argument to control retiring behavior Sometimes it may be the case when we idle the gpu or wait on something we don't actually want to process the retiring list. This patch allows callers to choose the behavior. Reviewed-by: Keith Packard Reviewed-by: Eugeni Dodonov Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 5 +++-- drivers/gpu/drm/i915/i915_gem.c | 28 ++++++++++++++++------------ drivers/gpu/drm/i915/i915_gem_evict.c | 2 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 2 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- drivers/gpu/drm/i915/intel_overlay.c | 6 ++++-- 7 files changed, 27 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8122738db91..3f27173fb51 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2131,7 +2131,7 @@ int i915_driver_unload(struct drm_device *dev) unregister_shrinker(&dev_priv->mm.inactive_shrinker); mutex_lock(&dev->struct_mutex); - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) DRM_ERROR("failed to idle hardware: %d\n", ret); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f02a5f525f0..1d10b8c26c9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1179,13 +1179,14 @@ void i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long mappable_end, unsigned long end); -int __must_check i915_gpu_idle(struct drm_device *dev); +int __must_check i915_gpu_idle(struct drm_device *dev, bool do_retire); int __must_check i915_gem_idle(struct drm_device *dev); int __must_check i915_add_request(struct intel_ring_buffer *ring, struct drm_file *file, struct drm_i915_gem_request *request); int __must_check i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno); + uint32_t seqno, + bool do_retire); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int __must_check i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eb98a7f55cf..ff3066c4c76 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1943,7 +1943,8 @@ i915_gem_retire_work_handler(struct work_struct *work) */ int i915_wait_request(struct intel_ring_buffer *ring, - uint32_t seqno) + uint32_t seqno, + bool do_retire) { drm_i915_private_t *dev_priv = ring->dev->dev_private; u32 ier; @@ -2027,7 +2028,7 @@ i915_wait_request(struct intel_ring_buffer *ring, * buffer to have made it to the inactive list, and we would need * a separate wait queue to handle that. */ - if (ret == 0) + if (ret == 0 && do_retire) i915_gem_retire_requests_ring(ring); return ret; @@ -2051,7 +2052,8 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj) * it. */ if (obj->active) { - ret = i915_wait_request(obj->ring, obj->last_rendering_seqno); + ret = i915_wait_request(obj->ring, obj->last_rendering_seqno, + true); if (ret) return ret; } @@ -2172,7 +2174,7 @@ i915_gem_flush_ring(struct intel_ring_buffer *ring, return 0; } -static int i915_ring_idle(struct intel_ring_buffer *ring) +static int i915_ring_idle(struct intel_ring_buffer *ring, bool do_retire) { int ret; @@ -2186,18 +2188,18 @@ static int i915_ring_idle(struct intel_ring_buffer *ring) return ret; } - return i915_wait_request(ring, i915_gem_next_request_seqno(ring)); + return i915_wait_request(ring, i915_gem_next_request_seqno(ring), + do_retire); } -int -i915_gpu_idle(struct drm_device *dev) +int i915_gpu_idle(struct drm_device *dev, bool do_retire) { drm_i915_private_t *dev_priv = dev->dev_private; int ret, i; /* Flush everything onto the inactive list. */ for (i = 0; i < I915_NUM_RINGS; i++) { - ret = i915_ring_idle(&dev_priv->ring[i]); + ret = i915_ring_idle(&dev_priv->ring[i], do_retire); if (ret) return ret; } @@ -2400,7 +2402,8 @@ i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, if (!ring_passed_seqno(obj->last_fenced_ring, obj->last_fenced_seqno)) { ret = i915_wait_request(obj->last_fenced_ring, - obj->last_fenced_seqno); + obj->last_fenced_seqno, + true); if (ret) return ret; } @@ -2541,7 +2544,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, if (!ring_passed_seqno(obj->last_fenced_ring, reg->setup_seqno)) { ret = i915_wait_request(obj->last_fenced_ring, - reg->setup_seqno); + reg->setup_seqno, + true); if (ret) return ret; } @@ -3710,7 +3714,7 @@ i915_gem_idle(struct drm_device *dev) return 0; } - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) { mutex_unlock(&dev->struct_mutex); return ret; @@ -4201,7 +4205,7 @@ rescan: * This has a dramatic impact to reduce the number of * OOM-killer events whilst running the GPU aggressively. */ - if (i915_gpu_idle(dev) == 0) + if (i915_gpu_idle(dev, true) == 0) goto rescan; } mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index ead5d00f91b..097119caa36 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -195,7 +195,7 @@ i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) trace_i915_gem_evict_everything(dev, purgeable_only); /* Flush everything (on to the inactive lists) and evict */ - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c01cb201849..c649e0f255b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -1186,7 +1186,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, * so every billion or so execbuffers, we need to stall * the GPU in order to reset the counters. */ - ret = i915_gpu_idle(dev); + ret = i915_gpu_idle(dev, true); if (ret) goto err; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 6042c5e6d27..e050b903da9 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -55,7 +55,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev)) { + if (i915_gpu_idle(dev_priv->dev, true)) { DRM_ERROR("Couldn't idle GPU\n"); /* Wait a bit, in hopes it avoids the hang */ udelay(10); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index cdf17d4cc1f..23a543cdfa9 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -227,7 +227,8 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, } overlay->last_flip_req = request->seqno; overlay->flip_tail = tail; - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); + ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, + true); if (ret) return ret; @@ -448,7 +449,8 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay) if (overlay->last_flip_req == 0) return 0; - ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req); + ret = i915_wait_request(LP_RING(dev_priv), overlay->last_flip_req, + true); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 8436473a4b10243fd4c3009b97b6646c2ba642f7 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Tue, 24 Jan 2012 20:36:15 -0800 Subject: drm/i915: drm/i915: Fix recursive calls to unmap After the ILK vt-d workaround patches it became clear that we had introduced a bug. Chris Wilson tracked down the issue to recursive calls to unmap. This happens because we try to optimize waiting on requests by calling retire requests after the wait, which may drop the last reference on an object and end up freeing the object (and then unmap the object from the gtt). After the last patch we can now choose to defer processing the retire list. Kudos to Chris Wilson for tracking this one down. This patch fixes gem_unref_active_buffers from i-g-t. It was tested by forcing do_idle_maps to true. This also fixes tests/gem_linear_blits in intel-gpu-tools. Reported-by: guang.a.yang@intel.com Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42180 Reviewed-by: Keith Packard Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index e050b903da9..11bddd5a5a6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -55,7 +55,7 @@ static bool do_idling(struct drm_i915_private *dev_priv) if (unlikely(dev_priv->mm.gtt->do_idle_maps)) { dev_priv->mm.interruptible = false; - if (i915_gpu_idle(dev_priv->dev, true)) { + if (i915_gpu_idle(dev_priv->dev, false)) { DRM_ERROR("Couldn't idle GPU\n"); /* Wait a bit, in hopes it avoids the hang */ udelay(10); -- cgit v1.2.3-70-g09d2 From 6dc0e816bb7478fd4dfebddcc65257f9ef161f7a Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Mon, 23 Jan 2012 15:30:02 -0800 Subject: drm/i915: correct lock type in destroy This is only relevant when using module unloading, and really only helps get rid of a probably benign warning. I can't remember if I sent this out already, but it's not turning up in any of my searches. Signed-off-by: Ben Widawsky Reviewed-by: Keith Packard Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5d433fc11ac..275ab6fecbd 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1017,11 +1017,12 @@ void i915_destroy_error_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_error_state *error; + unsigned long flags; - spin_lock(&dev_priv->error_lock); + spin_lock_irqsave(&dev_priv->error_lock, flags); error = dev_priv->first_error; dev_priv->first_error = NULL; - spin_unlock(&dev_priv->error_lock); + spin_unlock_irqrestore(&dev_priv->error_lock, flags); if (error) i915_error_state_free(dev, error); -- cgit v1.2.3-70-g09d2 From d53e54b4d43b2559c5a424188894fd63d145b5d7 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Wed, 16 Nov 2011 17:36:37 +0200 Subject: ARM: IOMMU: Tegra20: Add iommu_ops for GART driver Tegra 20 IOMMU H/W, GART (Graphics Address Relocation Table). This patch implements struct iommu_ops for GART for the upper IOMMU API. This H/W module supports only single virtual address space(domain), and manages a single level 1-to-1 mapping H/W translation page table. [With small fixes by Joerg Roedel] Signed-off-by: Hiroshi DOYU Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/tegra-gart.c | 451 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 462 insertions(+) create mode 100644 drivers/iommu/tegra-gart.c (limited to 'drivers') diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 6bea6962f8e..76c86da2b41 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -142,4 +142,14 @@ config OMAP_IOMMU_DEBUG Say N unless you know you need this. +config TEGRA_IOMMU_GART + bool "Tegra GART IOMMU Support" + depends on ARCH_TEGRA_2x_SOC + select IOMMU_API + help + Enables support for remapping discontiguous physical memory + shared with the operating system into contiguous I/O virtual + space through the GART (Graphics Address Relocation Table) + hardware included on Tegra SoCs. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 0e36b4934af..3238a31d260 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -8,3 +8,4 @@ obj-$(CONFIG_IRQ_REMAP) += intr_remapping.o obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o +obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o diff --git a/drivers/iommu/tegra-gart.c b/drivers/iommu/tegra-gart.c new file mode 100644 index 00000000000..b21598fc262 --- /dev/null +++ b/drivers/iommu/tegra-gart.c @@ -0,0 +1,451 @@ +/* + * IOMMU API for GART in Tegra20 + * + * Copyright (c) 2010-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define pr_fmt(fmt) "%s(): " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* bitmap of the page sizes currently supported */ +#define GART_IOMMU_PGSIZES (SZ_4K) + +#define GART_CONFIG 0x24 +#define GART_ENTRY_ADDR 0x28 +#define GART_ENTRY_DATA 0x2c +#define GART_ENTRY_PHYS_ADDR_VALID (1 << 31) + +#define GART_PAGE_SHIFT 12 +#define GART_PAGE_SIZE (1 << GART_PAGE_SHIFT) +#define GART_PAGE_MASK \ + (~(GART_PAGE_SIZE - 1) & ~GART_ENTRY_PHYS_ADDR_VALID) + +struct gart_client { + struct device *dev; + struct list_head list; +}; + +struct gart_device { + void __iomem *regs; + u32 *savedata; + u32 page_count; /* total remappable size */ + dma_addr_t iovmm_base; /* offset to vmm_area */ + spinlock_t pte_lock; /* for pagetable */ + struct list_head client; + spinlock_t client_lock; /* for client list */ + struct device *dev; +}; + +static struct gart_device *gart_handle; /* unique for a system */ + +#define GART_PTE(_pfn) \ + (GART_ENTRY_PHYS_ADDR_VALID | ((_pfn) << PAGE_SHIFT)) + +/* + * Any interaction between any block on PPSB and a block on APB or AHB + * must have these read-back to ensure the APB/AHB bus transaction is + * complete before initiating activity on the PPSB block. + */ +#define FLUSH_GART_REGS(gart) ((void)readl((gart)->regs + GART_CONFIG)) + +#define for_each_gart_pte(gart, iova) \ + for (iova = gart->iovmm_base; \ + iova < gart->iovmm_base + GART_PAGE_SIZE * gart->page_count; \ + iova += GART_PAGE_SIZE) + +static inline void gart_set_pte(struct gart_device *gart, + unsigned long offs, u32 pte) +{ + writel(offs, gart->regs + GART_ENTRY_ADDR); + writel(pte, gart->regs + GART_ENTRY_DATA); + + dev_dbg(gart->dev, "%s %08lx:%08x\n", + pte ? "map" : "unmap", offs, pte & GART_PAGE_MASK); +} + +static inline unsigned long gart_read_pte(struct gart_device *gart, + unsigned long offs) +{ + unsigned long pte; + + writel(offs, gart->regs + GART_ENTRY_ADDR); + pte = readl(gart->regs + GART_ENTRY_DATA); + + return pte; +} + +static void do_gart_setup(struct gart_device *gart, const u32 *data) +{ + unsigned long iova; + + for_each_gart_pte(gart, iova) + gart_set_pte(gart, iova, data ? *(data++) : 0); + + writel(1, gart->regs + GART_CONFIG); + FLUSH_GART_REGS(gart); +} + +#ifdef DEBUG +static void gart_dump_table(struct gart_device *gart) +{ + unsigned long iova; + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + for_each_gart_pte(gart, iova) { + unsigned long pte; + + pte = gart_read_pte(gart, iova); + + dev_dbg(gart->dev, "%s %08lx:%08lx\n", + (GART_ENTRY_PHYS_ADDR_VALID & pte) ? "v" : " ", + iova, pte & GART_PAGE_MASK); + } + spin_unlock_irqrestore(&gart->pte_lock, flags); +} +#else +static inline void gart_dump_table(struct gart_device *gart) +{ +} +#endif + +static inline bool gart_iova_range_valid(struct gart_device *gart, + unsigned long iova, size_t bytes) +{ + unsigned long iova_start, iova_end, gart_start, gart_end; + + iova_start = iova; + iova_end = iova_start + bytes - 1; + gart_start = gart->iovmm_base; + gart_end = gart_start + gart->page_count * GART_PAGE_SIZE - 1; + + if (iova_start < gart_start) + return false; + if (iova_end > gart_end) + return false; + return true; +} + +static int gart_iommu_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct gart_device *gart; + struct gart_client *client, *c; + int err = 0; + + gart = dev_get_drvdata(dev->parent); + if (!gart) + return -EINVAL; + domain->priv = gart; + + client = devm_kzalloc(gart->dev, sizeof(*c), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->dev = dev; + + spin_lock(&gart->client_lock); + list_for_each_entry(c, &gart->client, list) { + if (c->dev == dev) { + dev_err(gart->dev, + "%s is already attached\n", dev_name(dev)); + err = -EINVAL; + goto fail; + } + } + list_add(&client->list, &gart->client); + spin_unlock(&gart->client_lock); + dev_dbg(gart->dev, "Attached %s\n", dev_name(dev)); + return 0; + +fail: + devm_kfree(gart->dev, client); + spin_unlock(&gart->client_lock); + return err; +} + +static void gart_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct gart_device *gart = domain->priv; + struct gart_client *c; + + spin_lock(&gart->client_lock); + + list_for_each_entry(c, &gart->client, list) { + if (c->dev == dev) { + list_del(&c->list); + devm_kfree(gart->dev, c); + dev_dbg(gart->dev, "Detached %s\n", dev_name(dev)); + goto out; + } + } + dev_err(gart->dev, "Couldn't find\n"); +out: + spin_unlock(&gart->client_lock); +} + +static int gart_iommu_domain_init(struct iommu_domain *domain) +{ + return 0; +} + +static void gart_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct gart_device *gart = domain->priv; + + if (!gart) + return; + + spin_lock(&gart->client_lock); + if (!list_empty(&gart->client)) { + struct gart_client *c; + + list_for_each_entry(c, &gart->client, list) + gart_iommu_detach_dev(domain, c->dev); + } + spin_unlock(&gart->client_lock); + domain->priv = NULL; +} + +static int gart_iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t pa, size_t bytes, int prot) +{ + struct gart_device *gart = domain->priv; + unsigned long flags; + unsigned long pfn; + + if (!gart_iova_range_valid(gart, iova, bytes)) + return -EINVAL; + + spin_lock_irqsave(&gart->pte_lock, flags); + pfn = __phys_to_pfn(pa); + if (!pfn_valid(pfn)) { + dev_err(gart->dev, "Invalid page: %08x\n", pa); + spin_lock_irqsave(&gart->pte_lock, flags); + return -EINVAL; + } + gart_set_pte(gart, iova, GART_PTE(pfn)); + FLUSH_GART_REGS(gart); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static size_t gart_iommu_unmap(struct iommu_domain *domain, unsigned long iova, + size_t bytes) +{ + struct gart_device *gart = domain->priv; + unsigned long flags; + + if (!gart_iova_range_valid(gart, iova, bytes)) + return 0; + + spin_lock_irqsave(&gart->pte_lock, flags); + gart_set_pte(gart, iova, 0); + FLUSH_GART_REGS(gart); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static phys_addr_t gart_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + struct gart_device *gart = domain->priv; + unsigned long pte; + phys_addr_t pa; + unsigned long flags; + + if (!gart_iova_range_valid(gart, iova, 0)) + return -EINVAL; + + spin_lock_irqsave(&gart->pte_lock, flags); + pte = gart_read_pte(gart, iova); + spin_unlock_irqrestore(&gart->pte_lock, flags); + + pa = (pte & GART_PAGE_MASK); + if (!pfn_valid(__phys_to_pfn(pa))) { + dev_err(gart->dev, "No entry for %08lx:%08x\n", iova, pa); + gart_dump_table(gart); + return -EINVAL; + } + return pa; +} + +static int gart_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static struct iommu_ops gart_iommu_ops = { + .domain_init = gart_iommu_domain_init, + .domain_destroy = gart_iommu_domain_destroy, + .attach_dev = gart_iommu_attach_dev, + .detach_dev = gart_iommu_detach_dev, + .map = gart_iommu_map, + .unmap = gart_iommu_unmap, + .iova_to_phys = gart_iommu_iova_to_phys, + .domain_has_cap = gart_iommu_domain_has_cap, + .pgsize_bitmap = GART_IOMMU_PGSIZES, +}; + +static int tegra_gart_suspend(struct device *dev) +{ + struct gart_device *gart = dev_get_drvdata(dev); + unsigned long iova; + u32 *data = gart->savedata; + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + for_each_gart_pte(gart, iova) + *(data++) = gart_read_pte(gart, iova); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static int tegra_gart_resume(struct device *dev) +{ + struct gart_device *gart = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&gart->pte_lock, flags); + do_gart_setup(gart, gart->savedata); + spin_unlock_irqrestore(&gart->pte_lock, flags); + return 0; +} + +static int tegra_gart_probe(struct platform_device *pdev) +{ + struct gart_device *gart; + struct resource *res, *res_remap; + void __iomem *gart_regs; + int err; + struct device *dev = &pdev->dev; + + if (gart_handle) + return -EIO; + + BUILD_BUG_ON(PAGE_SHIFT != GART_PAGE_SHIFT); + + /* the GART memory aperture is required */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res_remap = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res || !res_remap) { + dev_err(dev, "GART memory aperture expected\n"); + return -ENXIO; + } + + gart = devm_kzalloc(dev, sizeof(*gart), GFP_KERNEL); + if (!gart) { + dev_err(dev, "failed to allocate gart_device\n"); + return -ENOMEM; + } + + gart_regs = devm_ioremap(dev, res->start, resource_size(res)); + if (!gart_regs) { + dev_err(dev, "failed to remap GART registers\n"); + err = -ENXIO; + goto fail; + } + + gart->dev = &pdev->dev; + spin_lock_init(&gart->pte_lock); + spin_lock_init(&gart->client_lock); + INIT_LIST_HEAD(&gart->client); + gart->regs = gart_regs; + gart->iovmm_base = (dma_addr_t)res_remap->start; + gart->page_count = (resource_size(res_remap) >> GART_PAGE_SHIFT); + + gart->savedata = vmalloc(sizeof(u32) * gart->page_count); + if (!gart->savedata) { + dev_err(dev, "failed to allocate context save area\n"); + err = -ENOMEM; + goto fail; + } + + platform_set_drvdata(pdev, gart); + do_gart_setup(gart, NULL); + + gart_handle = gart; + return 0; + +fail: + if (gart_regs) + devm_iounmap(dev, gart_regs); + if (gart && gart->savedata) + vfree(gart->savedata); + devm_kfree(dev, gart); + return err; +} + +static int tegra_gart_remove(struct platform_device *pdev) +{ + struct gart_device *gart = platform_get_drvdata(pdev); + struct device *dev = gart->dev; + + writel(0, gart->regs + GART_CONFIG); + if (gart->savedata) + vfree(gart->savedata); + if (gart->regs) + devm_iounmap(dev, gart->regs); + devm_kfree(dev, gart); + gart_handle = NULL; + return 0; +} + +const struct dev_pm_ops tegra_gart_pm_ops = { + .suspend = tegra_gart_suspend, + .resume = tegra_gart_resume, +}; + +static struct platform_driver tegra_gart_driver = { + .probe = tegra_gart_probe, + .remove = tegra_gart_remove, + .driver = { + .owner = THIS_MODULE, + .name = "tegra-gart", + .pm = &tegra_gart_pm_ops, + }, +}; + +static int __devinit tegra_gart_init(void) +{ + bus_set_iommu(&platform_bus_type, &gart_iommu_ops); + return platform_driver_register(&tegra_gart_driver); +} + +static void __exit tegra_gart_exit(void) +{ + platform_driver_unregister(&tegra_gart_driver); +} + +subsys_initcall(tegra_gart_init); +module_exit(tegra_gart_exit); + +MODULE_DESCRIPTION("IOMMU API for GART in Tegra20"); +MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 7a31f6f48bb6e37b3195fcecd69d30740f6b0036 Mon Sep 17 00:00:00 2001 From: Hiroshi DOYU Date: Thu, 17 Nov 2011 07:31:31 +0200 Subject: ARM: IOMMU: Tegra30: Add iommu_ops for SMMU driver Tegra 30 IOMMU H/W, SMMU (System Memory Management Unit). This patch implements struct iommu_ops for SMMU for the upper IOMMU API. This H/W module supports multiple virtual address spaces(domain x4), and manages 2 level H/W translation pagetable. Signed-off-by: Hiroshi DOYU Signed-off-by: Joerg Roedel --- arch/arm/mach-tegra/include/mach/smmu.h | 63 ++ drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 1 + drivers/iommu/tegra-smmu.c | 1034 +++++++++++++++++++++++++++++++ 4 files changed, 1108 insertions(+) create mode 100644 arch/arm/mach-tegra/include/mach/smmu.h create mode 100644 drivers/iommu/tegra-smmu.c (limited to 'drivers') diff --git a/arch/arm/mach-tegra/include/mach/smmu.h b/arch/arm/mach-tegra/include/mach/smmu.h new file mode 100644 index 00000000000..dad403a9cf0 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/smmu.h @@ -0,0 +1,63 @@ +/* + * IOMMU API for SMMU in Tegra30 + * + * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MACH_SMMU_H +#define MACH_SMMU_H + +enum smmu_hwgrp { + HWGRP_AFI, + HWGRP_AVPC, + HWGRP_DC, + HWGRP_DCB, + HWGRP_EPP, + HWGRP_G2, + HWGRP_HC, + HWGRP_HDA, + HWGRP_ISP, + HWGRP_MPE, + HWGRP_NV, + HWGRP_NV2, + HWGRP_PPCS, + HWGRP_SATA, + HWGRP_VDE, + HWGRP_VI, + + HWGRP_COUNT, + + HWGRP_END = ~0, +}; + +#define HWG_AFI (1 << HWGRP_AFI) +#define HWG_AVPC (1 << HWGRP_AVPC) +#define HWG_DC (1 << HWGRP_DC) +#define HWG_DCB (1 << HWGRP_DCB) +#define HWG_EPP (1 << HWGRP_EPP) +#define HWG_G2 (1 << HWGRP_G2) +#define HWG_HC (1 << HWGRP_HC) +#define HWG_HDA (1 << HWGRP_HDA) +#define HWG_ISP (1 << HWGRP_ISP) +#define HWG_MPE (1 << HWGRP_MPE) +#define HWG_NV (1 << HWGRP_NV) +#define HWG_NV2 (1 << HWGRP_NV2) +#define HWG_PPCS (1 << HWGRP_PPCS) +#define HWG_SATA (1 << HWGRP_SATA) +#define HWG_VDE (1 << HWGRP_VDE) +#define HWG_VI (1 << HWGRP_VI) + +#endif /* MACH_SMMU_H */ diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 76c86da2b41..3bd9fff5c58 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -152,4 +152,14 @@ config TEGRA_IOMMU_GART space through the GART (Graphics Address Relocation Table) hardware included on Tegra SoCs. +config TEGRA_IOMMU_SMMU + bool "Tegra SMMU IOMMU Support" + depends on ARCH_TEGRA_3x_SOC + select IOMMU_API + help + Enables support for remapping discontiguous physical memory + shared with the operating system into contiguous I/O virtual + space through the SMMU (System Memory Management Unit) + hardware included on Tegra SoCs. + endif # IOMMU_SUPPORT diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 3238a31d260..7ad7a3bc124 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o obj-$(CONFIG_OMAP_IOMMU_DEBUG) += omap-iommu-debug.o obj-$(CONFIG_TEGRA_IOMMU_GART) += tegra-gart.o +obj-$(CONFIG_TEGRA_IOMMU_SMMU) += tegra-smmu.o diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c new file mode 100644 index 00000000000..eb93c821f59 --- /dev/null +++ b/drivers/iommu/tegra-smmu.c @@ -0,0 +1,1034 @@ +/* + * IOMMU API for SMMU in Tegra30 + * + * Copyright (c) 2011-2012, NVIDIA CORPORATION. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define pr_fmt(fmt) "%s(): " fmt, __func__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +/* bitmap of the page sizes currently supported */ +#define SMMU_IOMMU_PGSIZES (SZ_4K) + +#define SMMU_CONFIG 0x10 +#define SMMU_CONFIG_DISABLE 0 +#define SMMU_CONFIG_ENABLE 1 + +#define SMMU_TLB_CONFIG 0x14 +#define SMMU_TLB_CONFIG_STATS__MASK (1 << 31) +#define SMMU_TLB_CONFIG_STATS__ENABLE (1 << 31) +#define SMMU_TLB_CONFIG_HIT_UNDER_MISS__ENABLE (1 << 29) +#define SMMU_TLB_CONFIG_ACTIVE_LINES__VALUE 0x10 +#define SMMU_TLB_CONFIG_RESET_VAL 0x20000010 + +#define SMMU_PTC_CONFIG 0x18 +#define SMMU_PTC_CONFIG_STATS__MASK (1 << 31) +#define SMMU_PTC_CONFIG_STATS__ENABLE (1 << 31) +#define SMMU_PTC_CONFIG_CACHE__ENABLE (1 << 29) +#define SMMU_PTC_CONFIG_INDEX_MAP__PATTERN 0x3f +#define SMMU_PTC_CONFIG_RESET_VAL 0x2000003f + +#define SMMU_PTB_ASID 0x1c +#define SMMU_PTB_ASID_CURRENT_SHIFT 0 + +#define SMMU_PTB_DATA 0x20 +#define SMMU_PTB_DATA_RESET_VAL 0 +#define SMMU_PTB_DATA_ASID_NONSECURE_SHIFT 29 +#define SMMU_PTB_DATA_ASID_WRITABLE_SHIFT 30 +#define SMMU_PTB_DATA_ASID_READABLE_SHIFT 31 + +#define SMMU_TLB_FLUSH 0x30 +#define SMMU_TLB_FLUSH_VA_MATCH_ALL 0 +#define SMMU_TLB_FLUSH_VA_MATCH_SECTION 2 +#define SMMU_TLB_FLUSH_VA_MATCH_GROUP 3 +#define SMMU_TLB_FLUSH_ASID_SHIFT 29 +#define SMMU_TLB_FLUSH_ASID_MATCH_DISABLE 0 +#define SMMU_TLB_FLUSH_ASID_MATCH_ENABLE 1 +#define SMMU_TLB_FLUSH_ASID_MATCH_SHIFT 31 + +#define SMMU_PTC_FLUSH 0x34 +#define SMMU_PTC_FLUSH_TYPE_ALL 0 +#define SMMU_PTC_FLUSH_TYPE_ADR 1 +#define SMMU_PTC_FLUSH_ADR_SHIFT 4 + +#define SMMU_ASID_SECURITY 0x38 + +#define SMMU_STATS_TLB_HIT_COUNT 0x1f0 +#define SMMU_STATS_TLB_MISS_COUNT 0x1f4 +#define SMMU_STATS_PTC_HIT_COUNT 0x1f8 +#define SMMU_STATS_PTC_MISS_COUNT 0x1fc + +#define SMMU_TRANSLATION_ENABLE_0 0x228 +#define SMMU_TRANSLATION_ENABLE_1 0x22c +#define SMMU_TRANSLATION_ENABLE_2 0x230 + +#define SMMU_AFI_ASID 0x238 /* PCIE */ +#define SMMU_AVPC_ASID 0x23c /* AVP */ +#define SMMU_DC_ASID 0x240 /* Display controller */ +#define SMMU_DCB_ASID 0x244 /* Display controller B */ +#define SMMU_EPP_ASID 0x248 /* Encoder pre-processor */ +#define SMMU_G2_ASID 0x24c /* 2D engine */ +#define SMMU_HC_ASID 0x250 /* Host1x */ +#define SMMU_HDA_ASID 0x254 /* High-def audio */ +#define SMMU_ISP_ASID 0x258 /* Image signal processor */ +#define SMMU_MPE_ASID 0x264 /* MPEG encoder */ +#define SMMU_NV_ASID 0x268 /* (3D) */ +#define SMMU_NV2_ASID 0x26c /* (3D) */ +#define SMMU_PPCS_ASID 0x270 /* AHB */ +#define SMMU_SATA_ASID 0x278 /* SATA */ +#define SMMU_VDE_ASID 0x27c /* Video decoder */ +#define SMMU_VI_ASID 0x280 /* Video input */ + +#define SMMU_PDE_NEXT_SHIFT 28 + +/* AHB Arbiter Registers */ +#define AHB_XBAR_CTRL 0xe0 +#define AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE 1 +#define AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT 17 + +#define SMMU_NUM_ASIDS 4 +#define SMMU_TLB_FLUSH_VA_SECTION__MASK 0xffc00000 +#define SMMU_TLB_FLUSH_VA_SECTION__SHIFT 12 /* right shift */ +#define SMMU_TLB_FLUSH_VA_GROUP__MASK 0xffffc000 +#define SMMU_TLB_FLUSH_VA_GROUP__SHIFT 12 /* right shift */ +#define SMMU_TLB_FLUSH_VA(iova, which) \ + ((((iova) & SMMU_TLB_FLUSH_VA_##which##__MASK) >> \ + SMMU_TLB_FLUSH_VA_##which##__SHIFT) | \ + SMMU_TLB_FLUSH_VA_MATCH_##which) +#define SMMU_PTB_ASID_CUR(n) \ + ((n) << SMMU_PTB_ASID_CURRENT_SHIFT) +#define SMMU_TLB_FLUSH_ASID_MATCH_disable \ + (SMMU_TLB_FLUSH_ASID_MATCH_DISABLE << \ + SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) +#define SMMU_TLB_FLUSH_ASID_MATCH__ENABLE \ + (SMMU_TLB_FLUSH_ASID_MATCH_ENABLE << \ + SMMU_TLB_FLUSH_ASID_MATCH_SHIFT) + +#define SMMU_PAGE_SHIFT 12 +#define SMMU_PAGE_SIZE (1 << SMMU_PAGE_SHIFT) + +#define SMMU_PDIR_COUNT 1024 +#define SMMU_PDIR_SIZE (sizeof(unsigned long) * SMMU_PDIR_COUNT) +#define SMMU_PTBL_COUNT 1024 +#define SMMU_PTBL_SIZE (sizeof(unsigned long) * SMMU_PTBL_COUNT) +#define SMMU_PDIR_SHIFT 12 +#define SMMU_PDE_SHIFT 12 +#define SMMU_PTE_SHIFT 12 +#define SMMU_PFN_MASK 0x000fffff + +#define SMMU_ADDR_TO_PFN(addr) ((addr) >> 12) +#define SMMU_ADDR_TO_PDN(addr) ((addr) >> 22) +#define SMMU_PDN_TO_ADDR(addr) ((pdn) << 22) + +#define _READABLE (1 << SMMU_PTB_DATA_ASID_READABLE_SHIFT) +#define _WRITABLE (1 << SMMU_PTB_DATA_ASID_WRITABLE_SHIFT) +#define _NONSECURE (1 << SMMU_PTB_DATA_ASID_NONSECURE_SHIFT) +#define _PDE_NEXT (1 << SMMU_PDE_NEXT_SHIFT) +#define _MASK_ATTR (_READABLE | _WRITABLE | _NONSECURE) + +#define _PDIR_ATTR (_READABLE | _WRITABLE | _NONSECURE) + +#define _PDE_ATTR (_READABLE | _WRITABLE | _NONSECURE) +#define _PDE_ATTR_N (_PDE_ATTR | _PDE_NEXT) +#define _PDE_VACANT(pdn) (((pdn) << 10) | _PDE_ATTR) + +#define _PTE_ATTR (_READABLE | _WRITABLE | _NONSECURE) +#define _PTE_VACANT(addr) (((addr) >> SMMU_PAGE_SHIFT) | _PTE_ATTR) + +#define SMMU_MK_PDIR(page, attr) \ + ((page_to_phys(page) >> SMMU_PDIR_SHIFT) | (attr)) +#define SMMU_MK_PDE(page, attr) \ + (unsigned long)((page_to_phys(page) >> SMMU_PDE_SHIFT) | (attr)) +#define SMMU_EX_PTBL_PAGE(pde) \ + pfn_to_page((unsigned long)(pde) & SMMU_PFN_MASK) +#define SMMU_PFN_TO_PTE(pfn, attr) (unsigned long)((pfn) | (attr)) + +#define SMMU_ASID_ENABLE(asid) ((asid) | (1 << 31)) +#define SMMU_ASID_DISABLE 0 +#define SMMU_ASID_ASID(n) ((n) & ~SMMU_ASID_ENABLE(0)) + +#define smmu_client_enable_hwgrp(c, m) smmu_client_set_hwgrp(c, m, 1) +#define smmu_client_disable_hwgrp(c) smmu_client_set_hwgrp(c, 0, 0) +#define __smmu_client_enable_hwgrp(c, m) __smmu_client_set_hwgrp(c, m, 1) +#define __smmu_client_disable_hwgrp(c) __smmu_client_set_hwgrp(c, 0, 0) + +#define HWGRP_INIT(client) [HWGRP_##client] = SMMU_##client##_ASID + +static const u32 smmu_hwgrp_asid_reg[] = { + HWGRP_INIT(AFI), + HWGRP_INIT(AVPC), + HWGRP_INIT(DC), + HWGRP_INIT(DCB), + HWGRP_INIT(EPP), + HWGRP_INIT(G2), + HWGRP_INIT(HC), + HWGRP_INIT(HDA), + HWGRP_INIT(ISP), + HWGRP_INIT(MPE), + HWGRP_INIT(NV), + HWGRP_INIT(NV2), + HWGRP_INIT(PPCS), + HWGRP_INIT(SATA), + HWGRP_INIT(VDE), + HWGRP_INIT(VI), +}; +#define HWGRP_ASID_REG(x) (smmu_hwgrp_asid_reg[x]) + +/* + * Per client for address space + */ +struct smmu_client { + struct device *dev; + struct list_head list; + struct smmu_as *as; + u32 hwgrp; +}; + +/* + * Per address space + */ +struct smmu_as { + struct smmu_device *smmu; /* back pointer to container */ + unsigned int asid; + spinlock_t lock; /* for pagetable */ + struct page *pdir_page; + unsigned long pdir_attr; + unsigned long pde_attr; + unsigned long pte_attr; + unsigned int *pte_count; + + struct list_head client; + spinlock_t client_lock; /* for client list */ +}; + +/* + * Per SMMU device - IOMMU device + */ +struct smmu_device { + void __iomem *regs, *regs_ahbarb; + unsigned long iovmm_base; /* remappable base address */ + unsigned long page_count; /* total remappable size */ + spinlock_t lock; + char *name; + struct device *dev; + int num_as; + struct smmu_as *as; /* Run-time allocated array */ + struct page *avp_vector_page; /* dummy page shared by all AS's */ + + /* + * Register image savers for suspend/resume + */ + unsigned long translation_enable_0; + unsigned long translation_enable_1; + unsigned long translation_enable_2; + unsigned long asid_security; +}; + +static struct smmu_device *smmu_handle; /* unique for a system */ + +/* + * SMMU/AHB register accessors + */ +static inline u32 smmu_read(struct smmu_device *smmu, size_t offs) +{ + return readl(smmu->regs + offs); +} +static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs) +{ + writel(val, smmu->regs + offs); +} + +static inline u32 ahb_read(struct smmu_device *smmu, size_t offs) +{ + return readl(smmu->regs_ahbarb + offs); +} +static inline void ahb_write(struct smmu_device *smmu, u32 val, size_t offs) +{ + writel(val, smmu->regs_ahbarb + offs); +} + +#define VA_PAGE_TO_PA(va, page) \ + (page_to_phys(page) + ((unsigned long)(va) & ~PAGE_MASK)) + +#define FLUSH_CPU_DCACHE(va, page, size) \ + do { \ + unsigned long _pa_ = VA_PAGE_TO_PA(va, page); \ + __cpuc_flush_dcache_area((void *)(va), (size_t)(size)); \ + outer_flush_range(_pa_, _pa_+(size_t)(size)); \ + } while (0) + +/* + * Any interaction between any block on PPSB and a block on APB or AHB + * must have these read-back barriers to ensure the APB/AHB bus + * transaction is complete before initiating activity on the PPSB + * block. + */ +#define FLUSH_SMMU_REGS(smmu) smmu_read(smmu, SMMU_CONFIG) + +#define smmu_client_hwgrp(c) (u32)((c)->dev->platform_data) + +static int __smmu_client_set_hwgrp(struct smmu_client *c, + unsigned long map, int on) +{ + int i; + struct smmu_as *as = c->as; + u32 val, offs, mask = SMMU_ASID_ENABLE(as->asid); + struct smmu_device *smmu = as->smmu; + + WARN_ON(!on && map); + if (on && !map) + return -EINVAL; + if (!on) + map = smmu_client_hwgrp(c); + + for_each_set_bit(i, &map, HWGRP_COUNT) { + offs = HWGRP_ASID_REG(i); + val = smmu_read(smmu, offs); + if (on) { + if (WARN_ON(val & mask)) + goto err_hw_busy; + val |= mask; + } else { + WARN_ON((val & mask) == mask); + val &= ~mask; + } + smmu_write(smmu, val, offs); + } + FLUSH_SMMU_REGS(smmu); + c->hwgrp = map; + return 0; + +err_hw_busy: + for_each_set_bit(i, &map, HWGRP_COUNT) { + offs = HWGRP_ASID_REG(i); + val = smmu_read(smmu, offs); + val &= ~mask; + smmu_write(smmu, val, offs); + } + return -EBUSY; +} + +static int smmu_client_set_hwgrp(struct smmu_client *c, u32 map, int on) +{ + u32 val; + unsigned long flags; + struct smmu_as *as = c->as; + struct smmu_device *smmu = as->smmu; + + spin_lock_irqsave(&smmu->lock, flags); + val = __smmu_client_set_hwgrp(c, map, on); + spin_unlock_irqrestore(&smmu->lock, flags); + return val; +} + +/* + * Flush all TLB entries and all PTC entries + * Caller must lock smmu + */ +static void smmu_flush_regs(struct smmu_device *smmu, int enable) +{ + u32 val; + + smmu_write(smmu, SMMU_PTC_FLUSH_TYPE_ALL, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(smmu); + val = SMMU_TLB_FLUSH_VA_MATCH_ALL | + SMMU_TLB_FLUSH_ASID_MATCH_disable; + smmu_write(smmu, val, SMMU_TLB_FLUSH); + + if (enable) + smmu_write(smmu, SMMU_CONFIG_ENABLE, SMMU_CONFIG); + FLUSH_SMMU_REGS(smmu); +} + +static void smmu_setup_regs(struct smmu_device *smmu) +{ + int i; + u32 val; + + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *as = &smmu->as[i]; + struct smmu_client *c; + + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + val = as->pdir_page ? + SMMU_MK_PDIR(as->pdir_page, as->pdir_attr) : + SMMU_PTB_DATA_RESET_VAL; + smmu_write(smmu, val, SMMU_PTB_DATA); + + list_for_each_entry(c, &as->client, list) + __smmu_client_set_hwgrp(c, c->hwgrp, 1); + } + + smmu_write(smmu, smmu->translation_enable_0, SMMU_TRANSLATION_ENABLE_0); + smmu_write(smmu, smmu->translation_enable_1, SMMU_TRANSLATION_ENABLE_1); + smmu_write(smmu, smmu->translation_enable_2, SMMU_TRANSLATION_ENABLE_2); + smmu_write(smmu, smmu->asid_security, SMMU_ASID_SECURITY); + smmu_write(smmu, SMMU_TLB_CONFIG_RESET_VAL, SMMU_TLB_CONFIG); + smmu_write(smmu, SMMU_PTC_CONFIG_RESET_VAL, SMMU_PTC_CONFIG); + + smmu_flush_regs(smmu, 1); + + val = ahb_read(smmu, AHB_XBAR_CTRL); + val |= AHB_XBAR_CTRL_SMMU_INIT_DONE_DONE << + AHB_XBAR_CTRL_SMMU_INIT_DONE_SHIFT; + ahb_write(smmu, val, AHB_XBAR_CTRL); +} + +static void flush_ptc_and_tlb(struct smmu_device *smmu, + struct smmu_as *as, dma_addr_t iova, + unsigned long *pte, struct page *page, int is_pde) +{ + u32 val; + unsigned long tlb_flush_va = is_pde + ? SMMU_TLB_FLUSH_VA(iova, SECTION) + : SMMU_TLB_FLUSH_VA(iova, GROUP); + + val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pte, page); + smmu_write(smmu, val, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(smmu); + val = tlb_flush_va | + SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | + (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); + smmu_write(smmu, val, SMMU_TLB_FLUSH); + FLUSH_SMMU_REGS(smmu); +} + +static void free_ptbl(struct smmu_as *as, dma_addr_t iova) +{ + unsigned long pdn = SMMU_ADDR_TO_PDN(iova); + unsigned long *pdir = (unsigned long *)page_address(as->pdir_page); + + if (pdir[pdn] != _PDE_VACANT(pdn)) { + dev_dbg(as->smmu->dev, "pdn: %lx\n", pdn); + + ClearPageReserved(SMMU_EX_PTBL_PAGE(pdir[pdn])); + __free_page(SMMU_EX_PTBL_PAGE(pdir[pdn])); + pdir[pdn] = _PDE_VACANT(pdn); + FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); + flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], + as->pdir_page, 1); + } +} + +static void free_pdir(struct smmu_as *as) +{ + unsigned addr; + int count; + struct device *dev = as->smmu->dev; + + if (!as->pdir_page) + return; + + addr = as->smmu->iovmm_base; + count = as->smmu->page_count; + while (count-- > 0) { + free_ptbl(as, addr); + addr += SMMU_PAGE_SIZE * SMMU_PTBL_COUNT; + } + ClearPageReserved(as->pdir_page); + __free_page(as->pdir_page); + as->pdir_page = NULL; + devm_kfree(dev, as->pte_count); + as->pte_count = NULL; +} + +/* + * Maps PTBL for given iova and returns the PTE address + * Caller must unmap the mapped PTBL returned in *ptbl_page_p + */ +static unsigned long *locate_pte(struct smmu_as *as, + dma_addr_t iova, bool allocate, + struct page **ptbl_page_p, + unsigned int **count) +{ + unsigned long ptn = SMMU_ADDR_TO_PFN(iova); + unsigned long pdn = SMMU_ADDR_TO_PDN(iova); + unsigned long *pdir = page_address(as->pdir_page); + unsigned long *ptbl; + + if (pdir[pdn] != _PDE_VACANT(pdn)) { + /* Mapped entry table already exists */ + *ptbl_page_p = SMMU_EX_PTBL_PAGE(pdir[pdn]); + ptbl = page_address(*ptbl_page_p); + } else if (!allocate) { + return NULL; + } else { + int pn; + unsigned long addr = SMMU_PDN_TO_ADDR(pdn); + + /* Vacant - allocate a new page table */ + dev_dbg(as->smmu->dev, "New PTBL pdn: %lx\n", pdn); + + *ptbl_page_p = alloc_page(GFP_ATOMIC); + if (!*ptbl_page_p) { + dev_err(as->smmu->dev, + "failed to allocate smmu_device page table\n"); + return NULL; + } + SetPageReserved(*ptbl_page_p); + ptbl = (unsigned long *)page_address(*ptbl_page_p); + for (pn = 0; pn < SMMU_PTBL_COUNT; + pn++, addr += SMMU_PAGE_SIZE) { + ptbl[pn] = _PTE_VACANT(addr); + } + FLUSH_CPU_DCACHE(ptbl, *ptbl_page_p, SMMU_PTBL_SIZE); + pdir[pdn] = SMMU_MK_PDE(*ptbl_page_p, + as->pde_attr | _PDE_NEXT); + FLUSH_CPU_DCACHE(&pdir[pdn], as->pdir_page, sizeof pdir[pdn]); + flush_ptc_and_tlb(as->smmu, as, iova, &pdir[pdn], + as->pdir_page, 1); + } + *count = &as->pte_count[pdn]; + + return &ptbl[ptn % SMMU_PTBL_COUNT]; +} + +#ifdef CONFIG_SMMU_SIG_DEBUG +static void put_signature(struct smmu_as *as, + dma_addr_t iova, unsigned long pfn) +{ + struct page *page; + unsigned long *vaddr; + + page = pfn_to_page(pfn); + vaddr = page_address(page); + if (!vaddr) + return; + + vaddr[0] = iova; + vaddr[1] = pfn << PAGE_SHIFT; + FLUSH_CPU_DCACHE(vaddr, page, sizeof(vaddr[0]) * 2); +} +#else +static inline void put_signature(struct smmu_as *as, + unsigned long addr, unsigned long pfn) +{ +} +#endif + +/* + * Caller must lock/unlock as + */ +static int alloc_pdir(struct smmu_as *as) +{ + unsigned long *pdir; + int pdn; + u32 val; + struct smmu_device *smmu = as->smmu; + + if (as->pdir_page) + return 0; + + as->pte_count = devm_kzalloc(smmu->dev, + sizeof(as->pte_count[0]) * SMMU_PDIR_COUNT, GFP_KERNEL); + if (!as->pte_count) { + dev_err(smmu->dev, + "failed to allocate smmu_device PTE cunters\n"); + return -ENOMEM; + } + as->pdir_page = alloc_page(GFP_KERNEL | __GFP_DMA); + if (!as->pdir_page) { + dev_err(smmu->dev, + "failed to allocate smmu_device page directory\n"); + devm_kfree(smmu->dev, as->pte_count); + as->pte_count = NULL; + return -ENOMEM; + } + SetPageReserved(as->pdir_page); + pdir = page_address(as->pdir_page); + + for (pdn = 0; pdn < SMMU_PDIR_COUNT; pdn++) + pdir[pdn] = _PDE_VACANT(pdn); + FLUSH_CPU_DCACHE(pdir, as->pdir_page, SMMU_PDIR_SIZE); + val = SMMU_PTC_FLUSH_TYPE_ADR | VA_PAGE_TO_PA(pdir, as->pdir_page); + smmu_write(smmu, val, SMMU_PTC_FLUSH); + FLUSH_SMMU_REGS(as->smmu); + val = SMMU_TLB_FLUSH_VA_MATCH_ALL | + SMMU_TLB_FLUSH_ASID_MATCH__ENABLE | + (as->asid << SMMU_TLB_FLUSH_ASID_SHIFT); + smmu_write(smmu, val, SMMU_TLB_FLUSH); + FLUSH_SMMU_REGS(as->smmu); + + return 0; +} + +static void __smmu_iommu_unmap(struct smmu_as *as, dma_addr_t iova) +{ + unsigned long *pte; + struct page *page; + unsigned int *count; + + pte = locate_pte(as, iova, false, &page, &count); + if (WARN_ON(!pte)) + return; + + if (WARN_ON(*pte == _PTE_VACANT(iova))) + return; + + *pte = _PTE_VACANT(iova); + FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); + flush_ptc_and_tlb(as->smmu, as, iova, pte, page, 0); + if (!--(*count)) { + free_ptbl(as, iova); + smmu_flush_regs(as->smmu, 0); + } +} + +static void __smmu_iommu_map_pfn(struct smmu_as *as, dma_addr_t iova, + unsigned long pfn) +{ + struct smmu_device *smmu = as->smmu; + unsigned long *pte; + unsigned int *count; + struct page *page; + + pte = locate_pte(as, iova, true, &page, &count); + if (WARN_ON(!pte)) + return; + + if (*pte == _PTE_VACANT(iova)) + (*count)++; + *pte = SMMU_PFN_TO_PTE(pfn, as->pte_attr); + if (unlikely((*pte == _PTE_VACANT(iova)))) + (*count)--; + FLUSH_CPU_DCACHE(pte, page, sizeof(*pte)); + flush_ptc_and_tlb(smmu, as, iova, pte, page, 0); + put_signature(as, iova, pfn); +} + +static int smmu_iommu_map(struct iommu_domain *domain, unsigned long iova, + phys_addr_t pa, size_t bytes, int prot) +{ + struct smmu_as *as = domain->priv; + unsigned long pfn = __phys_to_pfn(pa); + unsigned long flags; + + dev_dbg(as->smmu->dev, "[%d] %08lx:%08x\n", as->asid, iova, pa); + + if (!pfn_valid(pfn)) + return -ENOMEM; + + spin_lock_irqsave(&as->lock, flags); + __smmu_iommu_map_pfn(as, iova, pfn); + spin_unlock_irqrestore(&as->lock, flags); + return 0; +} + +static size_t smmu_iommu_unmap(struct iommu_domain *domain, unsigned long iova, + size_t bytes) +{ + struct smmu_as *as = domain->priv; + unsigned long flags; + + dev_dbg(as->smmu->dev, "[%d] %08lx\n", as->asid, iova); + + spin_lock_irqsave(&as->lock, flags); + __smmu_iommu_unmap(as, iova); + spin_unlock_irqrestore(&as->lock, flags); + return SMMU_PAGE_SIZE; +} + +static phys_addr_t smmu_iommu_iova_to_phys(struct iommu_domain *domain, + unsigned long iova) +{ + struct smmu_as *as = domain->priv; + unsigned long *pte; + unsigned int *count; + struct page *page; + unsigned long pfn; + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + + pte = locate_pte(as, iova, true, &page, &count); + pfn = *pte & SMMU_PFN_MASK; + WARN_ON(!pfn_valid(pfn)); + dev_dbg(as->smmu->dev, + "iova:%08lx pfn:%08lx asid:%d\n", iova, pfn, as->asid); + + spin_unlock_irqrestore(&as->lock, flags); + return PFN_PHYS(pfn); +} + +static int smmu_iommu_domain_has_cap(struct iommu_domain *domain, + unsigned long cap) +{ + return 0; +} + +static int smmu_iommu_attach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + struct smmu_client *client, *c; + u32 map; + int err; + + client = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL); + if (!client) + return -ENOMEM; + client->dev = dev; + client->as = as; + map = (unsigned long)dev->platform_data; + if (!map) + return -EINVAL; + + err = smmu_client_enable_hwgrp(client, map); + if (err) + goto err_hwgrp; + + spin_lock(&as->client_lock); + list_for_each_entry(c, &as->client, list) { + if (c->dev == dev) { + dev_err(smmu->dev, + "%s is already attached\n", dev_name(c->dev)); + err = -EINVAL; + goto err_client; + } + } + list_add(&client->list, &as->client); + spin_unlock(&as->client_lock); + + /* + * Reserve "page zero" for AVP vectors using a common dummy + * page. + */ + if (map & HWG_AVPC) { + struct page *page; + + page = as->smmu->avp_vector_page; + __smmu_iommu_map_pfn(as, 0, page_to_pfn(page)); + + pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n"); + } + + dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev)); + return 0; + +err_client: + smmu_client_disable_hwgrp(client); + spin_unlock(&as->client_lock); +err_hwgrp: + devm_kfree(smmu->dev, client); + return err; +} + +static void smmu_iommu_detach_dev(struct iommu_domain *domain, + struct device *dev) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + struct smmu_client *c; + + spin_lock(&as->client_lock); + + list_for_each_entry(c, &as->client, list) { + if (c->dev == dev) { + smmu_client_disable_hwgrp(c); + list_del(&c->list); + devm_kfree(smmu->dev, c); + c->as = NULL; + dev_dbg(smmu->dev, + "%s is detached\n", dev_name(c->dev)); + goto out; + } + } + dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); +out: + spin_unlock(&as->client_lock); +} + +static int smmu_iommu_domain_init(struct iommu_domain *domain) +{ + int i; + unsigned long flags; + struct smmu_as *as; + struct smmu_device *smmu = smmu_handle; + + /* Look for a free AS with lock held */ + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *tmp = &smmu->as[i]; + + spin_lock_irqsave(&tmp->lock, flags); + if (!tmp->pdir_page) { + as = tmp; + goto found; + } + spin_unlock_irqrestore(&tmp->lock, flags); + } + dev_err(smmu->dev, "no free AS\n"); + return -ENODEV; + +found: + if (alloc_pdir(as) < 0) + goto err_alloc_pdir; + + spin_lock(&smmu->lock); + + /* Update PDIR register */ + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + smmu_write(smmu, + SMMU_MK_PDIR(as->pdir_page, as->pdir_attr), SMMU_PTB_DATA); + FLUSH_SMMU_REGS(smmu); + + spin_unlock(&smmu->lock); + + spin_unlock_irqrestore(&as->lock, flags); + domain->priv = as; + + dev_dbg(smmu->dev, "smmu_as@%p\n", as); + return 0; + +err_alloc_pdir: + spin_unlock_irqrestore(&as->lock, flags); + return -ENODEV; +} + +static void smmu_iommu_domain_destroy(struct iommu_domain *domain) +{ + struct smmu_as *as = domain->priv; + struct smmu_device *smmu = as->smmu; + unsigned long flags; + + spin_lock_irqsave(&as->lock, flags); + + if (as->pdir_page) { + spin_lock(&smmu->lock); + smmu_write(smmu, SMMU_PTB_ASID_CUR(as->asid), SMMU_PTB_ASID); + smmu_write(smmu, SMMU_PTB_DATA_RESET_VAL, SMMU_PTB_DATA); + FLUSH_SMMU_REGS(smmu); + spin_unlock(&smmu->lock); + + free_pdir(as); + } + + if (!list_empty(&as->client)) { + struct smmu_client *c; + + list_for_each_entry(c, &as->client, list) + smmu_iommu_detach_dev(domain, c->dev); + } + + spin_unlock_irqrestore(&as->lock, flags); + + domain->priv = NULL; + dev_dbg(smmu->dev, "smmu_as@%p\n", as); +} + +static struct iommu_ops smmu_iommu_ops = { + .domain_init = smmu_iommu_domain_init, + .domain_destroy = smmu_iommu_domain_destroy, + .attach_dev = smmu_iommu_attach_dev, + .detach_dev = smmu_iommu_detach_dev, + .map = smmu_iommu_map, + .unmap = smmu_iommu_unmap, + .iova_to_phys = smmu_iommu_iova_to_phys, + .domain_has_cap = smmu_iommu_domain_has_cap, + .pgsize_bitmap = SMMU_IOMMU_PGSIZES, +}; + +static int tegra_smmu_suspend(struct device *dev) +{ + struct smmu_device *smmu = dev_get_drvdata(dev); + + smmu->translation_enable_0 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_0); + smmu->translation_enable_1 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_1); + smmu->translation_enable_2 = smmu_read(smmu, SMMU_TRANSLATION_ENABLE_2); + smmu->asid_security = smmu_read(smmu, SMMU_ASID_SECURITY); + return 0; +} + +static int tegra_smmu_resume(struct device *dev) +{ + struct smmu_device *smmu = dev_get_drvdata(dev); + unsigned long flags; + + spin_lock_irqsave(&smmu->lock, flags); + smmu_setup_regs(smmu); + spin_unlock_irqrestore(&smmu->lock, flags); + return 0; +} + +static int tegra_smmu_probe(struct platform_device *pdev) +{ + struct smmu_device *smmu; + struct resource *regs, *regs2, *window; + struct device *dev = &pdev->dev; + int i, err = 0; + + if (smmu_handle) + return -EIO; + + BUILD_BUG_ON(PAGE_SHIFT != SMMU_PAGE_SHIFT); + + regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); + regs2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); + window = platform_get_resource(pdev, IORESOURCE_MEM, 2); + if (!regs || !regs2 || !window) { + dev_err(dev, "No SMMU resources\n"); + return -ENODEV; + } + + smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL); + if (!smmu) { + dev_err(dev, "failed to allocate smmu_device\n"); + return -ENOMEM; + } + + smmu->dev = dev; + smmu->num_as = SMMU_NUM_ASIDS; + smmu->iovmm_base = (unsigned long)window->start; + smmu->page_count = resource_size(window) >> SMMU_PAGE_SHIFT; + smmu->regs = devm_ioremap(dev, regs->start, resource_size(regs)); + smmu->regs_ahbarb = devm_ioremap(dev, regs2->start, + resource_size(regs2)); + if (!smmu->regs || !smmu->regs_ahbarb) { + dev_err(dev, "failed to remap SMMU registers\n"); + err = -ENXIO; + goto fail; + } + + smmu->translation_enable_0 = ~0; + smmu->translation_enable_1 = ~0; + smmu->translation_enable_2 = ~0; + smmu->asid_security = 0; + + smmu->as = devm_kzalloc(dev, + sizeof(smmu->as[0]) * smmu->num_as, GFP_KERNEL); + if (!smmu->as) { + dev_err(dev, "failed to allocate smmu_as\n"); + err = -ENOMEM; + goto fail; + } + + for (i = 0; i < smmu->num_as; i++) { + struct smmu_as *as = &smmu->as[i]; + + as->smmu = smmu; + as->asid = i; + as->pdir_attr = _PDIR_ATTR; + as->pde_attr = _PDE_ATTR; + as->pte_attr = _PTE_ATTR; + + spin_lock_init(&as->lock); + INIT_LIST_HEAD(&as->client); + } + spin_lock_init(&smmu->lock); + smmu_setup_regs(smmu); + platform_set_drvdata(pdev, smmu); + + smmu->avp_vector_page = alloc_page(GFP_KERNEL); + if (!smmu->avp_vector_page) + goto fail; + + smmu_handle = smmu; + return 0; + +fail: + if (smmu->avp_vector_page) + __free_page(smmu->avp_vector_page); + if (smmu->regs) + devm_iounmap(dev, smmu->regs); + if (smmu->regs_ahbarb) + devm_iounmap(dev, smmu->regs_ahbarb); + if (smmu && smmu->as) { + for (i = 0; i < smmu->num_as; i++) { + if (smmu->as[i].pdir_page) { + ClearPageReserved(smmu->as[i].pdir_page); + __free_page(smmu->as[i].pdir_page); + } + } + devm_kfree(dev, smmu->as); + } + devm_kfree(dev, smmu); + return err; +} + +static int tegra_smmu_remove(struct platform_device *pdev) +{ + struct smmu_device *smmu = platform_get_drvdata(pdev); + struct device *dev = smmu->dev; + + smmu_write(smmu, SMMU_CONFIG_DISABLE, SMMU_CONFIG); + platform_set_drvdata(pdev, NULL); + if (smmu->as) { + int i; + + for (i = 0; i < smmu->num_as; i++) + free_pdir(&smmu->as[i]); + devm_kfree(dev, smmu->as); + } + if (smmu->avp_vector_page) + __free_page(smmu->avp_vector_page); + if (smmu->regs) + devm_iounmap(dev, smmu->regs); + if (smmu->regs_ahbarb) + devm_iounmap(dev, smmu->regs_ahbarb); + devm_kfree(dev, smmu); + smmu_handle = NULL; + return 0; +} + +const struct dev_pm_ops tegra_smmu_pm_ops = { + .suspend = tegra_smmu_suspend, + .resume = tegra_smmu_resume, +}; + +static struct platform_driver tegra_smmu_driver = { + .probe = tegra_smmu_probe, + .remove = tegra_smmu_remove, + .driver = { + .owner = THIS_MODULE, + .name = "tegra-smmu", + .pm = &tegra_smmu_pm_ops, + }, +}; + +static int __devinit tegra_smmu_init(void) +{ + bus_set_iommu(&platform_bus_type, &smmu_iommu_ops); + return platform_driver_register(&tegra_smmu_driver); +} + +static void __exit tegra_smmu_exit(void) +{ + platform_driver_unregister(&tegra_smmu_driver); +} + +subsys_initcall(tegra_smmu_init); +module_exit(tegra_smmu_exit); + +MODULE_DESCRIPTION("IOMMU API for SMMU in Tegra30"); +MODULE_AUTHOR("Hiroshi DOYU "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From cf427952adcee0210e64b77ae7de9c8f256cce5c Mon Sep 17 00:00:00 2001 From: Antti Palosaari Date: Sat, 21 Jan 2012 11:19:29 -0300 Subject: [media] anysee: repeat failed USB control messages Control message load increased heavily after CI/CAM support due to dvb_ca_en50221. It looks like CI/CAM drops to non-working state easily after error is returned to its callbacks. Due to that, add some logic to avoid errors repeating failed messages. Signed-off-by: Antti Palosaari Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-usb/anysee.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c index cf0c318d698..03c28655af1 100644 --- a/drivers/media/dvb/dvb-usb/anysee.c +++ b/drivers/media/dvb/dvb-usb/anysee.c @@ -58,7 +58,7 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, u8 *rbuf, u8 rlen) { struct anysee_state *state = d->priv; - int act_len, ret; + int act_len, ret, i; u8 buf[64]; memcpy(&buf[0], sbuf, slen); @@ -73,26 +73,52 @@ static int anysee_ctrl_msg(struct dvb_usb_device *d, u8 *sbuf, u8 slen, /* We need receive one message more after dvb_usb_generic_rw due to weird transaction flow, which is 1 x send + 2 x receive. */ ret = dvb_usb_generic_rw(d, buf, sizeof(buf), buf, sizeof(buf), 0); - if (!ret) { + if (ret) + goto error_unlock; + + /* TODO FIXME: dvb_usb_generic_rw() fails rarely with error code -32 + * (EPIPE, Broken pipe). Function supports currently msleep() as a + * parameter but I would not like to use it, since according to + * Documentation/timers/timers-howto.txt it should not be used such + * short, under < 20ms, sleeps. Repeating failed message would be + * better choice as not to add unwanted delays... + * Fixing that correctly is one of those or both; + * 1) use repeat if possible + * 2) add suitable delay + */ + + /* get answer, retry few times if error returned */ + for (i = 0; i < 3; i++) { /* receive 2nd answer */ ret = usb_bulk_msg(d->udev, usb_rcvbulkpipe(d->udev, d->props.generic_bulk_ctrl_endpoint), buf, sizeof(buf), &act_len, 2000); - if (ret) - err("%s: recv bulk message failed: %d", __func__, ret); - else { + + if (ret) { + deb_info("%s: recv bulk message failed: %d", + __func__, ret); + } else { deb_xfer("<<< "); debug_dump(buf, rlen, deb_xfer); if (buf[63] != 0x4f) deb_info("%s: cmd failed\n", __func__); + + break; } } + if (ret) { + /* all retries failed, it is fatal */ + err("%s: recv bulk message failed: %d", __func__, ret); + goto error_unlock; + } + /* read request, copy returned data to return buf */ - if (!ret && rbuf && rlen) + if (rbuf && rlen) memcpy(rbuf, buf, rlen); +error_unlock: mutex_unlock(&anysee_usb_mutex); return ret; -- cgit v1.2.3-70-g09d2 From e4b444369c75604ef6e656969039b1c6b4ca61c5 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 23 Jan 2012 18:45:58 -0300 Subject: [media] drxk_hard: does not need to include linux/version.h This patch removes the unneeded include. Signed-off-by: Jesper Juhl Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/drxk_hard.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/drxk_hard.c b/drivers/media/dvb/frontends/drxk_hard.c index 5fa192731fc..47bf16d44bc 100644 --- a/drivers/media/dvb/frontends/drxk_hard.c +++ b/drivers/media/dvb/frontends/drxk_hard.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "dvb_frontend.h" -- cgit v1.2.3-70-g09d2 From 23268ae5f0447316101ff320ac89d5ee8a0b5f70 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 24 Jan 2012 05:24:36 -0300 Subject: [media] vivi: don't set V4L2_CAP_DEVICE_CAPS for the device_caps field V4L2_CAP_DEVICE_CAPS is valid for the capabilities field only as per the spec. Found with v4l2-compliance. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/vivi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index 84ea88dc10a..5578c195358 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -819,9 +819,9 @@ static int vidioc_querycap(struct file *file, void *priv, strcpy(cap->driver, "vivi"); strcpy(cap->card, "vivi"); strlcpy(cap->bus_info, dev->v4l2_dev.name, sizeof(cap->bus_info)); - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | - V4L2_CAP_READWRITE | V4L2_CAP_DEVICE_CAPS; - cap->device_caps = cap->capabilities; + cap->device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING | + V4L2_CAP_READWRITE; + cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; return 0; } -- cgit v1.2.3-70-g09d2 From a24f64a648376766497fddd8bc24b1ca5b906431 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 26 Jan 2012 18:30:16 +0000 Subject: regmap: Reset device debugfs when reinitialising the cache Most of the data exposed via debugfs is for or from the cache so reset all the debugfs configuration to make sure everything is up to date with the latest configuration, especially if we're changing cache type. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index e9c2ac0174c..2d71aeae310 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -278,6 +278,7 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) mutex_lock(&map->lock); regcache_exit(map); + regmap_debugfs_exit(map); map->max_register = config->max_register; map->writeable_reg = config->writeable_reg; @@ -286,6 +287,8 @@ int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config) map->precious_reg = config->precious_reg; map->cache_type = config->cache_type; + regmap_debugfs_init(map); + ret = regcache_init(map, config); mutex_unlock(&map->lock); -- cgit v1.2.3-70-g09d2 From 8d7b02783bc2b05974f6e47c2be8157f3a9cd89e Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:45 +0000 Subject: bnx2x: Support Queue Per Cos in 5771xx devices Enable the use of up to three hardware queues for transmission. The queues are always dequed round robin (i.e. strict priority, PFC and ETS are not supported). This does allow the allocation of a seperate HW queue for low volume, high priority traffic which will be serviced more promptly. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 7 ++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bf27c54ff2e..0dd22bb44f0 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -984,10 +984,11 @@ static inline int bnx2x_func_start(struct bnx2x *bp) /* Function parameters */ start_params->mf_mode = bp->mf_mode; start_params->sd_vlan_tag = bp->mf_ov; - if (CHIP_IS_E1x(bp)) - start_params->network_cos_mode = OVERRIDE_COS; - else + + if (CHIP_IS_E2(bp) || CHIP_IS_E3(bp)) start_params->network_cos_mode = STATIC_COS; + else /* CHIP_IS_E1X */ + start_params->network_cos_mode = FW_WRR; return bnx2x_func_state_change(bp, &func_params); } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index 66da39f0c84..f33bc5722e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -803,10 +803,10 @@ enum bnx2x_q_type { }; #define BNX2X_PRIMARY_CID_INDEX 0 -#define BNX2X_MULTI_TX_COS_E1X 1 +#define BNX2X_MULTI_TX_COS_E1X 3 /* QM only */ #define BNX2X_MULTI_TX_COS_E2_E3A0 2 #define BNX2X_MULTI_TX_COS_E3B0 3 -#define BNX2X_MULTI_TX_COS BNX2X_MULTI_TX_COS_E3B0 +#define BNX2X_MULTI_TX_COS 3 /* Maximum possible */ struct bnx2x_queue_init_params { -- cgit v1.2.3-70-g09d2 From 127a425e8f05b9813879e8ca909ef4338ec8ec04 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:46 +0000 Subject: bnx2x: Removing indirect register access In virtualized environments indirect access to the device may not be supported (depending on the Hypervisor type). Indirect device access was used since in some harware contexts (i.e. certain chipset and BIOS) every access the driver makes across the pci is followed by a BIOS initiated Zero Length Read to the same address. When accessing widebus registers this zero length read corrupts the serialization of the read/write sequence resulting with errors. To avoid this problem widebus registers are always accessed via the DMAE or the indirect interface. However, the 57712x and 578xx devices intercept the zero length read and so using the indirect interface with these devices is not necessary. Since PDA is only supported for 57712x and 578xx the indirect access to device was restricted to 57710 and 57711x. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- .../net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 53 ++++++++++++---------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 24 +++++++--- 2 files changed, 47 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index 7ec1724753a..f05ee2f137f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -69,12 +69,12 @@ static void bnx2x_write_big_buf(struct bnx2x *bp, u32 addr, u32 len, { if (bp->dmae_ready) bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); - else if (wb) - /* - * Wide bus registers with no dmae need to be written - * using indirect write. - */ + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (wb && CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ else bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); } @@ -99,8 +99,14 @@ static void bnx2x_write_big_buf_wb(struct bnx2x *bp, u32 addr, u32 len) { if (bp->dmae_ready) bnx2x_write_dmae_phys_len(bp, GUNZIP_PHYS(bp), addr, len); - else + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, GUNZIP_BUF(bp), len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ + else + bnx2x_init_str_wr(bp, addr, GUNZIP_BUF(bp), len); } static void bnx2x_init_wr_64(struct bnx2x *bp, u32 addr, @@ -177,8 +183,14 @@ static void bnx2x_init_wr_wb(struct bnx2x *bp, u32 addr, { if (bp->dmae_ready) VIRT_WR_DMAE_LEN(bp, data, addr, len, 0); - else + + /* in E1 chips BIOS initiated ZLR may interrupt widebus writes */ + else if (CHIP_IS_E1(bp)) bnx2x_init_ind_wr(bp, addr, data, len); + + /* in later chips PXP root complex handles BIOS ZLR w/o interrupting */ + else + bnx2x_init_str_wr(bp, addr, data, len); } static void bnx2x_wr_64(struct bnx2x *bp, u32 reg, u32 val_lo, @@ -840,25 +852,15 @@ static void bnx2x_qm_init_cid_count(struct bnx2x *bp, int qm_cid_count, } } -static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count) +static void bnx2x_qm_set_ptr_table(struct bnx2x *bp, int qm_cid_count, + u32 base_reg, u32 reg) { int i; - u32 wb_data[2]; - - wb_data[0] = wb_data[1] = 0; - + u32 wb_data[2] = {0, 0}; for (i = 0; i < 4 * QM_QUEUES_PER_FUNC; i++) { - REG_WR(bp, QM_REG_BASEADDR + i*4, + REG_WR(bp, base_reg + i*4, qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL + i*8, - wb_data, 2); - - if (CHIP_IS_E1H(bp)) { - REG_WR(bp, QM_REG_BASEADDR_EXT_A + i*4, - qm_cid_count * 4 * (i % QM_QUEUES_PER_FUNC)); - bnx2x_init_ind_wr(bp, QM_REG_PTRTBL_EXT_A + i*8, - wb_data, 2); - } + bnx2x_init_wr_wb(bp, reg + i*8, wb_data, 2); } } @@ -873,7 +875,12 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, case INITOP_INIT: /* set in the init-value array */ case INITOP_SET: - bnx2x_qm_set_ptr_table(bp, qm_cid_count); + bnx2x_qm_set_ptr_table(bp, qm_cid_count, + QM_REG_BASEADDR, QM_REG_PTRTBL); + if (CHIP_IS_E1H(bp)) + bnx2x_qm_set_ptr_table(bp, qm_cid_count, + QM_REG_BASEADDR_EXT_A, + QM_REG_PTRTBL_EXT_A); break; case INITOP_CLEAR: break; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e3f978ee6d..e56b8326652 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -498,9 +498,13 @@ void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, if (!bp->dmae_ready) { u32 *data = bnx2x_sp(bp, wb_data[0]); - DP(BNX2X_MSG_OFF, "DMAE is not ready (dst_addr %08x len32 %d)" - " using indirect\n", dst_addr, len32); - bnx2x_init_ind_wr(bp, dst_addr, data, len32); + DP(BNX2X_MSG_OFF, + "DMAE is not ready (dst_addr %08x len32 %d) using indirect\n", + dst_addr, len32); + if (CHIP_IS_E1(bp)) + bnx2x_init_ind_wr(bp, dst_addr, data, len32); + else + bnx2x_init_str_wr(bp, dst_addr, data, len32); return; } @@ -528,10 +532,16 @@ void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32) u32 *data = bnx2x_sp(bp, wb_data[0]); int i; - DP(BNX2X_MSG_OFF, "DMAE is not ready (src_addr %08x len32 %d)" - " using indirect\n", src_addr, len32); - for (i = 0; i < len32; i++) - data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4); + if (CHIP_IS_E1(bp)) { + DP(BNX2X_MSG_OFF, + "DMAE is not ready (src_addr %08x len32 %d) using indirect\n", + src_addr, len32); + for (i = 0; i < len32; i++) + data[i] = bnx2x_reg_rd_ind(bp, src_addr + i*4); + } else + for (i = 0; i < len32; i++) + data[i] = REG_RD(bp, src_addr + i*4); + return; } -- cgit v1.2.3-70-g09d2 From c22610d0001ebf3420d39f419056a56c5aa43096 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:47 +0000 Subject: bnx2x: Obtain Bus Device Function from register BDF was obtained from kernel but since in virtualized environment (e.g. physical device assigment in KVM) the function number may not be the real one, the info must be obtained from the device. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 17 ++++++++++++++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 3 ++- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index e56b8326652..115d77a8beb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10546,6 +10546,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, { struct bnx2x *bp; int rc; + u32 pci_cfg_dword; bool chip_is_e1x = (board_type == BCM57710 || board_type == BCM57711 || board_type == BCM57711E); @@ -10556,7 +10557,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, bp->dev = dev; bp->pdev = pdev; bp->flags = 0; - bp->pf_num = PCI_FUNC(pdev->devfn); rc = pci_enable_device(pdev); if (rc) { @@ -10623,6 +10623,21 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, goto err_out_release; } + /* In E1/E1H use pci device function given by kernel. + * In E2/E3 read physical function from ME register since these chips + * support Physical Device Assignment where kernel BDF maybe arbitrary + * (depending on hypervisor). + */ + if (chip_is_e1x) + bp->pf_num = PCI_FUNC(pdev->devfn); + else {/* chip is E2/3*/ + pci_read_config_dword(bp->pdev, + PCICFG_ME_REGISTER, &pci_cfg_dword); + bp->pf_num = (u8)((pci_cfg_dword & ME_REG_ABS_PF_NUM) >> + ME_REG_ABS_PF_NUM_SHIFT); + } + DP(BNX2X_MSG_SP, "me reg PF num: %d\n", bp->pf_num); + bnx2x_set_power_state(bp, PCI_D0); /* clean indirect addresses */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index dddbcf6e154..8c79e00b37e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -6023,7 +6023,8 @@ #define PCICFG_MSI_CONTROL_64_BIT_ADDR_CAP (0x1<<23) #define PCICFG_MSI_CONTROL_MSI_PVMASK_CAPABLE (0x1<<24) #define PCICFG_GRC_ADDRESS 0x78 -#define PCICFG_GRC_DATA 0x80 +#define PCICFG_GRC_DATA 0x80 +#define PCICFG_ME_REGISTER 0x98 #define PCICFG_MSIX_CAP_ID_OFFSET 0xa0 #define PCICFG_MSIX_CONTROL_TABLE_SIZE (0x7ff<<16) #define PCICFG_MSIX_CONTROL_RESERVED (0x7<<27) -- cgit v1.2.3-70-g09d2 From 89db4ad830fbdde9c2d990b88bbac8245718177d Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:48 +0000 Subject: bnx2x: Function Level Reset Final Cleanup 1. Fix bug where return value is ignored 2. Improve printouts 3. Fix typos Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 28 ++++++++++++++---------- 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 115d77a8beb..9a1c4501f0e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1017,8 +1017,8 @@ void bnx2x_panic_dump(struct bnx2x *bp) * initialization. */ #define FLR_WAIT_USEC 10000 /* 10 miliseconds */ -#define FLR_WAIT_INTERAVAL 50 /* usec */ -#define FLR_POLL_CNT (FLR_WAIT_USEC/FLR_WAIT_INTERAVAL) /* 200 */ +#define FLR_WAIT_INTERVAL 50 /* usec */ +#define FLR_POLL_CNT (FLR_WAIT_USEC/FLR_WAIT_INTERVAL) /* 200 */ struct pbf_pN_buf_regs { int pN; @@ -1051,7 +1051,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp, while ((crd != init_crd) && ((u32)SUB_S32(crd_freed, crd_freed_start) < (init_crd - crd_start))) { if (cur_cnt--) { - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); crd = REG_RD(bp, regs->crd); crd_freed = REG_RD(bp, regs->crd_freed); } else { @@ -1065,7 +1065,7 @@ static void bnx2x_pbf_pN_buf_flushed(struct bnx2x *bp, } } DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF tx buffer[%d]\n", - poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); + poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN); } static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, @@ -1083,7 +1083,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, while (occup && ((u32)SUB_S32(freed, freed_start) < to_free)) { if (cur_cnt--) { - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); occup = REG_RD(bp, regs->lines_occup); freed = REG_RD(bp, regs->lines_freed); } else { @@ -1097,7 +1097,7 @@ static void bnx2x_pbf_pN_cmd_flushed(struct bnx2x *bp, } } DP(BNX2X_MSG_SP, "Waited %d*%d usec for PBF cmd queue[%d]\n", - poll_count-cur_cnt, FLR_WAIT_INTERAVAL, regs->pN); + poll_count-cur_cnt, FLR_WAIT_INTERVAL, regs->pN); } static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg, @@ -1107,7 +1107,7 @@ static inline u32 bnx2x_flr_clnup_reg_poll(struct bnx2x *bp, u32 reg, u32 val; while ((val = REG_RD(bp, reg)) != expected && cur_cnt--) - udelay(FLR_WAIT_INTERAVAL); + udelay(FLR_WAIT_INTERVAL); return val; } @@ -1220,7 +1220,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, int ret = 0; if (REG_RD(bp, comp_addr)) { - BNX2X_ERR("Cleanup complete is not 0\n"); + BNX2X_ERR("Cleanup complete was not 0 before sending\n"); return 1; } @@ -1229,7 +1229,7 @@ static inline int bnx2x_send_final_clnup(struct bnx2x *bp, u8 clnup_func, op_gen.command |= OP_GEN_AGG_VECT(clnup_func); op_gen.command |= 1 << SDM_OP_GEN_AGG_VECT_IDX_VALID_SHIFT; - DP(BNX2X_MSG_SP, "FW Final cleanup\n"); + DP(BNX2X_MSG_SP, "sending FW Final cleanup\n"); REG_WR(bp, XSDM_REG_OPERATION_GEN, op_gen.command); if (bnx2x_flr_clnup_reg_poll(bp, comp_addr, 1, poll_cnt) != 1) { @@ -1344,6 +1344,7 @@ static int bnx2x_pf_flr_clnup(struct bnx2x *bp) REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); /* Poll HW usage counters */ + DP(BNX2X_MSG_SP, "Polling usage counters\n"); if (bnx2x_poll_hw_usage_counters(bp, poll_cnt)) return -EBUSY; @@ -6697,13 +6698,16 @@ static int bnx2x_init_hw_func(struct bnx2x *bp) u16 cdu_ilt_start; u32 addr, val; u32 main_mem_base, main_mem_size, main_mem_prty_clr; - int i, main_mem_width; + int i, main_mem_width, rc; DP(BNX2X_MSG_MCP, "starting func init func %d\n", func); /* FLR cleanup - hmmm */ - if (!CHIP_IS_E1x(bp)) - bnx2x_pf_flr_clnup(bp); + if (!CHIP_IS_E1x(bp)) { + rc = bnx2x_pf_flr_clnup(bp); + if (rc) + return rc; + } /* set MSI reconfigure capability */ if (bp->common.int_block == INT_BLOCK_HC) { -- cgit v1.2.3-70-g09d2 From d1e2d9660e6bca2f06606b4bc65ea669bf669b0a Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:49 +0000 Subject: bnx2x: Loaded Firmware Version Validation In a virtualized environment it is possible for a loading driver to discover that Firmware is already loaded to the device, and that this FW does not match its own. This can happen for example if different Physical Functions are Assigned to different VMs in which different driver versions are loaded. The code in this patch ensures that only drivers with matching FW are loaded over the device, and that in the case described above where the Firmware version doesn't match the driver load is aborted. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 03f3935fd8c..b75c8eab095 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1783,6 +1783,29 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) rc = -EBUSY; /* other port in diagnostic mode */ LOAD_ERROR_EXIT(bp, load_error1); } + if (load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP && + load_code != FW_MSG_CODE_DRV_LOAD_COMMON) { + /* build FW version dword */ + u32 my_fw = (BCM_5710_FW_MAJOR_VERSION) + + (BCM_5710_FW_MINOR_VERSION << 8) + + (BCM_5710_FW_REVISION_VERSION << 16) + + (BCM_5710_FW_ENGINEERING_VERSION << 24); + + /* read loaded FW from chip */ + u32 loaded_fw = REG_RD(bp, XSEM_REG_PRAM); + + DP(BNX2X_MSG_SP, "loaded fw %x, my fw %x", + loaded_fw, my_fw); + + /* abort nic load if version mismatch */ + if (my_fw != loaded_fw) { + BNX2X_ERR("bnx2x with FW %x already loaded, " + "which mismatches my %x FW. aborting", + loaded_fw, my_fw); + rc = -EBUSY; + LOAD_ERROR_EXIT(bp, load_error2); + } + } } else { int path = BP_PATH(bp); -- cgit v1.2.3-70-g09d2 From f16da43b5df947cef427f19b8f5c4b2f5d566231 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:50 +0000 Subject: bnx2x: Lock PF-common resources Use hardware locks to protect resources common to several Physical Functions. In a virtualized environment the RTNL lock only protects a PF's driver against the PFs sharing it's VMs with regard to device resources. Other PFs may reside in other VMs under other OSs, and are not subject to the lock. Such resources which were previously protected implicitly by the RTNL lock must now be protected explicitly with dedicated HW locks. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +- .../net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 22 ++++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 73 ++++++++++++---------- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 7 ++- 4 files changed, 68 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index 0dd22bb44f0..bd990c2e5d1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1540,7 +1540,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) { if (SHMEM2_HAS(bp, drv_flags)) { u32 drv_flags; - bnx2x_acquire_hw_lock(bp, HW_LOCK_DRV_FLAGS); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); drv_flags = SHMEM2_RD(bp, drv_flags); if (set) @@ -1550,7 +1550,7 @@ static inline void bnx2x_update_drv_flags(struct bnx2x *bp, u32 flags, u32 set) SHMEM2_WR(bp, drv_flags, drv_flags); DP(NETIF_MSG_HW, "drv_flags 0x%08x\n", drv_flags); - bnx2x_release_hw_lock(bp, HW_LOCK_DRV_FLAGS); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_DRV_FLAGS); } } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 31a8b38ab15..37a5c52197e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -882,11 +882,27 @@ static int bnx2x_get_eeprom_len(struct net_device *dev) return bp->common.flash_size; } +/* Per pf misc lock must be aquired before the per port mcp lock. Otherwise, had + * we done things the other way around, if two pfs from the same port would + * attempt to access nvram at the same time, we could run into a scenario such + * as: + * pf A takes the port lock. + * pf B succeeds in taking the same lock since they are from the same port. + * pf A takes the per pf misc lock. Performs eeprom access. + * pf A finishes. Unlocks the per pf misc lock. + * Pf B takes the lock and proceeds to perform it's own access. + * pf A unlocks the per port lock, while pf B is still working (!). + * mcp takes the per port lock and corrupts pf B's access (and/or has it's own + * acess corrupted by pf B).* + */ static int bnx2x_acquire_nvram_lock(struct bnx2x *bp) { int port = BP_PORT(bp); int count, i; - u32 val = 0; + u32 val; + + /* acquire HW lock: protect against other PFs in PF Direct Assignment */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM); /* adjust timeout for emulation/FPGA */ count = BNX2X_NVRAM_TIMEOUT_COUNT; @@ -917,7 +933,7 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp) { int port = BP_PORT(bp); int count, i; - u32 val = 0; + u32 val; /* adjust timeout for emulation/FPGA */ count = BNX2X_NVRAM_TIMEOUT_COUNT; @@ -941,6 +957,8 @@ static int bnx2x_release_nvram_lock(struct bnx2x *bp) return -EBUSY; } + /* release HW lock: protect against other PFs in PF Direct Assignment */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_NVRAM); return 0; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 9a1c4501f0e..4824b0f8bd2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -3724,11 +3724,11 @@ static inline void bnx2x_attn_int_deasserted3(struct bnx2x *bp, u32 attn) */ void bnx2x_set_reset_global(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); - + u32 val; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val | BNX2X_GLOBAL_RESET_BIT); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3738,11 +3738,11 @@ void bnx2x_set_reset_global(struct bnx2x *bp) */ static inline void bnx2x_clear_reset_global(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); - + u32 val; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~BNX2X_GLOBAL_RESET_BIT)); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3765,15 +3765,17 @@ static inline bool bnx2x_reset_is_global(struct bnx2x *bp) */ static inline void bnx2x_set_reset_done(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 bit = BP_PATH(bp) ? BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); /* Clear the bit */ val &= ~bit; REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3783,15 +3785,16 @@ static inline void bnx2x_set_reset_done(struct bnx2x *bp) */ void bnx2x_set_reset_in_progress(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 bit = BP_PATH(bp) ? BNX2X_PATH1_RST_IN_PROG_BIT : BNX2X_PATH0_RST_IN_PROG_BIT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); /* Set the bit */ val |= bit; REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /* @@ -3815,12 +3818,15 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine) */ void bnx2x_inc_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK; u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : BNX2X_PATH0_LOAD_CNT_SHIFT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); /* get the current counter value */ @@ -3836,8 +3842,7 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) val |= ((val1 << shift) & mask); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } /** @@ -3851,12 +3856,14 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) */ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) { - u32 val1, val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK; u32 shift = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_SHIFT : BNX2X_PATH0_LOAD_CNT_SHIFT; + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); DP(NETIF_MSG_HW, "Old GEN_REG_VAL=0x%08x\n", val); /* get the current counter value */ @@ -3872,10 +3879,8 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) val |= ((val1 << shift) & mask); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val); - barrier(); - mmiowb(); - - return val1; + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + return val1 != 0; } /* @@ -3907,11 +3912,13 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) */ static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) { - u32 val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); + u32 val; u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : - BNX2X_PATH0_LOAD_CNT_MASK); - + BNX2X_PATH0_LOAD_CNT_MASK); + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); + val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); } static inline void _print_next_block(int idx, const char *blk) @@ -8809,11 +8816,13 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) { u32 val; - /* Check if there is any driver already loaded */ - val = REG_RD(bp, MISC_REG_UNPREPARED); - if (val == 0x1) { + /* possibly another driver is trying to reset the chip */ + bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET); + + /* check if doorbell queue is reset */ + if (REG_RD(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET) + & MISC_REGISTERS_RESET_REG_1_RST_DORQ) { - bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RESET); /* * Check if it is the UNDI driver * UNDI driver initializes CID offset for normal bell to 0x7 @@ -8905,10 +8914,10 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & DRV_MSG_SEQ_NUMBER_MASK); } - - /* now it's safe to release the lock */ - bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET); } + + /* now it's safe to release the lock */ + bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RESET); } static void __devinit bnx2x_get_common_hwinfo(struct bnx2x *bp) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 8c79e00b37e..8ade7bd9a71 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -5731,6 +5731,7 @@ #define MISC_REGISTERS_GPIO_PORT_SHIFT 4 #define MISC_REGISTERS_GPIO_SET_POS 8 #define MISC_REGISTERS_RESET_REG_1_CLEAR 0x588 +#define MISC_REGISTERS_RESET_REG_1_RST_DORQ (0x1<<19) #define MISC_REGISTERS_RESET_REG_1_RST_HC (0x1<<29) #define MISC_REGISTERS_RESET_REG_1_RST_NIG (0x1<<7) #define MISC_REGISTERS_RESET_REG_1_RST_PXP (0x1<<26) @@ -5783,15 +5784,17 @@ #define MISC_REGISTERS_SPIO_OUTPUT_HIGH 1 #define MISC_REGISTERS_SPIO_OUTPUT_LOW 0 #define MISC_REGISTERS_SPIO_SET_POS 8 -#define HW_LOCK_DRV_FLAGS 10 #define HW_LOCK_MAX_RESOURCE_VALUE 31 +#define HW_LOCK_RESOURCE_DRV_FLAGS 10 #define HW_LOCK_RESOURCE_GPIO 1 #define HW_LOCK_RESOURCE_MDIO 0 +#define HW_LOCK_RESOURCE_NVRAM 12 #define HW_LOCK_RESOURCE_PORT0_ATT_MASK 3 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_0 8 #define HW_LOCK_RESOURCE_RECOVERY_LEADER_1 9 -#define HW_LOCK_RESOURCE_SPIO 2 +#define HW_LOCK_RESOURCE_RECOVERY_REG 11 #define HW_LOCK_RESOURCE_RESET 5 +#define HW_LOCK_RESOURCE_SPIO 2 #define AEU_INPUTS_ATTN_BITS_ATC_HW_INTERRUPT (0x1<<4) #define AEU_INPUTS_ATTN_BITS_ATC_PARITY_ERROR (0x1<<5) #define AEU_INPUTS_ATTN_BITS_BRB_PARITY_ERROR (0x1<<18) -- cgit v1.2.3-70-g09d2 From 889b9af34f986138eebebfe781567cb950b3a22b Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:51 +0000 Subject: bnx2x: Track active PFs with bitmap The recovery register (to which a hardware lock has been added in previous patch) is used amongst other things to track the active PFs. The old implementation which used a per path counter is not viable in a virtualized environment where a pf may increment the counter and then have the kernel crash around it preventing the counter from ever reaching zero. In the new implementation the scenario described will result in the PF timing out against the mcp, which will clear the PF's bit in the bitmask allowing recovery process to proceed. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 8 +++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 4 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 56 ++++++++++++------------ 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index b75c8eab095..15db2d679a1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1767,6 +1767,9 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) bnx2x_napi_enable(bp); + /* set pf load just before approaching the MCP */ + bnx2x_set_pf_load(bp); + /* Send LOAD_REQUEST command to MCP * Returns the type of LOAD command: * if it is the first port to be initialized @@ -1972,7 +1975,6 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) if (bp->state == BNX2X_STATE_OPEN) bnx2x_cnic_notify(bp, CNIC_CTL_START_CMD); #endif - bnx2x_inc_load_cnt(bp); /* Wait for all pending SP commands to complete */ if (!bnx2x_wait_sp_comp(bp, ~0x0UL)) { @@ -2012,6 +2014,8 @@ load_error2: bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); + /* clear pf_load status, as it was already set */ + bnx2x_clear_pf_load(bp); load_error0: bnx2x_free_mem(bp); @@ -2132,7 +2136,7 @@ int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode) /* The last driver must disable a "close the gate" if there is no * parity attention or "process kill" pending. */ - if (!bnx2x_dec_load_cnt(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) + if (!bnx2x_clear_pf_load(bp) && bnx2x_reset_is_done(bp, BP_PATH(bp))) bnx2x_disable_close_the_gate(bp); return 0; diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index bd990c2e5d1..a6ef3ef85e5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -379,8 +379,8 @@ void bnx2x_set_q_rx_mode(struct bnx2x *bp, u8 cl_id, unsigned long ramrod_flags); /* Parity errors related */ -void bnx2x_inc_load_cnt(struct bnx2x *bp); -u32 bnx2x_dec_load_cnt(struct bnx2x *bp); +void bnx2x_set_pf_load(struct bnx2x *bp); +bool bnx2x_clear_pf_load(struct bnx2x *bp); bool bnx2x_chk_parity_attn(struct bnx2x *bp, bool *global, bool print); bool bnx2x_reset_is_done(struct bnx2x *bp, int engine); void bnx2x_set_reset_in_progress(struct bnx2x *bp); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 4824b0f8bd2..f7f167a0f85 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -3812,11 +3812,11 @@ bool bnx2x_reset_is_done(struct bnx2x *bp, int engine) } /* - * Increment the load counter for the current engine. + * set pf load for the current pf. * * should be run under rtnl lock */ -void bnx2x_inc_load_cnt(struct bnx2x *bp) +void bnx2x_set_pf_load(struct bnx2x *bp) { u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -3832,8 +3832,8 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) /* get the current counter value */ val1 = (val & mask) >> shift; - /* increment... */ - val1++; + /* set bit of that PF */ + val1 |= (1 << bp->pf_num); /* clear the old value */ val &= ~mask; @@ -3846,15 +3846,15 @@ void bnx2x_inc_load_cnt(struct bnx2x *bp) } /** - * bnx2x_dec_load_cnt - decrement the load counter + * bnx2x_clear_pf_load - clear pf load mark * * @bp: driver handle * * Should be run under rtnl lock. * Decrements the load counter for the current engine. Returns - * the new counter value. + * whether other functions are still loaded */ -u32 bnx2x_dec_load_cnt(struct bnx2x *bp) +bool bnx2x_clear_pf_load(struct bnx2x *bp) { u32 val1, val; u32 mask = BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -3869,8 +3869,8 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) /* get the current counter value */ val1 = (val & mask) >> shift; - /* decrement... */ - val1--; + /* clear bit of that PF */ + val1 &= ~(1 << bp->pf_num); /* clear the old value */ val &= ~mask; @@ -3884,11 +3884,11 @@ u32 bnx2x_dec_load_cnt(struct bnx2x *bp) } /* - * Read the load counter for the current engine. + * Read the load status for the current engine. * * should be run under rtnl lock */ -static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) +static inline bool bnx2x_get_load_status(struct bnx2x *bp, int engine) { u32 mask = (engine ? BNX2X_PATH1_LOAD_CNT_MASK : BNX2X_PATH0_LOAD_CNT_MASK); @@ -3900,17 +3900,15 @@ static inline u32 bnx2x_get_load_cnt(struct bnx2x *bp, int engine) val = (val & mask) >> shift; - DP(NETIF_MSG_HW, "load_cnt for engine %d = %d\n", engine, val); + DP(NETIF_MSG_HW, "load mask for engine %d = 0x%x\n", engine, val); - return val; + return val != 0; } /* - * Reset the load counter for the current engine. - * - * should be run under rtnl lock + * Reset the load status for the current engine. */ -static inline void bnx2x_clear_load_cnt(struct bnx2x *bp) +static inline void bnx2x_clear_load_status(struct bnx2x *bp) { u32 val; u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : @@ -8582,10 +8580,10 @@ static void bnx2x_parity_recover(struct bnx2x *bp) DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_WAIT\n"); if (bp->is_leader) { int other_engine = BP_PATH(bp) ? 0 : 1; - u32 other_load_counter = - bnx2x_get_load_cnt(bp, other_engine); - u32 load_counter = - bnx2x_get_load_cnt(bp, BP_PATH(bp)); + bool other_load_status = + bnx2x_get_load_status(bp, other_engine); + bool load_status = + bnx2x_get_load_status(bp, BP_PATH(bp)); global = bnx2x_reset_is_global(bp); /* @@ -8596,8 +8594,8 @@ static void bnx2x_parity_recover(struct bnx2x *bp) * the the gates will remain closed for that * engine. */ - if (load_counter || - (global && other_load_counter)) { + if (load_status || + (global && other_load_status)) { /* Wait until all other functions get * down. */ @@ -10206,14 +10204,14 @@ static int bnx2x_open(struct net_device *dev) struct bnx2x *bp = netdev_priv(dev); bool global = false; int other_engine = BP_PATH(bp) ? 0 : 1; - u32 other_load_counter, load_counter; + bool other_load_status, load_status; netif_carrier_off(dev); bnx2x_set_power_state(bp, PCI_D0); - other_load_counter = bnx2x_get_load_cnt(bp, other_engine); - load_counter = bnx2x_get_load_cnt(bp, BP_PATH(bp)); + other_load_status = bnx2x_get_load_status(bp, other_engine); + load_status = bnx2x_get_load_status(bp, BP_PATH(bp)); /* * If parity had happen during the unload, then attentions @@ -10239,8 +10237,8 @@ static int bnx2x_open(struct net_device *dev) * global blocks only the first in the chip should try * to recover. */ - if ((!load_counter && - (!global || !other_load_counter)) && + if ((!load_status && + (!global || !other_load_status)) && bnx2x_trylock_leader_lock(bp) && !bnx2x_leader_reset(bp)) { netdev_info(bp->dev, "Recovered in open\n"); @@ -10680,7 +10678,7 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); /* Reset the load counter */ - bnx2x_clear_load_cnt(bp); + bnx2x_clear_load_status(bp); dev->watchdog_timeo = TX_TIMEOUT; -- cgit v1.2.3-70-g09d2 From 95c6c6165eaf5a031bcf31606e081c72e4acdeb8 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:52 +0000 Subject: bnx2x: Recovery flow bug fixes 1. Sample mcp pulse and mcp sequence in nic load instead of in init_one as they may change by the time we want to use them. 2. Allow cnic to access device during nic load (by adding a new "LOADING" state to recovery flow). This prevents the unnecessary cnic timeout which resulted by cnic attempting to access because nic is loading, but being blocked because of the Recovery state. 3. Issue 'fake' driver load command to mcp when last driver unloads to prevent mcp from taking ownership. When recovery is complete unload fake driver to allow mcp to initialize the hardware before first driver loads. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 3 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 18 +++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 102 +++++++++++++---------- 3 files changed, 75 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 8c73d34b2ff..06bbef742fa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1088,7 +1088,8 @@ enum bnx2x_recovery_state { BNX2X_RECOVERY_DONE, BNX2X_RECOVERY_INIT, BNX2X_RECOVERY_WAIT, - BNX2X_RECOVERY_FAILED + BNX2X_RECOVERY_FAILED, + BNX2X_RECOVERY_NIC_LOADING }; /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 15db2d679a1..8fdd71b7bef 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1776,6 +1776,18 @@ int bnx2x_nic_load(struct bnx2x *bp, int load_mode) * common blocks should be initialized, otherwise - not */ if (!BP_NOMCP(bp)) { + /* init fw_seq */ + bp->fw_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & + DRV_MSG_SEQ_NUMBER_MASK); + BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); + + /* Get current FW pulse sequence */ + bp->fw_drv_pulse_wr_seq = + (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_pulse_mb) & + DRV_PULSE_SEQ_MASK); + BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); if (!load_code) { BNX2X_ERR("MCP response failure, aborting\n"); @@ -3442,7 +3454,7 @@ int bnx2x_change_mtu(struct net_device *dev, int new_mtu) struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. Try again later\n"); return -EAGAIN; } @@ -3569,7 +3581,7 @@ int bnx2x_resume(struct pci_dev *pdev) bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. Try again later\n"); return -EAGAIN; } @@ -3585,8 +3597,6 @@ int bnx2x_resume(struct pci_dev *pdev) bnx2x_set_power_state(bp, PCI_D0); netif_device_attach(dev); - /* Since the chip was reset, clear the FW sequence number */ - bp->fw_seq = 0; rc = bnx2x_nic_load(bp, LOAD_OPEN); rtnl_unlock(); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index f7f167a0f85..c945df06161 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -468,7 +468,9 @@ static int bnx2x_issue_dmae_with_comp(struct bnx2x *bp, while ((*wb_comp & ~DMAE_PCI_ERR_FLAG) != DMAE_COMP_VAL) { DP(BNX2X_MSG_OFF, "wb_comp 0x%08x\n", *wb_comp); - if (!cnt) { + if (!cnt || + (bp->recovery_state != BNX2X_RECOVERY_DONE && + bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { BNX2X_ERR("DMAE timeout!\n"); rc = DMAE_TIMEOUT; goto unlock; @@ -8477,13 +8479,38 @@ int bnx2x_leader_reset(struct bnx2x *bp) { int rc = 0; bool global = bnx2x_reset_is_global(bp); + u32 load_code; + + /* if not going to reset MCP - load "fake" driver to reset HW while + * driver is owner of the HW + */ + if (!global && !BP_NOMCP(bp)) { + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_REQ, 0); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset; + } + if ((load_code != FW_MSG_CODE_DRV_LOAD_COMMON_CHIP) && + (load_code != FW_MSG_CODE_DRV_LOAD_COMMON)) { + BNX2X_ERR("MCP unexpected resp, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset2; + } + load_code = bnx2x_fw_command(bp, DRV_MSG_CODE_LOAD_DONE, 0); + if (!load_code) { + BNX2X_ERR("MCP response failure, aborting\n"); + rc = -EAGAIN; + goto exit_leader_reset2; + } + } /* Try to recover after the failure */ if (bnx2x_process_kill(bp, global)) { netdev_err(bp->dev, "Something bad had happen on engine %d! " "Aii!\n", BP_PATH(bp)); rc = -EAGAIN; - goto exit_leader_reset; + goto exit_leader_reset2; } /* @@ -8494,6 +8521,12 @@ int bnx2x_leader_reset(struct bnx2x *bp) if (global) bnx2x_clear_reset_global(bp); +exit_leader_reset2: + /* unload "fake driver" if it was loaded */ + if (!global && !BP_NOMCP(bp)) { + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_REQ_WOL_MCP, 0); + bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE, 0); + } exit_leader_reset: bp->is_leader = 0; bnx2x_release_leader_lock(bp); @@ -8530,13 +8563,15 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) static void bnx2x_parity_recover(struct bnx2x *bp) { bool global = false; + bool is_parity; DP(NETIF_MSG_HW, "Handling parity\n"); while (1) { switch (bp->recovery_state) { case BNX2X_RECOVERY_INIT: DP(NETIF_MSG_HW, "State is BNX2X_RECOVERY_INIT\n"); - bnx2x_chk_parity_attn(bp, &global, false); + is_parity = bnx2x_chk_parity_attn(bp, &global, false); + WARN_ON(!is_parity); /* Try to get a LEADER_LOCK HW lock */ if (bnx2x_trylock_leader_lock(bp)) { @@ -8560,15 +8595,6 @@ static void bnx2x_parity_recover(struct bnx2x *bp) bp->recovery_state = BNX2X_RECOVERY_WAIT; - /* - * Reset MCP command sequence number and MCP mail box - * sequence as we are going to reset the MCP. - */ - if (global) { - bp->fw_seq = 0; - bp->fw_drv_pulse_wr_seq = 0; - } - /* Ensure "is_leader", MCP command sequence and * "recovery_state" update values are seen on other * CPUs. @@ -8652,9 +8678,20 @@ static void bnx2x_parity_recover(struct bnx2x *bp) return; } - if (bnx2x_nic_load(bp, LOAD_NORMAL)) - bnx2x_recovery_failed(bp); - else { + bp->recovery_state = + BNX2X_RECOVERY_NIC_LOADING; + if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + netdev_err(bp->dev, + "Recovery failed. " + "Power cycle " + "needed\n"); + /* Disconnect this device */ + netif_device_detach(bp->dev); + /* Shut down the power */ + bnx2x_set_power_state( + bp, PCI_D3hot); + smp_mb(); + } else { bp->recovery_state = BNX2X_RECOVERY_DONE; smp_mb(); @@ -8908,9 +8945,6 @@ static void __devinit bnx2x_undi_unload(struct bnx2x *bp) /* restore our func and fw_seq */ bp->pf_num = orig_pf_num; - bp->fw_seq = - (SHMEM_RD(bp, func_mb[bp->pf_num].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); } } @@ -9936,16 +9970,6 @@ static int __devinit bnx2x_get_hwinfo(struct bnx2x *bp) bnx2x_get_cnic_info(bp); - /* Get current FW pulse sequence */ - if (!BP_NOMCP(bp)) { - int mb_idx = BP_FW_MB_IDX(bp); - - bp->fw_drv_pulse_wr_seq = - (SHMEM_RD(bp, func_mb[mb_idx].drv_pulse_mb) & - DRV_PULSE_SEQ_MASK); - BNX2X_DEV_INFO("drv_pulse 0x%x\n", bp->fw_drv_pulse_wr_seq); - } - return rc; } @@ -10115,14 +10139,6 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) if (!BP_NOMCP(bp)) bnx2x_undi_unload(bp); - /* init fw_seq after undi_unload! */ - if (!BP_NOMCP(bp)) { - bp->fw_seq = - (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - } - if (CHIP_REV_IS_FPGA(bp)) dev_err(&bp->pdev->dev, "FPGA detected\n"); @@ -11331,13 +11347,6 @@ static void bnx2x_eeh_recover(struct bnx2x *bp) if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB)) BNX2X_ERR("BAD MCP validity signature\n"); - - if (!BP_NOMCP(bp)) { - bp->fw_seq = - (SHMEM_RD(bp, func_mb[BP_FW_MB_IDX(bp)].drv_mb_header) & - DRV_MSG_SEQ_NUMBER_MASK); - BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq); - } } /** @@ -11593,6 +11602,13 @@ static int bnx2x_cnic_sp_queue(struct net_device *dev, return -EIO; #endif + if ((bp->recovery_state != BNX2X_RECOVERY_DONE) && + (bp->recovery_state != BNX2X_RECOVERY_NIC_LOADING)) { + netdev_err(dev, "Handling parity error recovery. Try again " + "later\n"); + return -EAGAIN; + } + spin_lock_bh(&bp->spq_lock); for (i = 0; i < count; i++) { -- cgit v1.2.3-70-g09d2 From 7a752993fe90adf8e150cc1a85beef5f782429e7 Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:53 +0000 Subject: bnx2x: Recoverable and unrecoverable error statistics Add statistics for tracking parity errors from which we successfully recovered and those which were deemed unrecoverable. Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 12 +++++++++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 13 +++++++++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 4 ++++ 3 files changed, 26 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 37a5c52197e..06cb2442c8f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -175,7 +175,11 @@ static const struct { { STATS_OFFSET32(total_tpa_aggregated_frames_hi), 8, STATS_FLAGS_FUNC, "tpa_aggregated_frames"}, { STATS_OFFSET32(total_tpa_bytes_hi), - 8, STATS_FLAGS_FUNC, "tpa_bytes"} + 8, STATS_FLAGS_FUNC, "tpa_bytes"}, + { STATS_OFFSET32(recoverable_error), + 4, STATS_FLAGS_FUNC, "recoverable_errors" }, + { STATS_OFFSET32(unrecoverable_error), + 4, STATS_FLAGS_FUNC, "unrecoverable_errors" }, }; #define BNX2X_NUM_STATS ARRAY_SIZE(bnx2x_stats_arr) @@ -1388,7 +1392,8 @@ static int bnx2x_set_ringparam(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(dev, "Handling parity error recovery. " + "Try again later\n"); return -EAGAIN; } @@ -2042,7 +2047,8 @@ static void bnx2x_self_test(struct net_device *dev, struct bnx2x *bp = netdev_priv(dev); u8 is_serdes; if (bp->recovery_state != BNX2X_RECOVERY_DONE) { - pr_err("Handling parity error recovery. Try again later\n"); + netdev_err(bp->dev, "Handling parity error recovery. " + "Try again later\n"); etest->flags |= ETH_TEST_FL_FAILED; return; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index c945df06161..cdce7663efd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -784,6 +784,7 @@ void bnx2x_panic_dump(struct bnx2x *bp) #endif bp->stats_state = STATS_STATE_DISABLED; + bp->eth_stats.unrecoverable_error++; DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n"); BNX2X_ERR("begin crash dump -----------------\n"); @@ -5441,6 +5442,7 @@ static void bnx2x_init_eth_fp(struct bnx2x *bp, int fp_idx) /* init shortcut */ fp->ustorm_rx_prods_offset = bnx2x_rx_ustorm_prods_offset(fp); + /* Setup SB indicies */ fp->rx_cons_sb = BNX2X_RX_SB_INDEX; @@ -8563,6 +8565,7 @@ static inline void bnx2x_recovery_failed(struct bnx2x *bp) static void bnx2x_parity_recover(struct bnx2x *bp) { bool global = false; + u32 error_recovered, error_unrecovered; bool is_parity; DP(NETIF_MSG_HW, "Handling parity\n"); @@ -8678,9 +8681,14 @@ static void bnx2x_parity_recover(struct bnx2x *bp) return; } + error_recovered = + bp->eth_stats.recoverable_error; + error_unrecovered = + bp->eth_stats.unrecoverable_error; bp->recovery_state = BNX2X_RECOVERY_NIC_LOADING; if (bnx2x_nic_load(bp, LOAD_NORMAL)) { + error_unrecovered++; netdev_err(bp->dev, "Recovery failed. " "Power cycle " @@ -8694,8 +8702,13 @@ static void bnx2x_parity_recover(struct bnx2x *bp) } else { bp->recovery_state = BNX2X_RECOVERY_DONE; + error_recovered++; smp_mb(); } + bp->eth_stats.recoverable_error = + error_recovered; + bp->eth_stats.unrecoverable_error = + error_unrecovered; return; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 683deb05310..9c28db167fa 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -199,6 +199,10 @@ struct bnx2x_eth_stats { u32 pfc_frames_received_lo; u32 pfc_frames_sent_hi; u32 pfc_frames_sent_lo; + + /* Recovery */ + u32 recoverable_error; + u32 unrecoverable_error; }; -- cgit v1.2.3-70-g09d2 From 85b26ea18ee63be83d65ec6db72ad7857980a04b Mon Sep 17 00:00:00 2001 From: Ariel Elior Date: Thu, 26 Jan 2012 06:01:54 +0000 Subject: bnx2x: Update version to 1.72.0 and copyrights Signed-off-by: Ariel Elior Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 6 +++--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 2 +- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 2 +- 20 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 06bbef742fa..7d184fbffaf 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h @@ -1,6 +1,6 @@ /* bnx2x.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,8 @@ * (you will need to reboot afterwards) */ /* #define BNX2X_STOP_ON_ERROR */ -#define DRV_MODULE_VERSION "1.70.35-0" -#define DRV_MODULE_RELDATE "2011/11/10" +#define DRV_MODULE_VERSION "1.72.00-0" +#define DRV_MODULE_RELDATE "2012/01/26" #define BNX2X_BC_VER 0x040200 #if defined(CONFIG_DCB) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index 8fdd71b7bef..6e6a684359b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -1,6 +1,6 @@ /* bnx2x_cmn.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h index a6ef3ef85e5..c7c7bf1e573 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h @@ -1,6 +1,6 @@ /* bnx2x_cmn.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c index 5051cf3deb2..9a9bd3ab479 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.c @@ -1,6 +1,6 @@ /* bnx2x_dcb.c: Broadcom Everest network driver. * - * Copyright 2009-2011 Broadcom Corporation + * Copyright 2009-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h index 2ab9254e2d5..06c7a043594 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dcb.h @@ -1,6 +1,6 @@ /* bnx2x_dcb.h: Broadcom Everest network driver. * - * Copyright 2009-2011 Broadcom Corporation + * Copyright 2009-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h index b983825d0ee..3e4cff9b1eb 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_dump.h @@ -1,6 +1,6 @@ /* bnx2x_dump.h: Broadcom Everest network driver. * - * Copyright (c) 2011 Broadcom Corporation + * Copyright (c) 2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 06cb2442c8f..137968d33d1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -1,6 +1,6 @@ /* bnx2x_ethtool.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h index 998652a1b85..e5c5982ae06 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_defs.h @@ -1,6 +1,6 @@ /* bnx2x_fw_defs.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h index f4a07fbaed0..4bed52ba300 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_fw_file_hdr.h @@ -1,6 +1,6 @@ /* bnx2x_fw_file_hdr.h: FW binary file header structure. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h index 3e30c8642c2..78b77de728b 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h @@ -1,6 +1,6 @@ /* bnx2x_hsi.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h index 4d748e77d1a..29f5c3cca31 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init.h @@ -1,7 +1,7 @@ /* bnx2x_init.h: Broadcom Everest network driver. * Structures and macroes needed during the initialization. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h index f05ee2f137f..fe66d902dc6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_init_ops.h @@ -2,7 +2,7 @@ * Static functions needed during the initialization. * This file is "included" in bnx2x_main.c. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 2091e5dbbcd..2102ad593c1 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -1,4 +1,4 @@ -/* Copyright 2008-2011 Broadcom Corporation +/* Copyright 2008-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index e02a68a7fb8..9cc7bafb3df 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2011 Broadcom Corporation +/* Copyright 2008-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index cdce7663efd..fea96150539 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -1,6 +1,6 @@ /* bnx2x_main.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h index 8ade7bd9a71..c95d9dcac6d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h @@ -1,6 +1,6 @@ /* bnx2x_reg.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c index 69465c32e5f..ac15f747f8d 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.c @@ -1,6 +1,6 @@ /* bnx2x_sp.c: Broadcom Everest network driver. * - * Copyright 2011 Broadcom Corporation + * Copyright (c) 2011-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h index f33bc5722e5..71e039b618a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sp.h @@ -1,6 +1,6 @@ /* bnx2x_sp.h: Broadcom Everest network driver. * - * Copyright 2011 Broadcom Corporation + * Copyright (c) 2011-2012 Broadcom Corporation * * Unless you and Broadcom execute a separate written software license * agreement governing use of this software, this software is licensed to you diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index bc0121ac291..7b9b304b910 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1,6 +1,6 @@ /* bnx2x_stats.c: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 9c28db167fa..7e979686cd6 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -1,6 +1,6 @@ /* bnx2x_stats.h: Broadcom Everest network driver. * - * Copyright (c) 2007-2011 Broadcom Corporation + * Copyright (c) 2007-2012 Broadcom Corporation * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-70-g09d2 From bb349bb4b19b39830e0486aedfd7c7dca23b7baf Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 25 Jan 2012 03:56:30 +0000 Subject: be2net: allocate more headroom in incoming skbs Allocation of 64 bytes in skb headroom is not enough if we have to pull ethernet + ipv6 + tcp headers, and/or extra tunneling header. Its currently not noticed because netdev_alloc_skb_ip_align(64) give us more room, thanks to power-of-two kmalloc() roundups. Make sure we ask for 128 bytes so that side effects of upcoming patches from Ian Campbell dont decrease benet rx performance, because of extra skb head reallocations. Signed-off-by: Eric Dumazet Cc: Ian Campbell Cc: Vasundhara Volam Cc: Sathya Perla Cc: Ajit Khaparde Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 3 +++ drivers/net/ethernet/emulex/benet/be_main.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index cbdec2536da..453d48612f8 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -74,6 +74,9 @@ static inline char *nic_name(struct pci_dev *pdev) /* Number of bytes of an RX frame that are copied to skb->data */ #define BE_HDR_LEN ((u16) 64) +/* allocate extra space to allow tunneling decapsulation without head reallocation */ +#define BE_RX_SKB_ALLOC_SIZE (BE_HDR_LEN + 64) + #define BE_MAX_JUMBO_FRAME_SIZE 9018 #define BE_MIN_MTU 256 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index e703d64434f..0fbf365f5c6 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -1189,7 +1189,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, struct net_device *netdev = adapter->netdev; struct sk_buff *skb; - skb = netdev_alloc_skb_ip_align(netdev, BE_HDR_LEN); + skb = netdev_alloc_skb_ip_align(netdev, BE_RX_SKB_ALLOC_SIZE); if (unlikely(!skb)) { rx_stats(rxo)->rx_drops_no_skbs++; be_rx_compl_discard(adapter, rxo, rxcp); -- cgit v1.2.3-70-g09d2 From fec67b45bf045582c3172101970090d640cd56d9 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 25 Jan 2012 13:03:29 +0100 Subject: usb: cdc-wdm: Add device-id for Huawei 3G/LTE modems MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [v2: Editorial changes suggested by Sergei Shtylyov] These modems use the Qualcomm MSM Interface (QMI) protocol for management of their CDC ECM like wwan interface. This driver is perfect for exporting the protocol to userspace. The created character device will be indistinguishable from a common AT command based Device Management interface, so userspace applications must do some intelligent matching on the USB device. Cc: Sergei Shtylyov Signed-off-by: Bjørn Mork Acked-by: Oliver Neukum Acked-by: Marcel Holtmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index c154d4f1d67..23cf9d38eb5 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -31,6 +31,8 @@ #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" +#define HUAWEI_VENDOR_ID 0x12D1 + static const struct usb_device_id wdm_ids[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | @@ -38,6 +40,20 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM }, + { + /* + * Huawei E392, E398 and possibly other Qualcomm based modems + * embed the Qualcomm QMI protocol inside CDC on CDC ECM like + * control interfaces. Userspace access to this is required + * to configure the accompanying data interface + */ + .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = HUAWEI_VENDOR_ID, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 1, + .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ + }, { } }; -- cgit v1.2.3-70-g09d2 From 3afbd89c9639c344300dcdd7d4e5e18dda559fd4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 25 Jan 2012 09:05:04 +0100 Subject: serial/efm32: add new driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/tty/serial/efm32-uart.txt | 14 + drivers/tty/serial/Kconfig | 13 + drivers/tty/serial/Makefile | 1 + drivers/tty/serial/efm32-uart.c | 830 +++++++++++++++++++++ include/linux/platform_data/efm32-uart.h | 18 + include/linux/serial_core.h | 2 + 6 files changed, 878 insertions(+) create mode 100644 Documentation/devicetree/bindings/tty/serial/efm32-uart.txt create mode 100644 drivers/tty/serial/efm32-uart.c create mode 100644 include/linux/platform_data/efm32-uart.h (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt new file mode 100644 index 00000000000..6588b6950a7 --- /dev/null +++ b/Documentation/devicetree/bindings/tty/serial/efm32-uart.txt @@ -0,0 +1,14 @@ +* Energymicro efm32 UART + +Required properties: +- compatible : Should be "efm32,uart" +- reg : Address and length of the register set +- interrupts : Should contain uart interrupt + +Example: + +uart@0x4000c400 { + compatible = "efm32,uart"; + reg = <0x4000c400 0x400>; + interrupts = <15>; +}; diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index aca2386c5ef..6e24a8f5fd2 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -1628,4 +1628,17 @@ config SERIAL_AR933X_NR_UARTS Set this to the number of serial ports you want the driver to support. +config SERIAL_EFM32_UART + tristate "EFM32 UART/USART port." + depends on ARCH_EFM32 + select SERIAL_CORE + help + This driver support the USART and UART ports on + Energy Micro's efm32 SoCs. + +config SERIAL_EFM32_UART_CONSOLE + bool "EFM32 UART/USART console support" + depends on SERIAL_EFM32_UART=y + select SERIAL_CORE_CONSOLE + endmenu diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile index f5b01f2ce52..1997ad4a39a 100644 --- a/drivers/tty/serial/Makefile +++ b/drivers/tty/serial/Makefile @@ -92,3 +92,4 @@ obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o +obj-$(CONFIG_SERIAL_EFM32_UART) += efm32-uart.o diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c new file mode 100644 index 00000000000..615e4647049 --- /dev/null +++ b/drivers/tty/serial/efm32-uart.c @@ -0,0 +1,830 @@ +#if defined(CONFIG_SERIAL_EFM32_UART_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +#define SUPPORT_SYSRQ +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define DRIVER_NAME "efm32-uart" +#define DEV_NAME "ttyefm" + +#define UARTn_CTRL 0x00 +#define UARTn_CTRL_SYNC 0x0001 +#define UARTn_CTRL_TXBIL 0x1000 + +#define UARTn_FRAME 0x04 +#define UARTn_FRAME_DATABITS__MASK 0x000f +#define UARTn_FRAME_DATABITS(n) ((n) - 3) +#define UARTn_FRAME_PARITY_NONE 0x0000 +#define UARTn_FRAME_PARITY_EVEN 0x0200 +#define UARTn_FRAME_PARITY_ODD 0x0300 +#define UARTn_FRAME_STOPBITS_HALF 0x0000 +#define UARTn_FRAME_STOPBITS_ONE 0x1000 +#define UARTn_FRAME_STOPBITS_TWO 0x3000 + +#define UARTn_CMD 0x0c +#define UARTn_CMD_RXEN 0x0001 +#define UARTn_CMD_RXDIS 0x0002 +#define UARTn_CMD_TXEN 0x0004 +#define UARTn_CMD_TXDIS 0x0008 + +#define UARTn_STATUS 0x10 +#define UARTn_STATUS_TXENS 0x0002 +#define UARTn_STATUS_TXC 0x0020 +#define UARTn_STATUS_TXBL 0x0040 +#define UARTn_STATUS_RXDATAV 0x0080 + +#define UARTn_CLKDIV 0x14 + +#define UARTn_RXDATAX 0x18 +#define UARTn_RXDATAX_RXDATA__MASK 0x01ff +#define UARTn_RXDATAX_PERR 0x4000 +#define UARTn_RXDATAX_FERR 0x8000 +/* + * This is a software only flag used for ignore_status_mask and + * read_status_mask! It's used for breaks that the hardware doesn't report + * explicitly. + */ +#define SW_UARTn_RXDATAX_BERR 0x2000 + +#define UARTn_TXDATA 0x34 + +#define UARTn_IF 0x40 +#define UARTn_IF_TXC 0x0001 +#define UARTn_IF_TXBL 0x0002 +#define UARTn_IF_RXDATAV 0x0004 +#define UARTn_IF_RXOF 0x0010 + +#define UARTn_IFS 0x44 +#define UARTn_IFC 0x48 +#define UARTn_IEN 0x4c + +#define UARTn_ROUTE 0x54 +#define UARTn_ROUTE_LOCATION__MASK 0x0700 +#define UARTn_ROUTE_LOCATION(n) (((n) << 8) & UARTn_ROUTE_LOCATION__MASK) +#define UARTn_ROUTE_RXPEN 0x0001 +#define UARTn_ROUTE_TXPEN 0x0002 + +struct efm32_uart_port { + struct uart_port port; + unsigned int txirq; + struct clk *clk; +}; +#define to_efm_port(_port) container_of(_port, struct efm32_uart_port, port) +#define efm_debug(efm_port, format, arg...) \ + dev_dbg(efm_port->port.dev, format, ##arg) + +static void efm32_uart_write32(struct efm32_uart_port *efm_port, + u32 value, unsigned offset) +{ + writel_relaxed(value, efm_port->port.membase + offset); +} + +static u32 efm32_uart_read32(struct efm32_uart_port *efm_port, + unsigned offset) +{ + return readl_relaxed(efm_port->port.membase + offset); +} + +static unsigned int efm32_uart_tx_empty(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + + if (status & UARTn_STATUS_TXC) + return TIOCSER_TEMT; + else + return 0; +} + +static void efm32_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) +{ + /* sorry, neither handshaking lines nor loop functionallity */ +} + +static unsigned int efm32_uart_get_mctrl(struct uart_port *port) +{ + /* sorry, no handshaking lines available */ + return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; +} + +static void efm32_uart_stop_tx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 ien = efm32_uart_read32(efm_port, UARTn_IEN); + + efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); + ien &= ~(UARTn_IF_TXC | UARTn_IF_TXBL); + efm32_uart_write32(efm_port, ien, UARTn_IEN); +} + +static void efm32_uart_tx_chars(struct efm32_uart_port *efm_port) +{ + struct uart_port *port = &efm_port->port; + struct circ_buf *xmit = &port->state->xmit; + + while (efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_TXBL) { + if (port->x_char) { + port->icount.tx++; + efm32_uart_write32(efm_port, port->x_char, + UARTn_TXDATA); + port->x_char = 0; + continue; + } + if (!uart_circ_empty(xmit) && !uart_tx_stopped(port)) { + port->icount.tx++; + efm32_uart_write32(efm_port, xmit->buf[xmit->tail], + UARTn_TXDATA); + xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); + } else + break; + } + + if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) + uart_write_wakeup(port); + + if (!port->x_char && uart_circ_empty(xmit) && + efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_TXC) + efm32_uart_stop_tx(port); +} + +static void efm32_uart_start_tx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 ien; + + efm32_uart_write32(efm_port, + UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IFC); + ien = efm32_uart_read32(efm_port, UARTn_IEN); + efm32_uart_write32(efm_port, + ien | UARTn_IF_TXBL | UARTn_IF_TXC, UARTn_IEN); + efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); + + efm32_uart_tx_chars(efm_port); +} + +static void efm32_uart_stop_rx(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + efm32_uart_write32(efm_port, UARTn_CMD_RXDIS, UARTn_CMD); +} + +static void efm32_uart_enable_ms(struct uart_port *port) +{ + /* no handshake lines, no modem status interrupts */ +} + +static void efm32_uart_break_ctl(struct uart_port *port, int ctl) +{ + /* not possible without fiddling with gpios */ +} + +static void efm32_uart_rx_chars(struct efm32_uart_port *efm_port, + struct tty_struct *tty) +{ + struct uart_port *port = &efm_port->port; + + while (efm32_uart_read32(efm_port, UARTn_STATUS) & + UARTn_STATUS_RXDATAV) { + u32 rxdata = efm32_uart_read32(efm_port, UARTn_RXDATAX); + int flag = 0; + + /* + * This is a reserved bit and I only saw it read as 0. But to be + * sure not to be confused too much by new devices adhere to the + * warning in the reference manual that reserverd bits might + * read as 1 in the future. + */ + rxdata &= ~SW_UARTn_RXDATAX_BERR; + + port->icount.rx++; + + if ((rxdata & UARTn_RXDATAX_FERR) && + !(rxdata & UARTn_RXDATAX_RXDATA__MASK)) { + rxdata |= SW_UARTn_RXDATAX_BERR; + port->icount.brk++; + if (uart_handle_break(port)) + continue; + } else if (rxdata & UARTn_RXDATAX_PERR) + port->icount.parity++; + else if (rxdata & UARTn_RXDATAX_FERR) + port->icount.frame++; + + rxdata &= port->read_status_mask; + + if (rxdata & SW_UARTn_RXDATAX_BERR) + flag = TTY_BREAK; + else if (rxdata & UARTn_RXDATAX_PERR) + flag = TTY_PARITY; + else if (rxdata & UARTn_RXDATAX_FERR) + flag = TTY_FRAME; + else if (uart_handle_sysrq_char(port, + rxdata & UARTn_RXDATAX_RXDATA__MASK)) + continue; + + if (tty && (rxdata & port->ignore_status_mask) == 0) + tty_insert_flip_char(tty, + rxdata & UARTn_RXDATAX_RXDATA__MASK, flag); + } +} + +static irqreturn_t efm32_uart_rxirq(int irq, void *data) +{ + struct efm32_uart_port *efm_port = data; + u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); + int handled = IRQ_NONE; + struct uart_port *port = &efm_port->port; + struct tty_struct *tty; + + spin_lock(&port->lock); + + tty = tty_kref_get(port->state->port.tty); + + if (irqflag & UARTn_IF_RXDATAV) { + efm32_uart_write32(efm_port, UARTn_IF_RXDATAV, UARTn_IFC); + efm32_uart_rx_chars(efm_port, tty); + + handled = IRQ_HANDLED; + } + + if (irqflag & UARTn_IF_RXOF) { + efm32_uart_write32(efm_port, UARTn_IF_RXOF, UARTn_IFC); + port->icount.overrun++; + if (tty) + tty_insert_flip_char(tty, 0, TTY_OVERRUN); + + handled = IRQ_HANDLED; + } + + if (tty) { + tty_flip_buffer_push(tty); + tty_kref_put(tty); + } + + spin_unlock(&port->lock); + + return handled; +} + +static irqreturn_t efm32_uart_txirq(int irq, void *data) +{ + struct efm32_uart_port *efm_port = data; + u32 irqflag = efm32_uart_read32(efm_port, UARTn_IF); + + /* TXBL doesn't need to be cleared */ + if (irqflag & UARTn_IF_TXC) + efm32_uart_write32(efm_port, UARTn_IF_TXC, UARTn_IFC); + + if (irqflag & (UARTn_IF_TXC | UARTn_IF_TXBL)) { + efm32_uart_tx_chars(efm_port); + return IRQ_HANDLED; + } else + return IRQ_NONE; +} + +static int efm32_uart_startup(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + u32 location = 0; + struct efm32_uart_pdata *pdata = dev_get_platdata(port->dev); + int ret; + + if (pdata) + location = UARTn_ROUTE_LOCATION(pdata->location); + + ret = clk_enable(efm_port->clk); + if (ret) { + efm_debug(efm_port, "failed to enable clk\n"); + goto err_clk_enable; + } + port->uartclk = clk_get_rate(efm_port->clk); + + /* Enable pins at configured location */ + efm32_uart_write32(efm_port, location | UARTn_ROUTE_RXPEN | UARTn_ROUTE_TXPEN, + UARTn_ROUTE); + + ret = request_irq(port->irq, efm32_uart_rxirq, 0, + DRIVER_NAME, efm_port); + if (ret) { + efm_debug(efm_port, "failed to register rxirq\n"); + goto err_request_irq_rx; + } + + /* disable all irqs */ + efm32_uart_write32(efm_port, 0, UARTn_IEN); + + ret = request_irq(efm_port->txirq, efm32_uart_txirq, 0, + DRIVER_NAME, efm_port); + if (ret) { + efm_debug(efm_port, "failed to register txirq\n"); + free_irq(port->irq, efm_port); +err_request_irq_rx: + + clk_disable(efm_port->clk); + } else { + efm32_uart_write32(efm_port, + UARTn_IF_RXDATAV | UARTn_IF_RXOF, UARTn_IEN); + efm32_uart_write32(efm_port, UARTn_CMD_RXEN, UARTn_CMD); + } + +err_clk_enable: + return ret; +} + +static void efm32_uart_shutdown(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + efm32_uart_write32(efm_port, 0, UARTn_IEN); + free_irq(port->irq, efm_port); + + clk_disable(efm_port->clk); +} + +static void efm32_uart_set_termios(struct uart_port *port, + struct ktermios *new, struct ktermios *old) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + unsigned long flags; + unsigned baud; + u32 clkdiv; + u32 frame = 0; + + /* no modem control lines */ + new->c_cflag &= ~(CRTSCTS | CMSPAR); + + baud = uart_get_baud_rate(port, new, old, + DIV_ROUND_CLOSEST(port->uartclk, 16 * 8192), + DIV_ROUND_CLOSEST(port->uartclk, 16)); + + switch (new->c_cflag & CSIZE) { + case CS5: + frame |= UARTn_FRAME_DATABITS(5); + break; + case CS6: + frame |= UARTn_FRAME_DATABITS(6); + break; + case CS7: + frame |= UARTn_FRAME_DATABITS(7); + break; + case CS8: + frame |= UARTn_FRAME_DATABITS(8); + break; + } + + if (new->c_cflag & CSTOPB) + /* the receiver only verifies the first stop bit */ + frame |= UARTn_FRAME_STOPBITS_TWO; + else + frame |= UARTn_FRAME_STOPBITS_ONE; + + if (new->c_cflag & PARENB) { + if (new->c_cflag & PARODD) + frame |= UARTn_FRAME_PARITY_ODD; + else + frame |= UARTn_FRAME_PARITY_EVEN; + } else + frame |= UARTn_FRAME_PARITY_NONE; + + /* + * the 6 lowest bits of CLKDIV are dc, bit 6 has value 0.25. + * port->uartclk <= 14e6, so 4 * port->uartclk doesn't overflow. + */ + clkdiv = (DIV_ROUND_CLOSEST(4 * port->uartclk, 16 * baud) - 4) << 6; + + spin_lock_irqsave(&port->lock, flags); + + efm32_uart_write32(efm_port, + UARTn_CMD_TXDIS | UARTn_CMD_RXDIS, UARTn_CMD); + + port->read_status_mask = UARTn_RXDATAX_RXDATA__MASK; + if (new->c_iflag & INPCK) + port->read_status_mask |= + UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; + if (new->c_iflag & (BRKINT | PARMRK)) + port->read_status_mask |= SW_UARTn_RXDATAX_BERR; + + port->ignore_status_mask = 0; + if (new->c_iflag & IGNPAR) + port->ignore_status_mask |= + UARTn_RXDATAX_FERR | UARTn_RXDATAX_PERR; + if (new->c_iflag & IGNBRK) + port->ignore_status_mask |= SW_UARTn_RXDATAX_BERR; + + uart_update_timeout(port, new->c_cflag, baud); + + efm32_uart_write32(efm_port, UARTn_CTRL_TXBIL, UARTn_CTRL); + efm32_uart_write32(efm_port, frame, UARTn_FRAME); + efm32_uart_write32(efm_port, clkdiv, UARTn_CLKDIV); + + efm32_uart_write32(efm_port, UARTn_CMD_TXEN | UARTn_CMD_RXEN, + UARTn_CMD); + + spin_unlock_irqrestore(&port->lock, flags); +} + +static const char *efm32_uart_type(struct uart_port *port) +{ + return port->type == PORT_EFMUART ? "efm32-uart" : NULL; +} + +static void efm32_uart_release_port(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + + clk_unprepare(efm_port->clk); + clk_put(efm_port->clk); + iounmap(port->membase); +} + +static int efm32_uart_request_port(struct uart_port *port) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + int ret; + + port->membase = ioremap(port->mapbase, 60); + if (!efm_port->port.membase) { + ret = -ENOMEM; + efm_debug(efm_port, "failed to remap\n"); + goto err_ioremap; + } + + efm_port->clk = clk_get(port->dev, NULL); + if (IS_ERR(efm_port->clk)) { + ret = PTR_ERR(efm_port->clk); + efm_debug(efm_port, "failed to get clock\n"); + goto err_clk_get; + } + + ret = clk_prepare(efm_port->clk); + if (ret) { + clk_put(efm_port->clk); +err_clk_get: + + iounmap(port->membase); +err_ioremap: + return ret; + } + return 0; +} + +static void efm32_uart_config_port(struct uart_port *port, int type) +{ + if (type & UART_CONFIG_TYPE && + !efm32_uart_request_port(port)) + port->type = PORT_EFMUART; +} + +static int efm32_uart_verify_port(struct uart_port *port, + struct serial_struct *serinfo) +{ + int ret = 0; + + if (serinfo->type != PORT_UNKNOWN && serinfo->type != PORT_EFMUART) + ret = -EINVAL; + + return ret; +} + +static struct uart_ops efm32_uart_pops = { + .tx_empty = efm32_uart_tx_empty, + .set_mctrl = efm32_uart_set_mctrl, + .get_mctrl = efm32_uart_get_mctrl, + .stop_tx = efm32_uart_stop_tx, + .start_tx = efm32_uart_start_tx, + .stop_rx = efm32_uart_stop_rx, + .enable_ms = efm32_uart_enable_ms, + .break_ctl = efm32_uart_break_ctl, + .startup = efm32_uart_startup, + .shutdown = efm32_uart_shutdown, + .set_termios = efm32_uart_set_termios, + .type = efm32_uart_type, + .release_port = efm32_uart_release_port, + .request_port = efm32_uart_request_port, + .config_port = efm32_uart_config_port, + .verify_port = efm32_uart_verify_port, +}; + +static struct efm32_uart_port *efm32_uart_ports[5]; + +#ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE +static void efm32_uart_console_putchar(struct uart_port *port, int ch) +{ + struct efm32_uart_port *efm_port = to_efm_port(port); + unsigned int timeout = 0x400; + u32 status; + + while (1) { + status = efm32_uart_read32(efm_port, UARTn_STATUS); + + if (status & UARTn_STATUS_TXBL) + break; + if (!timeout--) + return; + } + efm32_uart_write32(efm_port, ch, UARTn_TXDATA); +} + +static void efm32_uart_console_write(struct console *co, const char *s, + unsigned int count) +{ + struct efm32_uart_port *efm_port = efm32_uart_ports[co->index]; + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + unsigned int timeout = 0x400; + + if (!(status & UARTn_STATUS_TXENS)) + efm32_uart_write32(efm_port, UARTn_CMD_TXEN, UARTn_CMD); + + uart_console_write(&efm_port->port, s, count, + efm32_uart_console_putchar); + + /* Wait for the transmitter to become empty */ + while (1) { + u32 status = efm32_uart_read32(efm_port, UARTn_STATUS); + if (status & UARTn_STATUS_TXC) + break; + if (!timeout--) + break; + } + + if (!(status & UARTn_STATUS_TXENS)) + efm32_uart_write32(efm_port, UARTn_CMD_TXDIS, UARTn_CMD); +} + +static void efm32_uart_console_get_options(struct efm32_uart_port *efm_port, + int *baud, int *parity, int *bits) +{ + u32 ctrl = efm32_uart_read32(efm_port, UARTn_CTRL); + u32 route, clkdiv, frame; + + if (ctrl & UARTn_CTRL_SYNC) + /* not operating in async mode */ + return; + + route = efm32_uart_read32(efm_port, UARTn_ROUTE); + if (!(route & UARTn_ROUTE_TXPEN)) + /* tx pin not routed */ + return; + + clkdiv = efm32_uart_read32(efm_port, UARTn_CLKDIV); + + *baud = DIV_ROUND_CLOSEST(4 * efm_port->port.uartclk, + 16 * (4 + (clkdiv >> 6))); + + frame = efm32_uart_read32(efm_port, UARTn_FRAME); + if (frame & UARTn_FRAME_PARITY_ODD) + *parity = 'o'; + else if (frame & UARTn_FRAME_PARITY_EVEN) + *parity = 'e'; + else + *parity = 'n'; + + *bits = (frame & UARTn_FRAME_DATABITS__MASK) - + UARTn_FRAME_DATABITS(4) + 4; + + efm_debug(efm_port, "get_opts: options=%d%c%d\n", + *baud, *parity, *bits); +} + +static int efm32_uart_console_setup(struct console *co, char *options) +{ + struct efm32_uart_port *efm_port; + int baud = 115200; + int bits = 8; + int parity = 'n'; + int flow = 'n'; + int ret; + + if (co->index < 0 || co->index >= ARRAY_SIZE(efm32_uart_ports)) { + unsigned i; + for (i = 0; i < ARRAY_SIZE(efm32_uart_ports); ++i) { + if (efm32_uart_ports[i]) { + pr_warn("efm32-console: fall back to console index %u (from %hhi)\n", + i, co->index); + co->index = i; + break; + } + } + } + + efm_port = efm32_uart_ports[co->index]; + if (!efm_port) { + pr_warn("efm32-console: No port at %d\n", co->index); + return -ENODEV; + } + + ret = clk_prepare(efm_port->clk); + if (ret) { + dev_warn(efm_port->port.dev, + "console: clk_prepare failed: %d\n", ret); + return ret; + } + + efm_port->port.uartclk = clk_get_rate(efm_port->clk); + + if (options) + uart_parse_options(options, &baud, &parity, &bits, &flow); + else + efm32_uart_console_get_options(efm_port, + &baud, &parity, &bits); + + return uart_set_options(&efm_port->port, co, baud, parity, bits, flow); +} + +static struct uart_driver efm32_uart_reg; + +static struct console efm32_uart_console = { + .name = DEV_NAME, + .write = efm32_uart_console_write, + .device = uart_console_device, + .setup = efm32_uart_console_setup, + .flags = CON_PRINTBUFFER, + .index = -1, + .data = &efm32_uart_reg, +}; + +#else +#define efm32_uart_console (*(struct console *)NULL) +#endif /* ifdef CONFIG_SERIAL_EFM32_UART_CONSOLE / else */ + +static struct uart_driver efm32_uart_reg = { + .owner = THIS_MODULE, + .driver_name = DRIVER_NAME, + .dev_name = DEV_NAME, + .nr = ARRAY_SIZE(efm32_uart_ports), + .cons = &efm32_uart_console, +}; + +static int efm32_uart_probe_dt(struct platform_device *pdev, + struct efm32_uart_port *efm_port) +{ + struct device_node *np = pdev->dev.of_node; + int ret; + + if (!np) + return 1; + + ret = of_alias_get_id(np, "serial"); + if (ret < 0) { + dev_err(&pdev->dev, "failed to get alias id: %d\n", ret); + return ret; + } else { + efm_port->port.line = ret; + return 0; + } + +} + +static int __devinit efm32_uart_probe(struct platform_device *pdev) +{ + struct efm32_uart_port *efm_port; + struct resource *res; + int ret; + + efm_port = kzalloc(sizeof(*efm_port), GFP_KERNEL); + if (!efm_port) { + dev_dbg(&pdev->dev, "failed to allocate private data\n"); + return -ENOMEM; + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENODEV; + dev_dbg(&pdev->dev, "failed to determine base address\n"); + goto err_get_base; + } + + if (resource_size(res) < 60) { + ret = -EINVAL; + dev_dbg(&pdev->dev, "memory resource too small\n"); + goto err_too_small; + } + + ret = platform_get_irq(pdev, 0); + if (ret <= 0) { + dev_dbg(&pdev->dev, "failed to get rx irq\n"); + goto err_get_rxirq; + } + + efm_port->port.irq = ret; + + ret = platform_get_irq(pdev, 1); + if (ret <= 0) + ret = efm_port->port.irq + 1; + + efm_port->txirq = ret; + + efm_port->port.dev = &pdev->dev; + efm_port->port.mapbase = res->start; + efm_port->port.type = PORT_EFMUART; + efm_port->port.iotype = UPIO_MEM32; + efm_port->port.fifosize = 2; + efm_port->port.ops = &efm32_uart_pops; + efm_port->port.flags = UPF_BOOT_AUTOCONF; + + ret = efm32_uart_probe_dt(pdev, efm_port); + if (ret > 0) + /* not created by device tree */ + efm_port->port.line = pdev->id; + + if (efm_port->port.line >= 0 && + efm_port->port.line < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[efm_port->port.line] = efm_port; + + ret = uart_add_one_port(&efm32_uart_reg, &efm_port->port); + if (ret) { + dev_dbg(&pdev->dev, "failed to add port: %d\n", ret); + + if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[pdev->id] = NULL; +err_get_rxirq: +err_too_small: +err_get_base: + kfree(efm_port); + } else { + platform_set_drvdata(pdev, efm_port); + dev_dbg(&pdev->dev, "\\o/\n"); + } + + return ret; +} + +static int __devexit efm32_uart_remove(struct platform_device *pdev) +{ + struct efm32_uart_port *efm_port = platform_get_drvdata(pdev); + + platform_set_drvdata(pdev, NULL); + + uart_remove_one_port(&efm32_uart_reg, &efm_port->port); + + if (pdev->id >= 0 && pdev->id < ARRAY_SIZE(efm32_uart_ports)) + efm32_uart_ports[pdev->id] = NULL; + + kfree(efm_port); + + return 0; +} + +static struct of_device_id efm32_uart_dt_ids[] = { + { + .compatible = "efm32,uart", + }, { + /* sentinel */ + } +}; +MODULE_DEVICE_TABLE(of, efm32_uart_dt_ids); + +static struct platform_driver efm32_uart_driver = { + .probe = efm32_uart_probe, + .remove = __devexit_p(efm32_uart_remove), + + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = efm32_uart_dt_ids, + }, +}; + +static int __init efm32_uart_init(void) +{ + int ret; + + ret = uart_register_driver(&efm32_uart_reg); + if (ret) + return ret; + + ret = platform_driver_register(&efm32_uart_driver); + if (ret) + uart_unregister_driver(&efm32_uart_reg); + + pr_info("EFM32 UART/USART driver\n"); + + return ret; +} +module_init(efm32_uart_init); + +static void __exit efm32_uart_exit(void) +{ + platform_driver_unregister(&efm32_uart_driver); + uart_unregister_driver(&efm32_uart_reg); +} + +MODULE_AUTHOR("Uwe Kleine-Koenig "); +MODULE_DESCRIPTION("EFM32 UART/USART driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:" DRIVER_NAME); diff --git a/include/linux/platform_data/efm32-uart.h b/include/linux/platform_data/efm32-uart.h new file mode 100644 index 00000000000..ed0e975b3c5 --- /dev/null +++ b/include/linux/platform_data/efm32-uart.h @@ -0,0 +1,18 @@ +/* + * + * + */ +#ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__ +#define __LINUX_PLATFORM_DATA_EFM32_UART_H__ + +#include + +/** + * struct efm32_uart_pdata + * @location: pinmux location for the I/O pins (to be written to the ROUTE + * register) + */ +struct efm32_uart_pdata { + u8 location; +}; +#endif /* ifndef __LINUX_PLATFORM_DATA_EFM32_UART_H__ */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index c91ace70c21..585bfd03d2e 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -210,6 +210,8 @@ /* Atheros AR933X SoC */ #define PORT_AR933X 99 +/* Energy Micro efm32 SoC */ +#define PORT_EFMUART 100 #ifdef __KERNEL__ -- cgit v1.2.3-70-g09d2 From e0d21178ceb06f5bfa81a5697f68384f74af054a Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Dec 2011 14:07:31 +0000 Subject: PCMCIA: soc_common: move common initialization into soc_common Move common socket initialization into soc_common.c. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- drivers/pcmcia/pxa2xx_base.c | 5 +---- drivers/pcmcia/sa1111_generic.c | 4 +--- drivers/pcmcia/sa11xx_base.c | 5 +---- drivers/pcmcia/soc_common.c | 10 ++++++++++ drivers/pcmcia/soc_common.h | 3 ++- 5 files changed, 15 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index a87e2728b2c..18474f046e7 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -318,10 +318,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) skt->nr = ops->first + i; skt->clk = clk; - skt->ops = ops; - skt->socket.owner = ops->owner; - skt->socket.dev.parent = &dev->dev; - skt->socket.pci_irq = NO_IRQ; + soc_pcmcia_init_one(skt, ops, &dev->dev); ret = pxa2xx_drv_pcmcia_add_one(skt); if (ret) diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index 59866905ea3..7d6d3d423ef 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -141,9 +141,7 @@ int sa1111_pcmcia_add(struct sa1111_dev *dev, struct pcmcia_low_level *ops, return -ENOMEM; s->soc.nr = ops->first + i; - s->soc.ops = ops; - s->soc.socket.owner = ops->owner; - s->soc.socket.dev.parent = &dev->dev; + soc_pcmcia_init_one(&s->soc, ops, &dev->dev); s->soc.socket.pci_irq = s->soc.nr ? dev->irq[IDX_IRQ_S0_READY_NINT] : dev->irq[IDX_IRQ_S1_READY_NINT]; diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 0c62fe31a40..a3ee89a6dd0 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -236,10 +236,7 @@ int sa11xx_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops, skt = &sinfo->skt[i]; skt->nr = first + i; - skt->ops = ops; - skt->socket.owner = ops->owner; - skt->socket.dev.parent = dev; - skt->socket.pci_irq = NO_IRQ; + soc_pcmcia_init_one(skt, ops, dev); ret = sa11xx_drv_pcmcia_add_one(skt); if (ret) diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index a0a9c2aa8d7..84d90d5220c 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -635,6 +635,16 @@ module_exit(soc_pcmcia_cpufreq_unregister); #endif +void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, + struct pcmcia_low_level *ops, struct device *dev) +{ + skt->ops = ops; + skt->socket.owner = ops->owner; + skt->socket.dev.parent = dev; + skt->socket.pci_irq = NO_IRQ; +} +EXPORT_SYMBOL(soc_pcmcia_init_one); + void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) { mutex_lock(&soc_pcmcia_sockets_lock); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 9daa73615c8..3ff7ead11b1 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -133,7 +133,8 @@ extern void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia extern void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt, struct pcmcia_irqs *irqs, int nr); extern void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *, struct soc_pcmcia_timing *); - +void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, + struct pcmcia_low_level *ops, struct device *dev); void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt); int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt); -- cgit v1.2.3-70-g09d2 From d9dc878769f521f494d1617d7cd0c92073df75d8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 19 Dec 2011 22:00:22 +0000 Subject: PCMCIA: soc_common: add GPIO support for card status signals Add GPIO support for reading the card status (card detect, ready, battery voltage detect) signals into soc_common code. As we want interrupts from these GPIOs, this takes over the old irq handling infrastructure for card status signals, which will now be managed entirely by the soc_common code. Acked-by: Dominik Brodowski Signed-off-by: Russell King --- drivers/pcmcia/soc_common.c | 120 ++++++++++++++++++++++++++++++++++++++++++-- drivers/pcmcia/soc_common.h | 10 ++++ 2 files changed, 127 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index 84d90d5220c..09a9a52ad65 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -49,6 +50,8 @@ #include "soc_common.h" +static irqreturn_t soc_common_pcmcia_interrupt(int irq, void *dev); + #ifdef CONFIG_PCMCIA_DEBUG static int pc_debug; @@ -104,6 +107,93 @@ void soc_common_pcmcia_get_timing(struct soc_pcmcia_socket *skt, } EXPORT_SYMBOL(soc_common_pcmcia_get_timing); +static void __soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt, + unsigned int nr) +{ + unsigned int i; + + for (i = 0; i < nr; i++) { + if (skt->stat[i].irq) + free_irq(skt->stat[i].irq, skt); + if (gpio_is_valid(skt->stat[i].gpio)) + gpio_free(skt->stat[i].gpio); + } + + if (skt->ops->hw_shutdown) + skt->ops->hw_shutdown(skt); +} + +static void soc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) +{ + __soc_pcmcia_hw_shutdown(skt, ARRAY_SIZE(skt->stat)); +} + +static int soc_pcmcia_hw_init(struct soc_pcmcia_socket *skt) +{ + int ret = 0, i; + + if (skt->ops->hw_init) { + ret = skt->ops->hw_init(skt); + if (ret) + return ret; + } + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) { + if (gpio_is_valid(skt->stat[i].gpio)) { + int irq; + + ret = gpio_request_one(skt->stat[i].gpio, GPIOF_IN, + skt->stat[i].name); + if (ret) { + __soc_pcmcia_hw_shutdown(skt, i); + return ret; + } + + irq = gpio_to_irq(skt->stat[i].gpio); + + if (i == SOC_STAT_RDY) + skt->socket.pci_irq = irq; + else + skt->stat[i].irq = irq; + } + + if (skt->stat[i].irq) { + ret = request_irq(skt->stat[i].irq, + soc_common_pcmcia_interrupt, + IRQF_TRIGGER_NONE, + skt->stat[i].name, skt); + if (ret) { + if (gpio_is_valid(skt->stat[i].gpio)) + gpio_free(skt->stat[i].gpio); + __soc_pcmcia_hw_shutdown(skt, i); + return ret; + } + } + } + + return ret; +} + +static void soc_pcmcia_hw_enable(struct soc_pcmcia_socket *skt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + if (skt->stat[i].irq) { + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_RISING); + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_EDGE_BOTH); + } +} + +static void soc_pcmcia_hw_disable(struct soc_pcmcia_socket *skt) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + if (skt->stat[i].irq) + irq_set_irq_type(skt->stat[i].irq, IRQ_TYPE_NONE); +} + static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) { struct pcmcia_state state; @@ -111,6 +201,22 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) memset(&state, 0, sizeof(struct pcmcia_state)); + /* Make battery voltage state report 'good' */ + state.bvd1 = 1; + state.bvd2 = 1; + + /* CD is active low by default */ + if (gpio_is_valid(skt->stat[SOC_STAT_CD].gpio)) + state.detect = !gpio_get_value(skt->stat[SOC_STAT_CD].gpio); + + /* RDY and BVD are active high by default */ + if (gpio_is_valid(skt->stat[SOC_STAT_RDY].gpio)) + state.ready = !!gpio_get_value(skt->stat[SOC_STAT_RDY].gpio); + if (gpio_is_valid(skt->stat[SOC_STAT_BVD1].gpio)) + state.bvd1 = !!gpio_get_value(skt->stat[SOC_STAT_BVD1].gpio); + if (gpio_is_valid(skt->stat[SOC_STAT_BVD2].gpio)) + state.bvd2 = !!gpio_get_value(skt->stat[SOC_STAT_BVD2].gpio); + skt->ops->socket_state(skt, &state); stat = state.detect ? SS_DETECT : 0; @@ -188,6 +294,7 @@ static int soc_common_pcmcia_sock_init(struct pcmcia_socket *sock) debug(skt, 2, "initializing socket\n"); if (skt->ops->socket_init) skt->ops->socket_init(skt); + soc_pcmcia_hw_enable(skt); return 0; } @@ -207,6 +314,7 @@ static int soc_common_pcmcia_suspend(struct pcmcia_socket *sock) debug(skt, 2, "suspending socket\n"); + soc_pcmcia_hw_disable(skt); if (skt->ops->socket_suspend) skt->ops->socket_suspend(skt); @@ -638,10 +746,15 @@ module_exit(soc_pcmcia_cpufreq_unregister); void soc_pcmcia_init_one(struct soc_pcmcia_socket *skt, struct pcmcia_low_level *ops, struct device *dev) { + int i; + skt->ops = ops; skt->socket.owner = ops->owner; skt->socket.dev.parent = dev; skt->socket.pci_irq = NO_IRQ; + + for (i = 0; i < ARRAY_SIZE(skt->stat); i++) + skt->stat[i].gpio = -EINVAL; } EXPORT_SYMBOL(soc_pcmcia_init_one); @@ -652,8 +765,9 @@ void soc_pcmcia_remove_one(struct soc_pcmcia_socket *skt) pcmcia_unregister_socket(&skt->socket); - skt->ops->hw_shutdown(skt); + soc_pcmcia_hw_shutdown(skt); + /* should not be required; violates some lowlevel drivers */ soc_common_pcmcia_config_skt(skt, &dead_socket); list_del(&skt->node); @@ -710,7 +824,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) */ skt->ops->set_timing(skt); - ret = skt->ops->hw_init(skt); + ret = soc_pcmcia_hw_init(skt); if (ret) goto out_err_6; @@ -743,7 +857,7 @@ int soc_pcmcia_add_one(struct soc_pcmcia_socket *skt) pcmcia_unregister_socket(&skt->socket); out_err_7: - skt->ops->hw_shutdown(skt); + soc_pcmcia_hw_shutdown(skt); out_err_6: list_del(&skt->node); mutex_unlock(&soc_pcmcia_sockets_lock); diff --git a/drivers/pcmcia/soc_common.h b/drivers/pcmcia/soc_common.h index 3ff7ead11b1..ebdfa6c1630 100644 --- a/drivers/pcmcia/soc_common.h +++ b/drivers/pcmcia/soc_common.h @@ -50,6 +50,16 @@ struct soc_pcmcia_socket { struct resource res_attr; void __iomem *virt_io; + struct { + int gpio; + unsigned int irq; + const char *name; + } stat[4]; +#define SOC_STAT_CD 0 /* Card detect */ +#define SOC_STAT_BVD1 1 /* BATDEAD / IOSTSCHG */ +#define SOC_STAT_BVD2 2 /* BATWARN / IOSPKR */ +#define SOC_STAT_RDY 3 /* Ready / Interrupt */ + unsigned int irq_state; struct timer_list poll_timer; -- cgit v1.2.3-70-g09d2 From c85c21ad1fe18daf26bfe8684df974d88cec50b7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 26 Jan 2012 16:25:55 -0500 Subject: e1000e: Need to include vmalloc.h Otherwise (on sparc64): drivers/net/ethernet/intel/e1000e/ethtool.c:657:3: error: implicit declaration of function 'vmalloc' [-Werror=implicit-function-declaration] Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/e1000e/ethtool.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index ffb6c14cbbb..1ea317f1adc 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "e1000.h" -- cgit v1.2.3-70-g09d2 From e332bcb3d149644c344ee5fdf1f6e4ac39e9d9a3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 01:22:51 +0000 Subject: sfc: Remove fallback for invalid permanent MAC address By the time we look at the MAC address in efx_probe_port(), either the driver or the firmware has already validated the board configuration. The possibility of having an invalid MAC address just isn't worth considering. It certainly isn't worth having a compile-time option for this. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index d7301d2e81a..eff5d300aa0 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -122,15 +122,6 @@ static int napi_weight = 64; */ static unsigned int efx_monitor_interval = 1 * HZ; -/* This controls whether or not the driver will initialise devices - * with invalid MAC addresses stored in the EEPROM or flash. If true, - * such devices will be initialised with a random locally-generated - * MAC address. This allows for loading the sfc_mtd driver to - * reprogram the flash, even if the flash contents (including the MAC - * address) have previously been erased. - */ -static unsigned int allow_bad_hwaddr; - /* Initial interrupt moderation settings. They can be modified after * module load with ethtool. * @@ -916,7 +907,6 @@ static void efx_mac_work(struct work_struct *data) static int efx_probe_port(struct efx_nic *efx) { - unsigned char *perm_addr; int rc; netif_dbg(efx, probe, efx->net_dev, "create port\n"); @@ -929,28 +919,10 @@ static int efx_probe_port(struct efx_nic *efx) if (rc) return rc; - /* Sanity check MAC address */ - perm_addr = efx->net_dev->perm_addr; - if (is_valid_ether_addr(perm_addr)) { - memcpy(efx->net_dev->dev_addr, perm_addr, ETH_ALEN); - } else { - netif_err(efx, probe, efx->net_dev, "invalid MAC address %pM\n", - perm_addr); - if (!allow_bad_hwaddr) { - rc = -EINVAL; - goto err; - } - random_ether_addr(efx->net_dev->dev_addr); - netif_info(efx, probe, efx->net_dev, - "using locally-generated MAC %pM\n", - efx->net_dev->dev_addr); - } + /* Initialise MAC address to permanent address */ + memcpy(efx->net_dev->dev_addr, efx->net_dev->perm_addr, ETH_ALEN); return 0; - - err: - efx->type->remove_port(efx); - return rc; } static int efx_init_port(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From 3f713bf4dd9f7ef2a2c5e9ec124b3d992a2669db Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 23:39:31 +0000 Subject: sfc: Make handling of MC reboot more reliable When the MC reboots, either as part of a firmware upgrade or due to a bug, it attempts to complete (with an error) any requests that were outstanding before the reboot. Since there is an inherent race condition in checking this, it will also write to a status word in shared memory. If we look at each of these separately, we may detect each reboot twice, resulting in a spurious command failure after a firmware upgrade or frustrating recovery from a firmware bug. Instead, if a request completion indicates a reboot, we must poll and clear the status word. This bug was previously masked by use of an incorrect address for the status word. Fix that, using the definition now included in mcdi_pcol.h. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index 7c405d16692..f16145d9281 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -27,8 +27,6 @@ #define CMD_NOTIFY_PORT1 4 #define CMD_PDU_PORT0 0x008 #define CMD_PDU_PORT1 0x108 -#define REBOOT_FLAG_PORT0 0x3f8 -#define REBOOT_FLAG_PORT1 0x3fc #define MCDI_RPC_TIMEOUT 10 /*seconds */ @@ -36,8 +34,16 @@ (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0) #define MCDI_DOORBELL(efx) \ (efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0) -#define MCDI_REBOOT_FLAG(efx) \ - (efx_port_num(efx) ? REBOOT_FLAG_PORT1 : REBOOT_FLAG_PORT0) +#define MCDI_STATUS(efx) \ + (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST) + +/* A reboot/assertion causes the MCDI status word to be set after the + * command word is set or a REBOOT event is sent. If we notice a reboot + * via these mechanisms then wait 10ms for the status word to be set. */ +#define MCDI_STATUS_DELAY_US 100 +#define MCDI_STATUS_DELAY_COUNT 100 +#define MCDI_STATUS_SLEEP_MS \ + (MCDI_STATUS_DELAY_US * MCDI_STATUS_DELAY_COUNT / 1000) #define SEQ_MASK \ EFX_MASK32(EFX_WIDTH(MCDI_HEADER_SEQ)) @@ -210,7 +216,7 @@ out: /* Test and clear MC-rebooted flag for this port/function */ int efx_mcdi_poll_reboot(struct efx_nic *efx) { - unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_REBOOT_FLAG(efx); + unsigned int addr = FR_CZ_MC_TREG_SMEM + MCDI_STATUS(efx); efx_dword_t reg; uint32_t value; @@ -384,6 +390,11 @@ int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, netif_dbg(efx, hw, efx->net_dev, "MC command 0x%x inlen %d failed rc=%d\n", cmd, (int)inlen, -rc); + + if (rc == -EIO || rc == -EINTR) { + msleep(MCDI_STATUS_SLEEP_MS); + efx_mcdi_poll_reboot(efx); + } } efx_mcdi_release(mcdi); @@ -465,10 +476,20 @@ static void efx_mcdi_ev_death(struct efx_nic *efx, int rc) mcdi->resplen = 0; ++mcdi->credits; } - } else + } else { + int count; + /* Nobody was waiting for an MCDI request, so trigger a reset */ efx_schedule_reset(efx, RESET_TYPE_MC_FAILURE); + /* Consume the status word since efx_mcdi_rpc_finish() won't */ + for (count = 0; count < MCDI_STATUS_DELAY_COUNT; ++count) { + if (efx_mcdi_poll_reboot(efx)) + break; + udelay(MCDI_STATUS_DELAY_US); + } + } + spin_unlock(&mcdi->iface_lock); } -- cgit v1.2.3-70-g09d2 From 788ec41cc843f12e8d0eba5f2b37af18b76654a5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 20 Dec 2011 23:52:02 +0000 Subject: sfc: Use new names for MC shared memory layout constants These are defined alongside the firmware protocol in mcdi_pcol.h. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index f16145d9281..e5837a6485a 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -22,18 +22,12 @@ ************************************************************************** */ -/* Software-defined structure to the shared-memory */ -#define CMD_NOTIFY_PORT0 0 -#define CMD_NOTIFY_PORT1 4 -#define CMD_PDU_PORT0 0x008 -#define CMD_PDU_PORT1 0x108 - #define MCDI_RPC_TIMEOUT 10 /*seconds */ #define MCDI_PDU(efx) \ - (efx_port_num(efx) ? CMD_PDU_PORT1 : CMD_PDU_PORT0) + (efx_port_num(efx) ? MC_SMEM_P1_PDU_OFST : MC_SMEM_P0_PDU_OFST) #define MCDI_DOORBELL(efx) \ - (efx_port_num(efx) ? CMD_NOTIFY_PORT1 : CMD_NOTIFY_PORT0) + (efx_port_num(efx) ? MC_SMEM_P1_DOORBELL_OFST : MC_SMEM_P0_DOORBELL_OFST) #define MCDI_STATUS(efx) \ (efx_port_num(efx) ? MC_SMEM_P1_STATUS_OFST : MC_SMEM_P0_STATUS_OFST) @@ -83,7 +77,7 @@ static void efx_mcdi_copyin(struct efx_nic *efx, unsigned cmd, u32 xflags, seqno; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); - BUG_ON(inlen & 3 || inlen >= 0x100); + BUG_ON(inlen & 3 || inlen >= MC_SMEM_PDU_LEN); seqno = mcdi->seqno & SEQ_MASK; xflags = 0; @@ -117,7 +111,7 @@ static void efx_mcdi_copyout(struct efx_nic *efx, u8 *outbuf, size_t outlen) int i; BUG_ON(atomic_read(&mcdi->state) == MCDI_STATE_QUIESCENT); - BUG_ON(outlen & 3 || outlen >= 0x100); + BUG_ON(outlen & 3 || outlen >= MC_SMEM_PDU_LEN); for (i = 0; i < outlen; i += 4) *((__le32 *)(outbuf + i)) = _efx_readd(efx, pdu + 4 + i); -- cgit v1.2.3-70-g09d2 From 1cb345220f135dcca24f01cc04cbb97a8242d419 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 2 Sep 2011 23:23:00 +0100 Subject: sfc: Hold efx_nic::stats_lock while reading efx_nic::mac_stats efx_nic::stats_lock is used to serialise stats updates, but each reader was dropping it before it finished reading efx_nic::mac_stats. If there were concurrent stats reads using procfs, or one using procfs and one using ethtool, an update could race with a read. On a 32-bit system, the reader could see word-tearing of 64-bit stats (32 bits of the old value and 32 bits of the new). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 4 +++- drivers/net/ethernet/sfc/ethtool.c | 7 +++++-- drivers/net/ethernet/sfc/net_driver.h | 1 + 3 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index eff5d300aa0..8f4cbb642bf 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1743,8 +1743,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc struct efx_mac_stats *mac_stats = &efx->mac_stats; spin_lock_bh(&efx->stats_lock); + efx->type->update_stats(efx); - spin_unlock_bh(&efx->stats_lock); stats->rx_packets = mac_stats->rx_packets; stats->tx_packets = mac_stats->tx_packets; @@ -1768,6 +1768,8 @@ static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struc stats->tx_errors = (stats->tx_window_errors + mac_stats->tx_bad); + spin_unlock_bh(&efx->stats_lock); + return stats; } diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 52c9ee4c8aa..55a25b14d30 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -489,13 +489,14 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, const struct efx_ethtool_stat *stat; struct efx_channel *channel; struct efx_tx_queue *tx_queue; - struct rtnl_link_stats64 temp; int i; EFX_BUG_ON_PARANOID(stats->n_stats != EFX_ETHTOOL_NUM_STATS); + spin_lock_bh(&efx->stats_lock); + /* Update MAC and NIC statistics */ - dev_get_stats(net_dev, &temp); + efx->type->update_stats(efx); /* Fill detailed statistics buffer */ for (i = 0; i < EFX_ETHTOOL_NUM_STATS; i++) { @@ -525,6 +526,8 @@ static void efx_ethtool_get_stats(struct net_device *net_dev, break; } } + + spin_unlock_bh(&efx->stats_lock); } static void efx_ethtool_self_test(struct net_device *net_dev, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 9353ce80175..b6040141ef7 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -704,6 +704,7 @@ struct efx_filter_state; * can provide. Generic code converts these into a standard * &struct net_device_stats. * @stats_lock: Statistics update lock. Serialises statistics fetches + * and access to @mac_stats. * * This is stored in the private area of the &struct net_device. */ -- cgit v1.2.3-70-g09d2 From 710b208dc2687fdb3370110d54a67fb2288835eb Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 3 Sep 2011 00:15:00 +0100 Subject: sfc: Merge efx_mac_operations into efx_nic_type No NICs need to switch efx_mac_operations at run-time, and the MAC operations are fairly closely bound to NIC types. Move efx_mac_operations::reconfigure to efx_nic_type::reconfigure_mac and efx_mac_operations::check_fault fo efx_nic_type::check_mac_fault. Change callers to call through efx->type or directly if the NIC type is known. Remove efx_mac_operations::update_stats. The implementations for Falcon used to fetch MAC statistics synchronously and this was used by efx_register_netdev() to clear statistics after running self-tests. However, it now only converts statistics that have already been fetched (and that only for Falcon), and the call from efx_register_netdev() has no effect. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 17 ++++++----------- drivers/net/ethernet/sfc/ethtool.c | 4 ++-- drivers/net/ethernet/sfc/falcon.c | 15 ++++++++------- drivers/net/ethernet/sfc/falcon_xmac.c | 13 +++---------- drivers/net/ethernet/sfc/mac.h | 21 --------------------- drivers/net/ethernet/sfc/mcdi.h | 4 ++++ drivers/net/ethernet/sfc/mcdi_mac.c | 12 ++---------- drivers/net/ethernet/sfc/net_driver.h | 21 ++++----------------- drivers/net/ethernet/sfc/nic.h | 3 +++ drivers/net/ethernet/sfc/selftest.c | 2 +- drivers/net/ethernet/sfc/siena.c | 4 ++-- 11 files changed, 35 insertions(+), 81 deletions(-) delete mode 100644 drivers/net/ethernet/sfc/mac.h (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 8f4cbb642bf..1d20e01c6ae 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -900,7 +900,7 @@ static void efx_mac_work(struct work_struct *data) mutex_lock(&efx->mac_lock); if (efx->port_enabled) { efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); } mutex_unlock(&efx->mac_lock); } @@ -941,7 +941,7 @@ static int efx_init_port(struct efx_nic *efx) /* Reconfigure the MAC before creating dma queues (required for * Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */ - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); /* Ensure the PHY advertises the correct flow control settings */ rc = efx->phy_op->reconfigure(efx); @@ -969,7 +969,7 @@ static void efx_start_port(struct efx_nic *efx) /* efx_mac_work() might have been scheduled after efx_stop_port(), * and then cancelled by efx_flush_all() */ efx->type->push_multicast_hash(efx); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); } @@ -1807,7 +1807,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) /* Reconfigure the MAC before enabling the dma queues so that * the RX buffers don't overflow */ net_dev->mtu = new_mtu; - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); efx_init_channels(efx); @@ -1835,7 +1835,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) /* Reconfigure the MAC */ mutex_lock(&efx->mac_lock); - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); return 0; @@ -1949,10 +1949,6 @@ static int efx_register_netdev(struct efx_nic *efx) net_dev->netdev_ops = &efx_netdev_ops; SET_ETHTOOL_OPS(net_dev, &efx_ethtool_ops); - /* Clear MAC statistics */ - efx->mac_op->update_stats(efx); - memset(&efx->mac_stats, 0, sizeof(efx->mac_stats)); - rtnl_lock(); rc = dev_alloc_name(net_dev, net_dev->name); @@ -2069,7 +2065,7 @@ int efx_reset_up(struct efx_nic *efx, enum reset_type method, bool ok) "could not restore PHY settings\n"); } - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); efx_init_channels(efx); efx_restore_filters(efx); @@ -2274,7 +2270,6 @@ static int efx_init_struct(struct efx_nic *efx, const struct efx_nic_type *type, efx->net_dev = net_dev; spin_lock_init(&efx->stats_lock); mutex_init(&efx->mac_lock); - efx->mac_op = type->default_mac_ops; efx->phy_op = &efx_dummy_phy_operations; efx->mdio.dev = net_dev; INIT_WORK(&efx->mac_work, efx_mac_work); diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 55a25b14d30..1a7f7ba27be 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -750,7 +750,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, /* Recover by resetting the EM block */ falcon_stop_nic_stats(efx); falcon_drain_tx_fifo(efx); - efx->mac_op->reconfigure(efx); + falcon_reconfigure_xmac(efx); falcon_start_nic_stats(efx); } else { /* Schedule a reset to recover */ @@ -775,7 +775,7 @@ static int efx_ethtool_set_pauseparam(struct net_device *net_dev, /* Reconfigure the MAC. The PHY *may* generate a link state change event * if the user just changed the advertised capabilities, but there's no * harm doing this twice */ - efx->mac_op->reconfigure(efx); + efx->type->reconfigure_mac(efx); out: mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 5c7548959dd..1a8a316bb53 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -19,7 +19,6 @@ #include "net_driver.h" #include "bitfield.h" #include "efx.h" -#include "mac.h" #include "spi.h" #include "nic.h" #include "regs.h" @@ -613,7 +612,7 @@ static void falcon_stats_complete(struct efx_nic *efx) nic_data->stats_pending = false; if (*nic_data->stats_dma_done == FALCON_STATS_DONE) { rmb(); /* read the done flag before the stats */ - efx->mac_op->update_stats(efx); + falcon_update_stats_xmac(efx); } else { netif_err(efx, hw, efx->net_dev, "timed out waiting for statistics\n"); @@ -670,7 +669,7 @@ static int falcon_reconfigure_port(struct efx_nic *efx) falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); - rc = efx->mac_op->reconfigure(efx); + rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); @@ -1218,7 +1217,7 @@ static void falcon_monitor(struct efx_nic *efx) falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); - rc = efx->mac_op->reconfigure(efx); + rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); @@ -1676,7 +1675,7 @@ static void falcon_update_nic_stats(struct efx_nic *efx) *nic_data->stats_dma_done == FALCON_STATS_DONE) { nic_data->stats_pending = false; rmb(); /* read the done flag before the stats */ - efx->mac_op->update_stats(efx); + falcon_update_stats_xmac(efx); } } @@ -1769,11 +1768,12 @@ const struct efx_nic_type falcon_a1_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .reconfigure_mac = falcon_reconfigure_xmac, + .check_mac_fault = falcon_xmac_check_fault, .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, .test_nvram = falcon_test_nvram, - .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_A1, .mem_map_size = 0x20000, @@ -1811,12 +1811,13 @@ const struct efx_nic_type falcon_b0_nic_type = { .push_irq_moderation = falcon_push_irq_moderation, .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, + .reconfigure_mac = falcon_reconfigure_xmac, + .check_mac_fault = falcon_xmac_check_fault, .get_wol = falcon_get_wol, .set_wol = falcon_set_wol, .resume_wol = efx_port_dummy_op_void, .test_registers = falcon_b0_test_registers, .test_nvram = falcon_test_nvram, - .default_mac_ops = &falcon_xmac_operations, .revision = EFX_REV_FALCON_B0, /* Map everything up to and including the RSS indirection diff --git a/drivers/net/ethernet/sfc/falcon_xmac.c b/drivers/net/ethernet/sfc/falcon_xmac.c index 57434593f07..6106ef15dee 100644 --- a/drivers/net/ethernet/sfc/falcon_xmac.c +++ b/drivers/net/ethernet/sfc/falcon_xmac.c @@ -14,7 +14,6 @@ #include "nic.h" #include "regs.h" #include "io.h" -#include "mac.h" #include "mdio_10g.h" #include "workarounds.h" @@ -270,12 +269,12 @@ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) return mac_up; } -static bool falcon_xmac_check_fault(struct efx_nic *efx) +bool falcon_xmac_check_fault(struct efx_nic *efx) { return !falcon_xmac_link_ok_retry(efx, 5); } -static int falcon_reconfigure_xmac(struct efx_nic *efx) +int falcon_reconfigure_xmac(struct efx_nic *efx) { struct falcon_nic_data *nic_data = efx->nic_data; @@ -290,7 +289,7 @@ static int falcon_reconfigure_xmac(struct efx_nic *efx) return 0; } -static void falcon_update_stats_xmac(struct efx_nic *efx) +void falcon_update_stats_xmac(struct efx_nic *efx) { struct efx_mac_stats *mac_stats = &efx->mac_stats; @@ -361,9 +360,3 @@ void falcon_poll_xmac(struct efx_nic *efx) nic_data->xmac_poll_required = !falcon_xmac_link_ok_retry(efx, 1); falcon_ack_status_intr(efx); } - -const struct efx_mac_operations falcon_xmac_operations = { - .reconfigure = falcon_reconfigure_xmac, - .update_stats = falcon_update_stats_xmac, - .check_fault = falcon_xmac_check_fault, -}; diff --git a/drivers/net/ethernet/sfc/mac.h b/drivers/net/ethernet/sfc/mac.h deleted file mode 100644 index d6a255d0856..00000000000 --- a/drivers/net/ethernet/sfc/mac.h +++ /dev/null @@ -1,21 +0,0 @@ -/**************************************************************************** - * Driver for Solarflare Solarstorm network controllers and boards - * Copyright 2005-2006 Fen Systems Ltd. - * Copyright 2006-2009 Solarflare Communications Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation, incorporated herein by reference. - */ - -#ifndef EFX_MAC_H -#define EFX_MAC_H - -#include "net_driver.h" - -extern const struct efx_mac_operations falcon_xmac_operations; -extern const struct efx_mac_operations efx_mcdi_mac_operations; -extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, - u32 dma_len, int enable, int clear); - -#endif diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index aced2a7856f..c59667bf64a 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -126,5 +126,9 @@ extern int efx_mcdi_wol_filter_set_magic(struct efx_nic *efx, extern int efx_mcdi_wol_filter_get_magic(struct efx_nic *efx, int *id_out); extern int efx_mcdi_wol_filter_remove(struct efx_nic *efx, int id); extern int efx_mcdi_wol_filter_reset(struct efx_nic *efx); +extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, + u32 dma_len, int enable, int clear); +extern int efx_mcdi_mac_reconfigure(struct efx_nic *efx); +extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx); #endif /* EFX_MCDI_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 85fe24f8639..4907062b24a 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -9,7 +9,6 @@ #include "net_driver.h" #include "efx.h" -#include "mac.h" #include "mcdi.h" #include "mcdi_pcol.h" @@ -115,7 +114,7 @@ fail: return rc; } -static int efx_mcdi_mac_reconfigure(struct efx_nic *efx) +int efx_mcdi_mac_reconfigure(struct efx_nic *efx) { int rc; @@ -130,16 +129,9 @@ static int efx_mcdi_mac_reconfigure(struct efx_nic *efx) } -static bool efx_mcdi_mac_check_fault(struct efx_nic *efx) +bool efx_mcdi_mac_check_fault(struct efx_nic *efx) { u32 faults; int rc = efx_mcdi_get_mac_faults(efx, &faults); return (rc != 0) || (faults != 0); } - - -const struct efx_mac_operations efx_mcdi_mac_operations = { - .reconfigure = efx_mcdi_mac_reconfigure, - .update_stats = efx_port_dummy_op_void, - .check_fault = efx_mcdi_mac_check_fault, -}; diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index b6040141ef7..aa5a321a141 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -473,18 +473,6 @@ static inline bool efx_link_state_equal(const struct efx_link_state *left, left->fc == right->fc && left->speed == right->speed; } -/** - * struct efx_mac_operations - Efx MAC operations table - * @reconfigure: Reconfigure MAC. Serialised by the mac_lock - * @update_stats: Update statistics - * @check_fault: Check fault state. True if fault present. - */ -struct efx_mac_operations { - int (*reconfigure) (struct efx_nic *efx); - void (*update_stats) (struct efx_nic *efx); - bool (*check_fault)(struct efx_nic *efx); -}; - /** * struct efx_phy_operations - Efx PHY operations table * @probe: Probe PHY and initialise efx->mdio.mode_support, efx->mdio.mmds, @@ -676,7 +664,6 @@ struct efx_filter_state; * @port_initialized: Port initialized? * @net_dev: Operating system network device. Consider holding the rtnl lock * @stats_buffer: DMA buffer for statistics - * @mac_op: MAC interface * @phy_type: PHY type * @phy_op: PHY interface * @phy_data: PHY private data (including PHY-specific stats) @@ -767,8 +754,6 @@ struct efx_nic { struct efx_buffer stats_buffer; - const struct efx_mac_operations *mac_op; - unsigned int phy_type; const struct efx_phy_operations *phy_op; void *phy_data; @@ -843,12 +828,13 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @push_irq_moderation: Apply interrupt moderation value * @push_multicast_hash: Apply multicast hash table * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY + * @reconfigure_mac: Reconfigure MAC only. Serialised by the mac_lock + * @check_mac_fault: Check MAC fault state. True if fault present. * @get_wol: Get WoL configuration from driver state * @set_wol: Push WoL configuration to the NIC * @resume_wol: Synchronise WoL state between driver and MC (e.g. after resume) * @test_registers: Test read/write functionality of control registers * @test_nvram: Test validity of NVRAM contents - * @default_mac_ops: efx_mac_operations to set at startup * @revision: Hardware architecture revision * @mem_map_size: Memory BAR mapped size * @txd_ptr_tbl_base: TX descriptor ring base address @@ -888,12 +874,13 @@ struct efx_nic_type { void (*push_irq_moderation)(struct efx_channel *channel); void (*push_multicast_hash)(struct efx_nic *efx); int (*reconfigure_port)(struct efx_nic *efx); + int (*reconfigure_mac)(struct efx_nic *efx); + bool (*check_mac_fault)(struct efx_nic *efx); void (*get_wol)(struct efx_nic *efx, struct ethtool_wolinfo *wol); int (*set_wol)(struct efx_nic *efx, u32 type); void (*resume_wol)(struct efx_nic *efx); int (*test_registers)(struct efx_nic *efx); int (*test_nvram)(struct efx_nic *efx); - const struct efx_mac_operations *default_mac_ops; int revision; unsigned int mem_map_size; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index 5fb24d3aa3c..cfda6ded24f 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -189,6 +189,9 @@ extern bool efx_nic_event_present(struct efx_channel *channel); /* MAC/PHY */ extern void falcon_drain_tx_fifo(struct efx_nic *efx); extern void falcon_reconfigure_mac_wrapper(struct efx_nic *efx); +extern bool falcon_xmac_check_fault(struct efx_nic *efx); +extern int falcon_reconfigure_xmac(struct efx_nic *efx); +extern void falcon_update_stats_xmac(struct efx_nic *efx); /* Interrupts and test events */ extern int efx_nic_init_interrupt(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 5226d9857f3..9df2a794250 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -569,7 +569,7 @@ static int efx_wait_for_link(struct efx_nic *efx) mutex_lock(&efx->mac_lock); link_up = link_state->up; if (link_up) - link_up = !efx->mac_op->check_fault(efx); + link_up = !efx->type->check_mac_fault(efx); mutex_unlock(&efx->mac_lock); if (link_up) { diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 4d5d619feaa..775b6784cbd 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -18,7 +18,6 @@ #include "bitfield.h" #include "efx.h" #include "nic.h" -#include "mac.h" #include "spi.h" #include "regs.h" #include "io.h" @@ -631,13 +630,14 @@ const struct efx_nic_type siena_a0_nic_type = { .set_id_led = efx_mcdi_set_id_led, .push_irq_moderation = siena_push_irq_moderation, .push_multicast_hash = siena_push_multicast_hash, + .reconfigure_mac = efx_mcdi_mac_reconfigure, + .check_mac_fault = efx_mcdi_mac_check_fault, .reconfigure_port = efx_mcdi_phy_reconfigure, .get_wol = siena_get_wol, .set_wol = siena_set_wol, .resume_wol = siena_init_wol, .test_registers = siena_test_registers, .test_nvram = efx_mcdi_nvram_test_all, - .default_mac_ops = &efx_mcdi_mac_operations, .revision = EFX_REV_SIENA_A0, .mem_map_size = (FR_CZ_MC_TREG_SMEM + -- cgit v1.2.3-70-g09d2 From 1daf417029ddc10b7854430c1e1118df791d0eaf Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 8 Sep 2011 02:09:42 +0100 Subject: sfc: Merge efx_mcdi_mac_check_fault() and efx_mcdi_get_mac_faults() The latter is only called by the former, which is a very short wrapper. Further, gcc 4.5 may currently wrongly warn that the 'faults' variable may be used uninitialised. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi_mac.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 4907062b24a..559d79861fa 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -51,7 +51,7 @@ static int efx_mcdi_set_mac(struct efx_nic *efx) NULL, 0, NULL); } -static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults) +bool efx_mcdi_mac_check_fault(struct efx_nic *efx) { u8 outbuf[MC_CMD_GET_LINK_OUT_LEN]; size_t outlength; @@ -61,16 +61,13 @@ static int efx_mcdi_get_mac_faults(struct efx_nic *efx, u32 *faults) rc = efx_mcdi_rpc(efx, MC_CMD_GET_LINK, NULL, 0, outbuf, sizeof(outbuf), &outlength); - if (rc) - goto fail; - - *faults = MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT); - return 0; + if (rc) { + netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", + __func__, rc); + return true; + } -fail: - netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", - __func__, rc); - return rc; + return MCDI_DWORD(outbuf, GET_LINK_OUT_MAC_FAULT) != 0; } int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, @@ -127,11 +124,3 @@ int efx_mcdi_mac_reconfigure(struct efx_nic *efx) return 0; } - - -bool efx_mcdi_mac_check_fault(struct efx_nic *efx) -{ - u32 faults; - int rc = efx_mcdi_get_mac_faults(efx, &faults); - return (rc != 0) || (faults != 0); -} -- cgit v1.2.3-70-g09d2 From 30b81cda9516878906b44fed16aac9df1dbb89c7 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 13 Sep 2011 19:47:48 +0100 Subject: sfc: Remove efx_nic_type::push_multicast_hash operation Both implementations of efx_nic_type::reconfigure_mac operation push the multicast hash filter to the hardware. It is therefore redundant to call efx_nic_type::push_multicast_hash as well. efx_mcdi_mac_reconfigure() also uses this operation, but the implementation for Siena just uses MCDI anyway. Merge that into efx_mcdi_mac_reconfigure(). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 5 +---- drivers/net/ethernet/sfc/falcon.c | 2 -- drivers/net/ethernet/sfc/mcdi_mac.c | 10 ++++++---- drivers/net/ethernet/sfc/net_driver.h | 5 ++--- drivers/net/ethernet/sfc/siena.c | 10 ---------- 5 files changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 1d20e01c6ae..de162474c3c 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -898,10 +898,8 @@ static void efx_mac_work(struct work_struct *data) struct efx_nic *efx = container_of(data, struct efx_nic, mac_work); mutex_lock(&efx->mac_lock); - if (efx->port_enabled) { - efx->type->push_multicast_hash(efx); + if (efx->port_enabled) efx->type->reconfigure_mac(efx); - } mutex_unlock(&efx->mac_lock); } @@ -968,7 +966,6 @@ static void efx_start_port(struct efx_nic *efx) /* efx_mac_work() might have been scheduled after efx_stop_port(), * and then cancelled by efx_flush_all() */ - efx->type->push_multicast_hash(efx); efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 1a8a316bb53..fe21c7e349b 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -1766,7 +1766,6 @@ const struct efx_nic_type falcon_a1_nic_type = { .stop_stats = falcon_stop_nic_stats, .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, - .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, .reconfigure_mac = falcon_reconfigure_xmac, .check_mac_fault = falcon_xmac_check_fault, @@ -1809,7 +1808,6 @@ const struct efx_nic_type falcon_b0_nic_type = { .stop_stats = falcon_stop_nic_stats, .set_id_led = falcon_set_id_led, .push_irq_moderation = falcon_push_irq_moderation, - .push_multicast_hash = falcon_push_multicast_hash, .reconfigure_port = falcon_reconfigure_port, .reconfigure_mac = falcon_reconfigure_xmac, .check_mac_fault = falcon_xmac_check_fault, diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index 559d79861fa..f67cf921bd1 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -115,12 +115,14 @@ int efx_mcdi_mac_reconfigure(struct efx_nic *efx) { int rc; + WARN_ON(!mutex_is_locked(&efx->mac_lock)); + rc = efx_mcdi_set_mac(efx); if (rc != 0) return rc; - /* Restore the multicast hash registers. */ - efx->type->push_multicast_hash(efx); - - return 0; + return efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, + efx->multicast_hash.byte, + sizeof(efx->multicast_hash), + NULL, 0, NULL); } diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index aa5a321a141..a88e95f58b0 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -826,9 +826,9 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * @stop_stats: Stop the regular fetching of statistics * @set_id_led: Set state of identifying LED or revert to automatic function * @push_irq_moderation: Apply interrupt moderation value - * @push_multicast_hash: Apply multicast hash table * @reconfigure_port: Push loopback/power/txdis changes to the MAC and PHY - * @reconfigure_mac: Reconfigure MAC only. Serialised by the mac_lock + * @reconfigure_mac: Push MAC address, MTU, flow control and filter settings + * to the hardware. Serialised by the mac_lock. * @check_mac_fault: Check MAC fault state. True if fault present. * @get_wol: Get WoL configuration from driver state * @set_wol: Push WoL configuration to the NIC @@ -872,7 +872,6 @@ struct efx_nic_type { void (*stop_stats)(struct efx_nic *efx); void (*set_id_led)(struct efx_nic *efx, enum efx_led_mode mode); void (*push_irq_moderation)(struct efx_channel *channel); - void (*push_multicast_hash)(struct efx_nic *efx); int (*reconfigure_port)(struct efx_nic *efx); int (*reconfigure_mac)(struct efx_nic *efx); bool (*check_mac_fault)(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 775b6784cbd..d681f2597e7 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -52,15 +52,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel) channel->channel); } -static void siena_push_multicast_hash(struct efx_nic *efx) -{ - WARN_ON(!mutex_is_locked(&efx->mac_lock)); - - efx_mcdi_rpc(efx, MC_CMD_SET_MCAST_HASH, - efx->multicast_hash.byte, sizeof(efx->multicast_hash), - NULL, 0, NULL); -} - static int siena_mdio_write(struct net_device *net_dev, int prtad, int devad, u16 addr, u16 value) { @@ -629,7 +620,6 @@ const struct efx_nic_type siena_a0_nic_type = { .stop_stats = siena_stop_nic_stats, .set_id_led = efx_mcdi_set_id_led, .push_irq_moderation = siena_push_irq_moderation, - .push_multicast_hash = siena_push_multicast_hash, .reconfigure_mac = efx_mcdi_mac_reconfigure, .check_mac_fault = efx_mcdi_mac_check_fault, .reconfigure_port = efx_mcdi_phy_reconfigure, -- cgit v1.2.3-70-g09d2 From 5f3f9d6c441faa323444b2f6b092d630fcd7d04c Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 4 Nov 2011 22:29:14 +0000 Subject: sfc: Consistently test DEBUG macro, not EFX_ENABLE_DEBUG The netif_dbg() macro is defined in . If the DEBUG macro is defined, it logs a message at 'debug' level, otherwise it does nothing. In net_driver.h we define DEBUG if EFX_ENABLE_DEBUG is defined, but this is too late for those source files that already got a definition of netif_dbg() by including Get rid of EFX_ENABLE_DEBUG, and only define and test DEBUG. In mtd.c, we do not use DEBUG as a condition flag but are forced to use the DEBUG macro-function from . Undefine DEBUG before including it. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mtd.c | 1 + drivers/net/ethernet/sfc/net_driver.h | 6 +----- drivers/net/ethernet/sfc/nic.c | 2 +- drivers/net/ethernet/sfc/selftest.c | 2 +- 4 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index 7f61cd3812d..b702862a092 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -10,6 +10,7 @@ #include #include +#undef DEBUG /* has its own use for DEBUG */ #include #include #include diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index a88e95f58b0..4cbd997e378 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -13,10 +13,6 @@ #ifndef EFX_NET_DRIVER_H #define EFX_NET_DRIVER_H -#if defined(EFX_ENABLE_DEBUG) && !defined(DEBUG) -#define DEBUG -#endif - #include #include #include @@ -42,7 +38,7 @@ #define EFX_DRIVER_VERSION "3.1" -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG #define EFX_BUG_ON_PARANOID(x) BUG_ON(x) #define EFX_WARN_ON_PARANOID(x) WARN_ON(x) #else diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index b1df2f39c8f..bf07bd0488c 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -801,7 +801,7 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, * error message. FRM_TRUNC indicates RXDP dropped the packet due * to a FIFO overflow. */ -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG if (rx_ev_other_err && net_ratelimit()) { netif_dbg(efx, rx_err, efx->net_dev, " RX queue %d unexpected RX event " diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 9df2a794250..7718287ad0b 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -315,7 +315,7 @@ void efx_loopback_rx_packet(struct efx_nic *efx, return; err: -#ifdef EFX_ENABLE_DEBUG +#ifdef DEBUG if (atomic_read(&state->rx_bad) == 0) { netif_err(efx, drv, efx->net_dev, "received packet:\n"); print_hex_dump(KERN_ERR, "", DUMP_PREFIX_OFFSET, 0x10, 1, -- cgit v1.2.3-70-g09d2 From 6aa9c7f625e8ce07060467051b68fc068118ee64 Mon Sep 17 00:00:00 2001 From: Matthew Slattery Date: Wed, 14 Jul 2010 15:36:19 +0100 Subject: sfc: Support extraction of CAPABILITIES from GET_BOARD_CFG response. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mcdi.c | 10 +++++++++- drivers/net/ethernet/sfc/mcdi.h | 2 +- drivers/net/ethernet/sfc/mtd.c | 2 +- drivers/net/ethernet/sfc/siena.c | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index e5837a6485a..f1cad22b30f 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -678,7 +678,7 @@ fail: } int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, - u16 *fw_subtype_list) + u16 *fw_subtype_list, u32 *capabilities) { uint8_t outbuf[MC_CMD_GET_BOARD_CFG_OUT_LENMIN]; size_t outlen; @@ -708,6 +708,14 @@ int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, outbuf + MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_OFST, MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM * sizeof(fw_subtype_list[0])); + if (capabilities) { + if (port_num) + *capabilities = MCDI_DWORD(outbuf, + GET_BOARD_CFG_OUT_CAPABILITIES_PORT1); + else + *capabilities = MCDI_DWORD(outbuf, + GET_BOARD_CFG_OUT_CAPABILITIES_PORT0); + } return 0; diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index c59667bf64a..4dd39fcca67 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -97,7 +97,7 @@ extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, bool *was_attached_out); extern int efx_mcdi_get_board_cfg(struct efx_nic *efx, u8 *mac_address, - u16 *fw_subtype_list); + u16 *fw_subtype_list, u32 *capabilities); extern int efx_mcdi_log_ctrl(struct efx_nic *efx, bool evq, bool uart, u32 dest_evq); extern int efx_mcdi_nvram_types(struct efx_nic *efx, u32 *nvram_types_out); diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index b702862a092..eff49da458e 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -631,7 +631,7 @@ static int siena_mtd_get_fw_subtypes(struct efx_nic *efx, uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM]; int rc; - rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list); + rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL); if (rc) return rc; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index d681f2597e7..65cb5e4f426 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -216,7 +216,7 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) static int siena_probe_nvconfig(struct efx_nic *efx) { - return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL); + return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, NULL); } static int siena_probe_nic(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From cc180b69c009ec52f67a56d96b9073b9f774b323 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 8 Dec 2011 19:51:47 +0000 Subject: sfc: Correct interrupt timer quantum for Siena (normal and turbo mode) We currently assume that the timer quantum for Siena is 5 us, the same as for Falcon. This is not correct; timer ticks are generated on a rota which takes a minimum of 768 cycles (each event delivery or other timer change will delay it by 3 cycles). The timer quantum should be 6.144 or 3.072 us depending on whether turbo mode is active. Replace EFX_IRQ_MOD_RESOLUTION with a timer_quantum_ns field in struct efx_nic, initialised by the efx_nic_type::probe function. While we're at it, replace EFX_IRQ_MOD_MAX with a timer_period_max field in struct efx_nic_type. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 31 ++++++++++++++++++++++--------- drivers/net/ethernet/sfc/falcon.c | 6 ++++-- drivers/net/ethernet/sfc/net_driver.h | 4 ++++ drivers/net/ethernet/sfc/nic.h | 3 --- drivers/net/ethernet/sfc/siena.c | 13 ++++++++++--- 5 files changed, 40 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index de162474c3c..9d4ab5e5e1f 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1513,13 +1513,13 @@ static void efx_remove_all(struct efx_nic *efx) * **************************************************************************/ -static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int resolution) +static unsigned int irq_mod_ticks(unsigned int usecs, unsigned int quantum_ns) { if (usecs == 0) return 0; - if (usecs < resolution) + if (usecs * 1000 < quantum_ns) return 1; /* never round down to 0 */ - return usecs / resolution; + return usecs * 1000 / quantum_ns; } /* Set interrupt moderation parameters */ @@ -1528,14 +1528,20 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, bool rx_may_override_tx) { struct efx_channel *channel; - unsigned tx_ticks = irq_mod_ticks(tx_usecs, EFX_IRQ_MOD_RESOLUTION); - unsigned rx_ticks = irq_mod_ticks(rx_usecs, EFX_IRQ_MOD_RESOLUTION); + unsigned int irq_mod_max = DIV_ROUND_UP(efx->type->timer_period_max * + efx->timer_quantum_ns, + 1000); + unsigned int tx_ticks; + unsigned int rx_ticks; EFX_ASSERT_RESET_SERIALISED(efx); - if (tx_ticks > EFX_IRQ_MOD_MAX || rx_ticks > EFX_IRQ_MOD_MAX) + if (tx_usecs > irq_mod_max || rx_usecs > irq_mod_max) return -EINVAL; + tx_ticks = irq_mod_ticks(tx_usecs, efx->timer_quantum_ns); + rx_ticks = irq_mod_ticks(rx_usecs, efx->timer_quantum_ns); + if (tx_ticks != rx_ticks && efx->tx_channel_offset == 0 && !rx_may_override_tx) { netif_err(efx, drv, efx->net_dev, "Channels are shared. " @@ -1558,8 +1564,14 @@ int efx_init_irq_moderation(struct efx_nic *efx, unsigned int tx_usecs, void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, unsigned int *rx_usecs, bool *rx_adaptive) { + /* We must round up when converting ticks to microseconds + * because we round down when converting the other way. + */ + *rx_adaptive = efx->irq_rx_adaptive; - *rx_usecs = efx->irq_rx_moderation * EFX_IRQ_MOD_RESOLUTION; + *rx_usecs = DIV_ROUND_UP(efx->irq_rx_moderation * + efx->timer_quantum_ns, + 1000); /* If channels are shared between RX and TX, so is IRQ * moderation. Otherwise, IRQ moderation is the same for all @@ -1568,9 +1580,10 @@ void efx_get_irq_moderation(struct efx_nic *efx, unsigned int *tx_usecs, if (efx->tx_channel_offset == 0) *tx_usecs = *rx_usecs; else - *tx_usecs = + *tx_usecs = DIV_ROUND_UP( efx->channel[efx->tx_channel_offset]->irq_moderation * - EFX_IRQ_MOD_RESOLUTION; + efx->timer_quantum_ns, + 1000); } /************************************************************************** diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index fe21c7e349b..0b7880b0b8f 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -103,8 +103,6 @@ static void falcon_push_irq_moderation(struct efx_channel *channel) efx_dword_t timer_cmd; struct efx_nic *efx = channel->efx; - BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_AB_TC_TIMER_VAL_WIDTH)); - /* Set timer register */ if (channel->irq_moderation) { EFX_POPULATE_DWORD_2(timer_cmd, @@ -1471,6 +1469,8 @@ static int falcon_probe_nic(struct efx_nic *efx) goto fail5; } + efx->timer_quantum_ns = 4968; /* 621 cycles */ + /* Initialise I2C adapter */ board = falcon_board(efx); board->i2c_adap.owner = THIS_MODULE; @@ -1785,6 +1785,7 @@ const struct efx_nic_type falcon_a1_nic_type = { .rx_buffer_padding = 0x24, .max_interrupt_mode = EFX_INT_MODE_MSI, .phys_addr_channels = 4, + .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM, @@ -1836,6 +1837,7 @@ const struct efx_nic_type falcon_b0_nic_type = { .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 * channels */ + .timer_period_max = 1 << FRF_AB_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x130000, .rx_dc_base = 0x100000, .offload_features = NETIF_F_IP_CSUM | NETIF_F_RXHASH | NETIF_F_NTUPLE, diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 4cbd997e378..8ce4d068bba 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -624,6 +624,7 @@ struct efx_filter_state; * @membase_phys: Memory BAR value as physical address * @membase: Memory BAR value * @interrupt_mode: Interrupt mode + * @timer_quantum_ns: Interrupt timer quantum, in nanoseconds * @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues * @irq_rx_moderation: IRQ moderation time for RX event queues * @msg_enable: Log message enable flags @@ -706,6 +707,7 @@ struct efx_nic { void __iomem *membase; enum efx_int_mode interrupt_mode; + unsigned int timer_quantum_ns; bool irq_rx_adaptive; unsigned int irq_rx_moderation; u32 msg_enable; @@ -845,6 +847,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx) * from &enum efx_init_mode. * @phys_addr_channels: Number of channels with physically addressed * descriptors + * @timer_period_max: Maximum period of interrupt timer (in ticks) * @tx_dc_base: Base address in SRAM of TX queue descriptor caches * @rx_dc_base: Base address in SRAM of RX queue descriptor caches * @offload_features: net_device feature flags for protocol offload @@ -889,6 +892,7 @@ struct efx_nic_type { unsigned int rx_buffer_padding; unsigned int max_interrupt_mode; unsigned int phys_addr_channels; + unsigned int timer_period_max; unsigned int tx_dc_base; unsigned int rx_dc_base; netdev_features_t offload_features; diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index cfda6ded24f..a3ccd0b9d78 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -205,9 +205,6 @@ extern irqreturn_t efx_nic_fatal_interrupt(struct efx_nic *efx); extern irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id); extern void falcon_irq_ack_a1(struct efx_nic *efx); -#define EFX_IRQ_MOD_RESOLUTION 5 -#define EFX_IRQ_MOD_MAX 0x1000 - /* Global Resources */ extern int efx_nic_flush_queues(struct efx_nic *efx); extern void falcon_start_nic_stats(struct efx_nic *efx); diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index 65cb5e4f426..f05425842b3 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -35,8 +35,6 @@ static void siena_push_irq_moderation(struct efx_channel *channel) { efx_dword_t timer_cmd; - BUILD_BUG_ON(EFX_IRQ_MOD_MAX > (1 << FRF_CZ_TC_TIMER_VAL_WIDTH)); - if (channel->irq_moderation) EFX_POPULATE_DWORD_2(timer_cmd, FRF_CZ_TC_TIMER_MODE, @@ -216,7 +214,15 @@ static int siena_reset_hw(struct efx_nic *efx, enum reset_type method) static int siena_probe_nvconfig(struct efx_nic *efx) { - return efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, NULL); + u32 caps = 0; + int rc; + + rc = efx_mcdi_get_board_cfg(efx, efx->net_dev->perm_addr, NULL, &caps); + + efx->timer_quantum_ns = + (caps & (1 << MC_CMD_CAPABILITIES_TURBO_ACTIVE_LBN)) ? + 3072 : 6144; /* 768 cycles */ + return rc; } static int siena_probe_nic(struct efx_nic *efx) @@ -644,6 +650,7 @@ const struct efx_nic_type siena_a0_nic_type = { .phys_addr_channels = 32, /* Hardware limit is 64, but the legacy * interrupt handler only supports 32 * channels */ + .timer_period_max = 1 << FRF_CZ_TC_TIMER_VAL_WIDTH, .tx_dc_base = 0x88000, .rx_dc_base = 0x68000, .offload_features = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | -- cgit v1.2.3-70-g09d2 From 0fb53faa2e6fe67a76b8cfc6eb70a88d9d623648 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 4 Nov 2011 23:06:04 +0000 Subject: sfc: Remove dependence on NAPI polling in efx_test_eventq_irq() We cannot safely assume that the NAPI handler will complete within the 20 ms that we allow for the event self-test. The handler may be deferred for longer than this, particularly on realtime kernels. Instead, check whether either an event has been handled or (as in the old failure path) whether an interrupt has been received and an event has been delivered but not yet handled. Use napi_disable() to synchronize with the NAPI handler before checking, since it will clear events before updating eventq_read_ptr. Remove the test result chan.N.eventq.poll, since it is not an error if the NAPI handler does not run during the test. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/ethtool.c | 4 -- drivers/net/ethernet/sfc/selftest.c | 79 +++++++++++++++++++------------------ drivers/net/ethernet/sfc/selftest.h | 1 - 3 files changed, 40 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index 1a7f7ba27be..ba901167801 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -404,10 +404,6 @@ static int efx_ethtool_fill_self_tests(struct efx_nic *efx, &tests->eventq_int[channel->channel], EFX_CHANNEL_NAME(channel), "eventq.int", NULL); - efx_fill_test(n++, strings, data, - &tests->eventq_poll[channel->channel], - EFX_CHANNEL_NAME(channel), - "eventq.poll", NULL); } efx_fill_test(n++, strings, data, &tests->registers, diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 7718287ad0b..0f847892447 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -161,11 +161,8 @@ static int efx_test_eventq_irq(struct efx_channel *channel, struct efx_self_tests *tests) { struct efx_nic *efx = channel->efx; - unsigned int read_ptr, count; - - tests->eventq_dma[channel->channel] = -1; - tests->eventq_int[channel->channel] = -1; - tests->eventq_poll[channel->channel] = -1; + unsigned int read_ptr; + bool napi_ran, dma_seen, int_seen; read_ptr = channel->eventq_read_ptr; channel->efx->last_irq_cpu = -1; @@ -173,44 +170,48 @@ static int efx_test_eventq_irq(struct efx_channel *channel, efx_nic_generate_test_event(channel); - /* Wait for arrival of interrupt */ - count = 0; - do { - schedule_timeout_uninterruptible(HZ / 100); - - if (ACCESS_ONCE(channel->eventq_read_ptr) != read_ptr) - goto eventq_ok; - } while (++count < 2); - - netif_err(efx, drv, efx->net_dev, - "channel %d timed out waiting for event queue\n", - channel->channel); - - /* See if interrupt arrived */ - if (channel->efx->last_irq_cpu >= 0) { - netif_err(efx, drv, efx->net_dev, - "channel %d saw interrupt on CPU%d " - "during event queue test\n", channel->channel, - raw_smp_processor_id()); - tests->eventq_int[channel->channel] = 1; + /* Wait for arrival of interrupt. NAPI processing may or may + * not complete in time, but we can cope in any case. + */ + msleep(10); + napi_disable(&channel->napi_str); + if (channel->eventq_read_ptr != read_ptr) { + napi_ran = true; + dma_seen = true; + int_seen = true; + } else { + napi_ran = false; + dma_seen = efx_nic_event_present(channel); + int_seen = efx->last_irq_cpu >= 0; } + napi_enable(&channel->napi_str); + efx_nic_eventq_read_ack(channel); + + tests->eventq_dma[channel->channel] = dma_seen ? 1 : -1; + tests->eventq_int[channel->channel] = int_seen ? 1 : -1; - /* Check to see if event was received even if interrupt wasn't */ - if (efx_nic_event_present(channel)) { + if (dma_seen && int_seen) { + netif_dbg(efx, drv, efx->net_dev, + "channel %d event queue passed (with%s NAPI)\n", + channel->channel, napi_ran ? "" : "out"); + return 0; + } else { + /* Report failure and whether either interrupt or DMA worked */ netif_err(efx, drv, efx->net_dev, - "channel %d event was generated, but " - "failed to trigger an interrupt\n", channel->channel); - tests->eventq_dma[channel->channel] = 1; + "channel %d timed out waiting for event queue\n", + channel->channel); + if (int_seen) + netif_err(efx, drv, efx->net_dev, + "channel %d saw interrupt " + "during event queue test\n", + channel->channel); + if (dma_seen) + netif_err(efx, drv, efx->net_dev, + "channel %d event was generated, but " + "failed to trigger an interrupt\n", + channel->channel); + return -ETIMEDOUT; } - - return -ETIMEDOUT; - eventq_ok: - netif_dbg(efx, drv, efx->net_dev, "channel %d event queue passed\n", - channel->channel); - tests->eventq_dma[channel->channel] = 1; - tests->eventq_int[channel->channel] = 1; - tests->eventq_poll[channel->channel] = 1; - return 0; } static int efx_test_phy(struct efx_nic *efx, struct efx_self_tests *tests, diff --git a/drivers/net/ethernet/sfc/selftest.h b/drivers/net/ethernet/sfc/selftest.h index dba5456e70f..87abe2a5384 100644 --- a/drivers/net/ethernet/sfc/selftest.h +++ b/drivers/net/ethernet/sfc/selftest.h @@ -37,7 +37,6 @@ struct efx_self_tests { int interrupt; int eventq_dma[EFX_MAX_CHANNELS]; int eventq_int[EFX_MAX_CHANNELS]; - int eventq_poll[EFX_MAX_CHANNELS]; /* offline tests */ int registers; int phy_ext[EFX_MAX_PHY_TESTS]; -- cgit v1.2.3-70-g09d2 From f70d1847348e9548a9a56e4434946315bca297c8 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 01:08:24 +0000 Subject: Partly revert "sfc: Handle serious errors in exactly one interrupt handler" This reverts commit 6369545945b90daa1a73fca174da9194c398417c in drivers/net/ethernet/sfc/falcon.c. Unlike the INT_ISR0 register on later controller revisions, the NET_IVEC_INT_Q bits written to memory are only ever set for interrupting event queues, not for any other interrupt sources. By definition there can only be one legacy interrupt handler per function, so there is no need to worry about detecting a fatal interrupt more than once. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/falcon.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index 0b7880b0b8f..b4e91edec0f 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -174,19 +174,16 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); + /* Check to see if we have a serious error condition */ + syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); + if (unlikely(syserr)) + return efx_nic_fatal_interrupt(efx); + /* Determine interrupting queues, clear interrupt status * register and acknowledge the device interrupt. */ BUILD_BUG_ON(FSF_AZ_NET_IVEC_INT_Q_WIDTH > EFX_MAX_CHANNELS); queues = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_INT_Q); - - /* Check to see if we have a serious error condition */ - if (queues & (1U << efx->fatal_irq_level)) { - syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); - if (unlikely(syserr)) - return efx_nic_fatal_interrupt(efx); - } - EFX_ZERO_OWORD(*int_ker); wmb(); /* Ensure the vector is cleared before interrupt ack */ falcon_irq_ack_a1(efx); -- cgit v1.2.3-70-g09d2 From 1646a6f352a6f70fcca828589ed04797aa09d494 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 5 Jan 2012 20:14:10 +0000 Subject: sfc: Clean up test interrupt handling Interrupts are normally generated by the event queues, moderated by timers. However, they may also be triggered by detection of a 'fatal' error condition (e.g. memory parity error) or by the host writing to certain CSR fields as part of a self-test. The IRQ level/index used for these on Falcon rev B0 and Siena is set by the KER_INT_LEVE_SEL field and cached by the driver in efx_nic::fatal_irq_level. Since this value is also relevant to self-tests rename the field to just 'irq_level'. Avoid unnecessary cache traffic by using a per-channel 'last_irq_cpu' field and only writing to the per-controller field when the interrupt matches efx_nic::irq_level. Remove the volatile qualifier and use ACCESS_ONCE in the places we read these fields. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.h | 6 ++++++ drivers/net/ethernet/sfc/falcon.c | 4 ++-- drivers/net/ethernet/sfc/net_driver.h | 15 ++++++++------- drivers/net/ethernet/sfc/nic.c | 27 +++++++++++++-------------- drivers/net/ethernet/sfc/selftest.c | 12 +++++++----- 5 files changed, 36 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index a3541ac6ea0..e0b66d158d7 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -145,6 +145,12 @@ static inline void efx_schedule_channel(struct efx_channel *channel) napi_schedule(&channel->napi_str); } +static inline void efx_schedule_channel_irq(struct efx_channel *channel) +{ + channel->last_irq_cpu = raw_smp_processor_id(); + efx_schedule_channel(channel); +} + extern void efx_link_status_changed(struct efx_nic *efx); extern void efx_link_set_advertising(struct efx_nic *efx, u32); extern void efx_link_set_wanted_fc(struct efx_nic *efx, u8); diff --git a/drivers/net/ethernet/sfc/falcon.c b/drivers/net/ethernet/sfc/falcon.c index b4e91edec0f..98285115df1 100644 --- a/drivers/net/ethernet/sfc/falcon.c +++ b/drivers/net/ethernet/sfc/falcon.c @@ -189,9 +189,9 @@ irqreturn_t falcon_legacy_interrupt_a1(int irq, void *dev_id) falcon_irq_ack_a1(efx); if (queues & 1) - efx_schedule_channel(efx_get_channel(efx, 0)); + efx_schedule_channel_irq(efx_get_channel(efx, 0)); if (queues & 2) - efx_schedule_channel(efx_get_channel(efx, 1)); + efx_schedule_channel_irq(efx_get_channel(efx, 1)); return IRQ_HANDLED; } /************************************************************************** diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 8ce4d068bba..a4cf8cb8180 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -325,6 +325,7 @@ enum efx_rx_alloc_method { * @eventq_mask: Event queue pointer mask * @eventq_read_ptr: Event queue read pointer * @last_eventq_read_ptr: Last event queue read pointer value. + * @last_irq_cpu: Last CPU to handle interrupt for this channel * @irq_count: Number of IRQs since last adaptive moderation decision * @irq_mod_score: IRQ moderation score * @rx_alloc_level: Watermark based heuristic counter for pushing descriptors @@ -355,6 +356,7 @@ struct efx_channel { unsigned int eventq_read_ptr; unsigned int last_eventq_read_ptr; + int last_irq_cpu; unsigned int irq_count; unsigned int irq_mod_score; #ifdef CONFIG_RFS_ACCEL @@ -648,7 +650,7 @@ struct efx_filter_state; * @int_error_expire: Time at which error count will be expired * @irq_status: Interrupt status buffer * @irq_zero_count: Number of legacy IRQs seen with queue flags == 0 - * @fatal_irq_level: IRQ level (bit number) used for serious errors + * @irq_level: IRQ level/index for IRQs not triggered by an event queue * @mtd_list: List of MTDs attached to the NIC * @nic_data: Hardware dependent state * @mac_lock: MAC access lock. Protects @port_enabled, @phy_mode, @@ -679,10 +681,9 @@ struct efx_filter_state; * @loopback_selftest: Offline self-test private state * @monitor_work: Hardware monitor workitem * @biu_lock: BIU (bus interface unit) lock - * @last_irq_cpu: Last CPU to handle interrupt. - * This register is written with the SMP processor ID whenever an - * interrupt is handled. It is used by efx_nic_test_interrupt() - * to verify that an interrupt has occurred. + * @last_irq_cpu: Last CPU to handle a possible test interrupt. This + * field is used by efx_test_interrupts() to verify that an + * interrupt has occurred. * @n_rx_nodesc_drop_cnt: RX no descriptor drop count * @mac_stats: MAC statistics. These include all statistics the MACs * can provide. Generic code converts these into a standard @@ -735,7 +736,7 @@ struct efx_nic { struct efx_buffer irq_status; unsigned irq_zero_count; - unsigned fatal_irq_level; + unsigned irq_level; #ifdef CONFIG_SFC_MTD struct list_head mtd_list; @@ -779,7 +780,7 @@ struct efx_nic { struct delayed_work monitor_work ____cacheline_aligned_in_smp; spinlock_t biu_lock; - volatile signed int last_irq_cpu; + int last_irq_cpu; unsigned n_rx_nodesc_drop_cnt; struct efx_mac_stats mac_stats; spinlock_t stats_lock; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index bf07bd0488c..de7aa1c8ebd 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -1311,7 +1311,7 @@ static inline void efx_nic_interrupts(struct efx_nic *efx, efx_oword_t int_en_reg_ker; EFX_POPULATE_OWORD_3(int_en_reg_ker, - FRF_AZ_KER_INT_LEVE_SEL, efx->fatal_irq_level, + FRF_AZ_KER_INT_LEVE_SEL, efx->irq_level, FRF_AZ_KER_INT_KER, force, FRF_AZ_DRV_INT_EN_KER, enabled); efx_writeo(efx, &int_en_reg_ker, FR_AZ_INT_EN_KER); @@ -1427,11 +1427,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) efx_readd(efx, ®, FR_BZ_INT_ISR0); queues = EFX_EXTRACT_DWORD(reg, 0, 31); - /* Check to see if we have a serious error condition */ - if (queues & (1U << efx->fatal_irq_level)) { + /* Handle non-event-queue sources */ + if (queues & (1U << efx->irq_level)) { syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return efx_nic_fatal_interrupt(efx); + efx->last_irq_cpu = raw_smp_processor_id(); } if (queues != 0) { @@ -1441,7 +1442,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) /* Schedule processing of any interrupting queues */ efx_for_each_channel(channel, efx) { if (queues & 1) - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); queues >>= 1; } result = IRQ_HANDLED; @@ -1458,18 +1459,16 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) efx_for_each_channel(channel, efx) { event = efx_event(channel, channel->eventq_read_ptr); if (efx_event_present(event)) - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); else efx_nic_eventq_read_ack(channel); } } - if (result == IRQ_HANDLED) { - efx->last_irq_cpu = raw_smp_processor_id(); + if (result == IRQ_HANDLED) netif_vdbg(efx, intr, efx->net_dev, "IRQ %d on CPU %d status " EFX_DWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_DWORD_VAL(reg)); - } return result; } @@ -1488,20 +1487,20 @@ static irqreturn_t efx_msi_interrupt(int irq, void *dev_id) efx_oword_t *int_ker = efx->irq_status.addr; int syserr; - efx->last_irq_cpu = raw_smp_processor_id(); netif_vdbg(efx, intr, efx->net_dev, "IRQ %d on CPU %d status " EFX_OWORD_FMT "\n", irq, raw_smp_processor_id(), EFX_OWORD_VAL(*int_ker)); - /* Check to see if we have a serious error condition */ - if (channel->channel == efx->fatal_irq_level) { + /* Handle non-event-queue sources */ + if (channel->channel == efx->irq_level) { syserr = EFX_OWORD_FIELD(*int_ker, FSF_AZ_NET_IVEC_FATAL_INT); if (unlikely(syserr)) return efx_nic_fatal_interrupt(efx); + efx->last_irq_cpu = raw_smp_processor_id(); } /* Schedule processing of the channel */ - efx_schedule_channel(channel); + efx_schedule_channel_irq(channel); return IRQ_HANDLED; } @@ -1640,10 +1639,10 @@ void efx_nic_init_common(struct efx_nic *efx) if (EFX_WORKAROUND_17213(efx) && !EFX_INT_MODE_USE_MSI(efx)) /* Use an interrupt level unused by event queues */ - efx->fatal_irq_level = 0x1f; + efx->irq_level = 0x1f; else /* Use a valid MSI-X vector */ - efx->fatal_irq_level = 0; + efx->irq_level = 0; /* Enable all the genuinely fatal interrupts. (They are still * masked by the overall interrupt mask, controlled by diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 0f847892447..7def480570c 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -130,6 +130,8 @@ static int efx_test_chip(struct efx_nic *efx, struct efx_self_tests *tests) static int efx_test_interrupts(struct efx_nic *efx, struct efx_self_tests *tests) { + int cpu; + netif_dbg(efx, drv, efx->net_dev, "testing interrupts\n"); tests->interrupt = -1; @@ -142,7 +144,8 @@ static int efx_test_interrupts(struct efx_nic *efx, /* Wait for arrival of test interrupt. */ netif_dbg(efx, drv, efx->net_dev, "waiting for test interrupt\n"); schedule_timeout_uninterruptible(HZ / 10); - if (efx->last_irq_cpu >= 0) + cpu = ACCESS_ONCE(efx->last_irq_cpu); + if (cpu >= 0) goto success; netif_err(efx, drv, efx->net_dev, "timed out waiting for interrupt\n"); @@ -150,8 +153,7 @@ static int efx_test_interrupts(struct efx_nic *efx, success: netif_dbg(efx, drv, efx->net_dev, "%s test interrupt seen on CPU%d\n", - INT_MODE(efx), - efx->last_irq_cpu); + INT_MODE(efx), cpu); tests->interrupt = 1; return 0; } @@ -165,7 +167,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, bool napi_ran, dma_seen, int_seen; read_ptr = channel->eventq_read_ptr; - channel->efx->last_irq_cpu = -1; + channel->last_irq_cpu = -1; smp_wmb(); efx_nic_generate_test_event(channel); @@ -182,7 +184,7 @@ static int efx_test_eventq_irq(struct efx_channel *channel, } else { napi_ran = false; dma_seen = efx_nic_event_present(channel); - int_seen = efx->last_irq_cpu >= 0; + int_seen = ACCESS_ONCE(channel->last_irq_cpu) >= 0; } napi_enable(&channel->napi_str); efx_nic_eventq_read_ack(channel); -- cgit v1.2.3-70-g09d2 From 55c5e0f85dc550f03dc8a0b0097da6af3b4865c5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 20:25:39 +0000 Subject: sfc: Add hwmon driver for boards using SFC9000-family controllers The SFC9000-family controllers have firmware to manage all board peripherals including temperature, heat sink continuity and voltage sensors. The firmware reports sensor alarms, which we log, and will shut down the board if necessary. Some users may want to monitor their boards more closely, so add an hwmon driver that exposes all sensors reported by the firmware. Move efx_mcdi_sensor_event() into the new file so it can share the array of sensor labels with the hwmon driver. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/Kconfig | 7 + drivers/net/ethernet/sfc/Makefile | 2 +- drivers/net/ethernet/sfc/mcdi.c | 43 ---- drivers/net/ethernet/sfc/mcdi.h | 28 +++ drivers/net/ethernet/sfc/mcdi_mon.c | 415 ++++++++++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/nic.h | 14 ++ drivers/net/ethernet/sfc/siena.c | 6 + 7 files changed, 471 insertions(+), 44 deletions(-) create mode 100644 drivers/net/ethernet/sfc/mcdi_mon.c (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index 5d18841f0f3..ae40b666739 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -19,3 +19,10 @@ config SFC_MTD This exposes the on-board flash memory as MTD devices (e.g. /dev/mtd1). This makes it possible to upload new firmware to the NIC. +config SFC_MCDI_MON + bool "Solarflare SFC9000-family hwmon support" + depends on SFC && HWMON && !(SFC=y && HWMON=m) + default y + ----help--- + This exposes the on-board firmware-managed sensors as a + hardware monitor device. diff --git a/drivers/net/ethernet/sfc/Makefile b/drivers/net/ethernet/sfc/Makefile index ab31c7124db..3fa2e25ccc4 100644 --- a/drivers/net/ethernet/sfc/Makefile +++ b/drivers/net/ethernet/sfc/Makefile @@ -2,7 +2,7 @@ sfc-y += efx.o nic.o falcon.o siena.o tx.o rx.o filter.o \ falcon_xmac.o mcdi_mac.o \ selftest.o ethtool.o qt202x_phy.o mdio_10g.o \ tenxpress.o txc43128_phy.o falcon_boards.o \ - mcdi.o mcdi_phy.o + mcdi.o mcdi_phy.o mcdi_mon.o sfc-$(CONFIG_SFC_MTD) += mtd.o obj-$(CONFIG_SFC) += sfc.o diff --git a/drivers/net/ethernet/sfc/mcdi.c b/drivers/net/ethernet/sfc/mcdi.c index f1cad22b30f..619f63a66ce 100644 --- a/drivers/net/ethernet/sfc/mcdi.c +++ b/drivers/net/ethernet/sfc/mcdi.c @@ -517,49 +517,6 @@ static void efx_mcdi_process_link_change(struct efx_nic *efx, efx_qword_t *ev) efx_link_status_changed(efx); } -static const char *const sensor_names[] = { - [MC_CMD_SENSOR_CONTROLLER_TEMP] = "Controller temp. sensor", - [MC_CMD_SENSOR_PHY_COMMON_TEMP] = "PHY shared temp. sensor", - [MC_CMD_SENSOR_CONTROLLER_COOLING] = "Controller cooling", - [MC_CMD_SENSOR_PHY0_TEMP] = "PHY 0 temp. sensor", - [MC_CMD_SENSOR_PHY0_COOLING] = "PHY 0 cooling", - [MC_CMD_SENSOR_PHY1_TEMP] = "PHY 1 temp. sensor", - [MC_CMD_SENSOR_PHY1_COOLING] = "PHY 1 cooling", - [MC_CMD_SENSOR_IN_1V0] = "1.0V supply sensor", - [MC_CMD_SENSOR_IN_1V2] = "1.2V supply sensor", - [MC_CMD_SENSOR_IN_1V8] = "1.8V supply sensor", - [MC_CMD_SENSOR_IN_2V5] = "2.5V supply sensor", - [MC_CMD_SENSOR_IN_3V3] = "3.3V supply sensor", - [MC_CMD_SENSOR_IN_12V0] = "12V supply sensor" -}; - -static const char *const sensor_status_names[] = { - [MC_CMD_SENSOR_STATE_OK] = "OK", - [MC_CMD_SENSOR_STATE_WARNING] = "Warning", - [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", - [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure", -}; - -static void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) -{ - unsigned int monitor, state, value; - const char *name, *state_txt; - monitor = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); - state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); - value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); - /* Deal gracefully with the board having more drivers than we - * know about, but do not expect new sensor states. */ - name = (monitor >= ARRAY_SIZE(sensor_names)) - ? "No sensor name available" : - sensor_names[monitor]; - EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); - state_txt = sensor_status_names[state]; - - netif_err(efx, hw, efx->net_dev, - "Sensor %d (%s) reports condition '%s' for raw value %d\n", - monitor, name, state_txt, value); -} - /* Called from falcon_process_eventq for MCDI events */ void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event) diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index 4dd39fcca67..fbaa6efcd74 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -56,6 +56,15 @@ struct efx_mcdi_iface { size_t resplen; }; +struct efx_mcdi_mon { + struct efx_buffer dma_buf; + struct mutex update_lock; + unsigned long last_update; + struct device *device; + struct efx_mcdi_mon_attribute *attrs; + unsigned int n_attrs; +}; + extern void efx_mcdi_init(struct efx_nic *efx); extern int efx_mcdi_rpc(struct efx_nic *efx, unsigned cmd, const u8 *inbuf, @@ -68,6 +77,7 @@ extern void efx_mcdi_mode_event(struct efx_nic *efx); extern void efx_mcdi_process_event(struct efx_channel *channel, efx_qword_t *event); +extern void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); #define MCDI_PTR2(_buf, _ofst) \ (((u8 *)_buf) + _ofst) @@ -83,6 +93,10 @@ extern void efx_mcdi_process_event(struct efx_channel *channel, #define MCDI_PTR(_buf, _ofst) \ MCDI_PTR2(_buf, MC_CMD_ ## _ofst ## _OFST) +#define MCDI_ARRAY_PTR(_buf, _field, _type, _index) \ + MCDI_PTR2(_buf, \ + MC_CMD_ ## _field ## _OFST + \ + (_index) * MC_CMD_ ## _type ## _TYPEDEF_LEN) #define MCDI_SET_DWORD(_buf, _ofst, _value) \ MCDI_SET_DWORD2(_buf, MC_CMD_ ## _ofst ## _OFST, _value) #define MCDI_DWORD(_buf, _ofst) \ @@ -92,6 +106,12 @@ extern void efx_mcdi_process_event(struct efx_channel *channel, #define MCDI_EVENT_FIELD(_ev, _field) \ EFX_QWORD_FIELD(_ev, MCDI_EVENT_ ## _field) +#define MCDI_ARRAY_FIELD(_buf, _field1, _type, _index, _field2) \ + EFX_DWORD_FIELD( \ + *((efx_dword_t *) \ + (MCDI_ARRAY_PTR(_buf, _field1, _type, _index) + \ + (MC_CMD_ ## _type ## _TYPEDEF_ ## _field2 ## _OFST & ~3))), \ + MC_CMD_ ## _type ## _TYPEDEF_ ## _field2) extern void efx_mcdi_print_fwver(struct efx_nic *efx, char *buf, size_t len); extern int efx_mcdi_drv_attach(struct efx_nic *efx, bool driver_operating, @@ -131,4 +151,12 @@ extern int efx_mcdi_mac_stats(struct efx_nic *efx, dma_addr_t dma_addr, extern int efx_mcdi_mac_reconfigure(struct efx_nic *efx); extern bool efx_mcdi_mac_check_fault(struct efx_nic *efx); +#ifdef CONFIG_SFC_MCDI_MON +extern int efx_mcdi_mon_probe(struct efx_nic *efx); +extern void efx_mcdi_mon_remove(struct efx_nic *efx); +#else +static inline int efx_mcdi_mon_probe(struct efx_nic *efx) { return 0; } +static inline void efx_mcdi_mon_remove(struct efx_nic *efx) {} +#endif + #endif /* EFX_MCDI_H */ diff --git a/drivers/net/ethernet/sfc/mcdi_mon.c b/drivers/net/ethernet/sfc/mcdi_mon.c new file mode 100644 index 00000000000..8a72c10b9a6 --- /dev/null +++ b/drivers/net/ethernet/sfc/mcdi_mon.c @@ -0,0 +1,415 @@ +/**************************************************************************** + * Driver for Solarflare Solarstorm network controllers and boards + * Copyright 2011 Solarflare Communications Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published + * by the Free Software Foundation, incorporated herein by reference. + */ + +#include +#include +#include +#include + +#include "net_driver.h" +#include "mcdi.h" +#include "mcdi_pcol.h" +#include "nic.h" + +enum efx_hwmon_type { + EFX_HWMON_UNKNOWN, + EFX_HWMON_TEMP, /* temperature */ + EFX_HWMON_COOL, /* cooling device, probably a heatsink */ + EFX_HWMON_IN /* input voltage */ +}; + +static const struct { + const char *label; + enum efx_hwmon_type hwmon_type; + int port; +} efx_mcdi_sensor_type[MC_CMD_SENSOR_ENTRY_MAXNUM] = { +#define SENSOR(name, label, hwmon_type, port) \ + [MC_CMD_SENSOR_##name] = { label, hwmon_type, port } + SENSOR(CONTROLLER_TEMP, "Controller temp.", EFX_HWMON_TEMP, -1), + SENSOR(PHY_COMMON_TEMP, "PHY temp.", EFX_HWMON_TEMP, -1), + SENSOR(CONTROLLER_COOLING, "Controller cooling", EFX_HWMON_COOL, -1), + SENSOR(PHY0_TEMP, "PHY temp.", EFX_HWMON_TEMP, 0), + SENSOR(PHY0_COOLING, "PHY cooling", EFX_HWMON_COOL, 0), + SENSOR(PHY1_TEMP, "PHY temp.", EFX_HWMON_TEMP, 1), + SENSOR(PHY1_COOLING, "PHY cooling", EFX_HWMON_COOL, 1), + SENSOR(IN_1V0, "1.0V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V2, "1.2V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V8, "1.8V supply", EFX_HWMON_IN, -1), + SENSOR(IN_2V5, "2.5V supply", EFX_HWMON_IN, -1), + SENSOR(IN_3V3, "3.3V supply", EFX_HWMON_IN, -1), + SENSOR(IN_12V0, "12.0V supply", EFX_HWMON_IN, -1), + SENSOR(IN_1V2A, "1.2V analogue supply", EFX_HWMON_IN, -1), + SENSOR(IN_VREF, "ref. voltage", EFX_HWMON_IN, -1), +#undef SENSOR +}; + +static const char *const sensor_status_names[] = { + [MC_CMD_SENSOR_STATE_OK] = "OK", + [MC_CMD_SENSOR_STATE_WARNING] = "Warning", + [MC_CMD_SENSOR_STATE_FATAL] = "Fatal", + [MC_CMD_SENSOR_STATE_BROKEN] = "Device failure", +}; + +void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev) +{ + unsigned int type, state, value; + const char *name = NULL, *state_txt; + + type = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_MONITOR); + state = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_STATE); + value = EFX_QWORD_FIELD(*ev, MCDI_EVENT_SENSOREVT_VALUE); + + /* Deal gracefully with the board having more drivers than we + * know about, but do not expect new sensor states. */ + if (type < ARRAY_SIZE(efx_mcdi_sensor_type)) + name = efx_mcdi_sensor_type[type].label; + if (!name) + name = "No sensor name available"; + EFX_BUG_ON_PARANOID(state >= ARRAY_SIZE(sensor_status_names)); + state_txt = sensor_status_names[state]; + + netif_err(efx, hw, efx->net_dev, + "Sensor %d (%s) reports condition '%s' for raw value %d\n", + type, name, state_txt, value); +} + +#ifdef CONFIG_SFC_MCDI_MON + +struct efx_mcdi_mon_attribute { + struct device_attribute dev_attr; + unsigned int index; + unsigned int type; + unsigned int limit_value; + char name[12]; +}; + +static int efx_mcdi_mon_update(struct efx_nic *efx) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + u8 inbuf[MC_CMD_READ_SENSORS_IN_LEN]; + int rc; + + MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_LO, + hwmon->dma_buf.dma_addr & 0xffffffff); + MCDI_SET_DWORD(inbuf, READ_SENSORS_IN_DMA_ADDR_HI, + (u64)hwmon->dma_buf.dma_addr >> 32); + + rc = efx_mcdi_rpc(efx, MC_CMD_READ_SENSORS, + inbuf, sizeof(inbuf), NULL, 0, NULL); + if (rc == 0) + hwmon->last_update = jiffies; + return rc; +} + +static ssize_t efx_mcdi_mon_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%s\n", KBUILD_MODNAME); +} + +static int efx_mcdi_mon_get_entry(struct device *dev, unsigned int index, + efx_dword_t *entry) +{ + struct efx_nic *efx = dev_get_drvdata(dev); + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + int rc; + + BUILD_BUG_ON(MC_CMD_READ_SENSORS_OUT_LEN != 0); + + mutex_lock(&hwmon->update_lock); + + /* Use cached value if last update was < 1 s ago */ + if (time_before(jiffies, hwmon->last_update + HZ)) + rc = 0; + else + rc = efx_mcdi_mon_update(efx); + + /* Copy out the requested entry */ + *entry = ((efx_dword_t *)hwmon->dma_buf.addr)[index]; + + mutex_unlock(&hwmon->update_lock); + + return rc; +} + +static ssize_t efx_mcdi_mon_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + efx_dword_t entry; + unsigned int value; + int rc; + + rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); + if (rc) + return rc; + + value = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_VALUE); + + /* Convert temperature from degrees to milli-degrees Celsius */ + if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP) + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t efx_mcdi_mon_show_limit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + unsigned int value; + + value = mon_attr->limit_value; + + /* Convert temperature from degrees to milli-degrees Celsius */ + if (efx_mcdi_sensor_type[mon_attr->type].hwmon_type == EFX_HWMON_TEMP) + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t efx_mcdi_mon_show_alarm(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + efx_dword_t entry; + int state; + int rc; + + rc = efx_mcdi_mon_get_entry(dev, mon_attr->index, &entry); + if (rc) + return rc; + + state = EFX_DWORD_FIELD(entry, MC_CMD_SENSOR_VALUE_ENTRY_TYPEDEF_STATE); + return sprintf(buf, "%d\n", state != MC_CMD_SENSOR_STATE_OK); +} + +static ssize_t efx_mcdi_mon_show_label(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct efx_mcdi_mon_attribute *mon_attr = + container_of(attr, struct efx_mcdi_mon_attribute, dev_attr); + return sprintf(buf, "%s\n", + efx_mcdi_sensor_type[mon_attr->type].label); +} + +static int +efx_mcdi_mon_add_attr(struct efx_nic *efx, const char *name, + ssize_t (*reader)(struct device *, + struct device_attribute *, char *), + unsigned int index, unsigned int type, + unsigned int limit_value) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + struct efx_mcdi_mon_attribute *attr = &hwmon->attrs[hwmon->n_attrs]; + int rc; + + strlcpy(attr->name, name, sizeof(attr->name)); + attr->index = index; + attr->type = type; + attr->limit_value = limit_value; + attr->dev_attr.attr.name = attr->name; + attr->dev_attr.attr.mode = S_IRUGO; + attr->dev_attr.show = reader; + rc = device_create_file(&efx->pci_dev->dev, &attr->dev_attr); + if (rc == 0) + ++hwmon->n_attrs; + return rc; +} + +int efx_mcdi_mon_probe(struct efx_nic *efx) +{ + struct efx_mcdi_mon *hwmon = efx_mcdi_mon(efx); + unsigned int n_attrs, n_temp = 0, n_cool = 0, n_in = 0; + u8 outbuf[MC_CMD_SENSOR_INFO_OUT_LENMAX]; + size_t outlen; + char name[12]; + u32 mask; + int rc, i, type; + + BUILD_BUG_ON(MC_CMD_SENSOR_INFO_IN_LEN != 0); + + rc = efx_mcdi_rpc(efx, MC_CMD_SENSOR_INFO, NULL, 0, + outbuf, sizeof(outbuf), &outlen); + if (rc) + return rc; + if (outlen < MC_CMD_SENSOR_INFO_OUT_LENMIN) + return -EIO; + + /* Find out which sensors are present. Don't create a device + * if there are none. + */ + mask = MCDI_DWORD(outbuf, SENSOR_INFO_OUT_MASK); + if (mask == 0) + return 0; + + /* Check again for short response */ + if (outlen < MC_CMD_SENSOR_INFO_OUT_LEN(hweight32(mask))) + return -EIO; + + rc = efx_nic_alloc_buffer(efx, &hwmon->dma_buf, + 4 * MC_CMD_SENSOR_ENTRY_MAXNUM); + if (rc) + return rc; + + mutex_init(&hwmon->update_lock); + efx_mcdi_mon_update(efx); + + /* Allocate space for the maximum possible number of + * attributes for this set of sensors: name of the driver plus + * value, min, max, crit, alarm and label for each sensor. + */ + n_attrs = 1 + 6 * hweight32(mask); + hwmon->attrs = kcalloc(n_attrs, sizeof(*hwmon->attrs), GFP_KERNEL); + if (!hwmon->attrs) { + rc = -ENOMEM; + goto fail; + } + + hwmon->device = hwmon_device_register(&efx->pci_dev->dev); + if (IS_ERR(hwmon->device)) { + rc = PTR_ERR(hwmon->device); + goto fail; + } + + rc = efx_mcdi_mon_add_attr(efx, "name", efx_mcdi_mon_show_name, 0, 0, 0); + if (rc) + goto fail; + + for (i = 0, type = -1; ; i++) { + const char *hwmon_prefix; + unsigned hwmon_index; + u16 min1, max1, min2, max2; + + /* Find next sensor type or exit if there is none */ + type++; + while (!(mask & (1 << type))) { + type++; + if (type == 32) + return 0; + } + + /* Skip sensors specific to a different port */ + if (efx_mcdi_sensor_type[type].hwmon_type != EFX_HWMON_UNKNOWN && + efx_mcdi_sensor_type[type].port >= 0 && + efx_mcdi_sensor_type[type].port != efx_port_num(efx)) + continue; + + switch (efx_mcdi_sensor_type[type].hwmon_type) { + case EFX_HWMON_TEMP: + hwmon_prefix = "temp"; + hwmon_index = ++n_temp; /* 1-based */ + break; + case EFX_HWMON_COOL: + /* This is likely to be a heatsink, but there + * is no convention for representing cooling + * devices other than fans. + */ + hwmon_prefix = "fan"; + hwmon_index = ++n_cool; /* 1-based */ + break; + default: + hwmon_prefix = "in"; + hwmon_index = n_in++; /* 0-based */ + break; + } + + min1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MIN1); + max1 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MAX1); + min2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MIN2); + max2 = MCDI_ARRAY_FIELD(outbuf, SENSOR_ENTRY, + SENSOR_INFO_ENTRY, i, MAX2); + + if (min1 != max1) { + snprintf(name, sizeof(name), "%s%u_input", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_value, i, type, 0); + if (rc) + goto fail; + + snprintf(name, sizeof(name), "%s%u_min", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, min1); + if (rc) + goto fail; + + snprintf(name, sizeof(name), "%s%u_max", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, max1); + if (rc) + goto fail; + + if (min2 != max2) { + /* Assume max2 is critical value. + * But we have no good way to expose min2. + */ + snprintf(name, sizeof(name), "%s%u_crit", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_limit, + i, type, max2); + if (rc) + goto fail; + } + } + + snprintf(name, sizeof(name), "%s%u_alarm", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_alarm, i, type, 0); + if (rc) + goto fail; + + if (efx_mcdi_sensor_type[type].label) { + snprintf(name, sizeof(name), "%s%u_label", + hwmon_prefix, hwmon_index); + rc = efx_mcdi_mon_add_attr( + efx, name, efx_mcdi_mon_show_label, i, type, 0); + if (rc) + goto fail; + } + } + +fail: + efx_mcdi_mon_remove(efx); + return rc; +} + +void efx_mcdi_mon_remove(struct efx_nic *efx) +{ + struct siena_nic_data *nic_data = efx->nic_data; + struct efx_mcdi_mon *hwmon = &nic_data->hwmon; + unsigned int i; + + for (i = 0; i < hwmon->n_attrs; i++) + device_remove_file(&efx->pci_dev->dev, + &hwmon->attrs[i].dev_attr); + kfree(hwmon->attrs); + if (hwmon->device) + hwmon_device_unregister(hwmon->device); + efx_nic_free_buffer(efx, &hwmon->dma_buf); +} + +#endif /* CONFIG_SFC_MCDI_MON */ diff --git a/drivers/net/ethernet/sfc/nic.h b/drivers/net/ethernet/sfc/nic.h index a3ccd0b9d78..905a1877d60 100644 --- a/drivers/net/ethernet/sfc/nic.h +++ b/drivers/net/ethernet/sfc/nic.h @@ -144,12 +144,26 @@ static inline struct falcon_board *falcon_board(struct efx_nic *efx) * struct siena_nic_data - Siena NIC state * @mcdi: Management-Controller-to-Driver Interface * @wol_filter_id: Wake-on-LAN packet filter id + * @hwmon: Hardware monitor state */ struct siena_nic_data { struct efx_mcdi_iface mcdi; int wol_filter_id; +#ifdef CONFIG_SFC_MCDI_MON + struct efx_mcdi_mon hwmon; +#endif }; +#ifdef CONFIG_SFC_MCDI_MON +static inline struct efx_mcdi_mon *efx_mcdi_mon(struct efx_nic *efx) +{ + struct siena_nic_data *nic_data; + EFX_BUG_ON_PARANOID(efx_nic_rev(efx) < EFX_REV_SIENA_A0); + nic_data = efx->nic_data; + return &nic_data->hwmon; +} +#endif + extern const struct efx_nic_type falcon_a1_nic_type; extern const struct efx_nic_type falcon_b0_nic_type; extern const struct efx_nic_type siena_a0_nic_type; diff --git a/drivers/net/ethernet/sfc/siena.c b/drivers/net/ethernet/sfc/siena.c index f05425842b3..d3c4169e2a0 100644 --- a/drivers/net/ethernet/sfc/siena.c +++ b/drivers/net/ethernet/sfc/siena.c @@ -300,6 +300,10 @@ static int siena_probe_nic(struct efx_nic *efx) goto fail5; } + rc = efx_mcdi_mon_probe(efx); + if (rc) + goto fail5; + return 0; fail5: @@ -387,6 +391,8 @@ static int siena_init_nic(struct efx_nic *efx) static void siena_remove_nic(struct efx_nic *efx) { + efx_mcdi_mon_remove(efx); + efx_nic_free_buffer(efx, &efx->irq_status); siena_reset_hw(efx, RESET_TYPE_ALL); -- cgit v1.2.3-70-g09d2 From 94813b86bf1981338de0a6e2ab50be3b4366f3bd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 6 Jan 2012 22:47:17 +0000 Subject: sfc: Update the description of SFC_MTD SFC4000 boards also have an EEPROM exposed as MTD. The boot configuration is accessed through MTD. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/Kconfig b/drivers/net/ethernet/sfc/Kconfig index ae40b666739..8d423544a7e 100644 --- a/drivers/net/ethernet/sfc/Kconfig +++ b/drivers/net/ethernet/sfc/Kconfig @@ -16,9 +16,9 @@ config SFC_MTD depends on SFC && MTD && !(SFC=y && MTD=m) default y ---help--- - This exposes the on-board flash memory as MTD devices (e.g. - /dev/mtd1). This makes it possible to upload new firmware - to the NIC. + This exposes the on-board flash and/or EEPROM as MTD devices + (e.g. /dev/mtd1). This is required to update the firmware or + the boot configuration under Linux. config SFC_MCDI_MON bool "Solarflare SFC9000-family hwmon support" depends on SFC && HWMON && !(SFC=y && HWMON=m) -- cgit v1.2.3-70-g09d2 From b249513e8ba3ca8bc2c87e78eb6e302d5d8abd6f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:41:48 +0000 Subject: sfc: Remove obsolete function efx_dev_name() Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index a4cf8cb8180..310c50f0645 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -791,15 +791,6 @@ static inline int efx_dev_registered(struct efx_nic *efx) return efx->net_dev->reg_state == NETREG_REGISTERED; } -/* Net device name, for inclusion in log messages if it has been registered. - * Use efx->name not efx->net_dev->name so that races with (un)registration - * are harmless. - */ -static inline const char *efx_dev_name(struct efx_nic *efx) -{ - return efx_dev_registered(efx) ? efx->name : ""; -} - static inline unsigned int efx_port_num(struct efx_nic *efx) { return efx->net_dev->dev_id; -- cgit v1.2.3-70-g09d2 From 73ba7b68e952d98b0885e35402b204a7a675f4a9 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:47:08 +0000 Subject: sfc: Remove remnants of on-load self-test The out-of-tree version of the sfc driver used to run a self-test on each device before registering it. Although this was never included in-tree, some functions have checks for this special case which is not really possible. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 34 +++++++++++++--------------------- drivers/net/ethernet/sfc/nic.c | 6 ++---- drivers/net/ethernet/sfc/selftest.c | 12 ++++-------- drivers/net/ethernet/sfc/tx.c | 4 +--- 4 files changed, 20 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 9d4ab5e5e1f..4f412fe22e8 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -855,10 +855,8 @@ int __efx_reconfigure_port(struct efx_nic *efx) WARN_ON(!mutex_is_locked(&efx->mac_lock)); /* Serialise the promiscuous flag with efx_set_multicast_list. */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); /* Disable PHY transmit in mac level loopbacks */ phy_mode = efx->phy_mode; @@ -981,10 +979,8 @@ static void efx_stop_port(struct efx_nic *efx) mutex_unlock(&efx->mac_lock); /* Serialise against efx_set_multicast_list() */ - if (efx_dev_registered(efx)) { - netif_addr_lock_bh(efx->net_dev); - netif_addr_unlock_bh(efx->net_dev); - } + netif_addr_lock_bh(efx->net_dev); + netif_addr_unlock_bh(efx->net_dev); } static void efx_fini_port(struct efx_nic *efx) @@ -1394,14 +1390,14 @@ static void efx_start_all(struct efx_nic *efx) return; if ((efx->state != STATE_RUNNING) && (efx->state != STATE_INIT)) return; - if (efx_dev_registered(efx) && !netif_running(efx->net_dev)) + if (!netif_running(efx->net_dev)) return; /* Mark the port as enabled so port reconfigurations can start, then * restart the transmit interface early so the watchdog timer stops */ efx_start_port(efx); - if (efx_dev_registered(efx) && netif_device_present(efx->net_dev)) + if (netif_device_present(efx->net_dev)) netif_tx_wake_all_queues(efx->net_dev); efx_for_each_channel(channel, efx) @@ -1492,11 +1488,9 @@ static void efx_stop_all(struct efx_nic *efx) /* Stop the kernel transmit interface late, so the watchdog * timer isn't ticking over the flush */ - if (efx_dev_registered(efx)) { - netif_tx_stop_all_queues(efx->net_dev); - netif_tx_lock_bh(efx->net_dev); - netif_tx_unlock_bh(efx->net_dev); - } + netif_tx_stop_all_queues(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); } static void efx_remove_all(struct efx_nic *efx) @@ -2018,11 +2012,9 @@ static void efx_unregister_netdev(struct efx_nic *efx) efx_release_tx_buffers(tx_queue); } - if (efx_dev_registered(efx)) { - strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); - device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); - unregister_netdev(efx->net_dev); - } + strlcpy(efx->name, pci_name(efx->pci_dev), sizeof(efx->name)); + device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_type); + unregister_netdev(efx->net_dev); } /************************************************************************** @@ -2438,7 +2430,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) /* NIC initialisation * * This is called at module load (or hotplug insertion, - * theoretically). It sets up PCI mappings, tests and resets the NIC, + * theoretically). It sets up PCI mappings, resets the NIC, * sets up and registers the network devices with the kernel and hooks * the interrupt service routine. It does not prepare the device for * transmission; this is left to the first time one of the network diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index de7aa1c8ebd..cd250f197b3 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -726,11 +726,9 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) tx_queue = efx_channel_get_tx_queue( channel, tx_ev_q_label % EFX_TXQ_TYPES); - if (efx_dev_registered(efx)) - netif_tx_lock(efx->net_dev); + netif_tx_lock(efx->net_dev); efx_notify_tx_desc(tx_queue); - if (efx_dev_registered(efx)) - netif_tx_unlock(efx->net_dev); + netif_tx_unlock(efx->net_dev); } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_PKT_ERR) && EFX_WORKAROUND_10727(efx)) { efx_schedule_reset(efx, RESET_TYPE_TX_DESC_FETCH); diff --git a/drivers/net/ethernet/sfc/selftest.c b/drivers/net/ethernet/sfc/selftest.c index 7def480570c..febe2a9e621 100644 --- a/drivers/net/ethernet/sfc/selftest.c +++ b/drivers/net/ethernet/sfc/selftest.c @@ -397,11 +397,9 @@ static int efx_begin_loopback(struct efx_tx_queue *tx_queue) * interrupt handler. */ smp_wmb(); - if (efx_dev_registered(efx)) - netif_tx_lock_bh(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); rc = efx_enqueue_skb(tx_queue, skb); - if (efx_dev_registered(efx)) - netif_tx_unlock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); if (rc != NETDEV_TX_OK) { netif_err(efx, drv, efx->net_dev, @@ -442,8 +440,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, int tx_done = 0, rx_good, rx_bad; int i, rc = 0; - if (efx_dev_registered(efx)) - netif_tx_lock_bh(efx->net_dev); + netif_tx_lock_bh(efx->net_dev); /* Count the number of tx completions, and decrement the refcnt. Any * skbs not already completed will be free'd when the queue is flushed */ @@ -454,8 +451,7 @@ static int efx_end_loopback(struct efx_tx_queue *tx_queue, dev_kfree_skb_any(skb); } - if (efx_dev_registered(efx)) - netif_tx_unlock_bh(efx->net_dev); + netif_tx_unlock_bh(efx->net_dev); /* Check TX completion and received packet counts */ rx_good = atomic_read(&state->rx_good); diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c index 72f0fbc73b1..5cb81fa3fcb 100644 --- a/drivers/net/ethernet/sfc/tx.c +++ b/drivers/net/ethernet/sfc/tx.c @@ -446,10 +446,8 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) likely(efx->port_enabled) && likely(netif_device_present(efx->net_dev))) { fill_level = tx_queue->insert_count - tx_queue->read_count; - if (fill_level < EFX_TXQ_THRESHOLD(efx)) { - EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); + if (fill_level < EFX_TXQ_THRESHOLD(efx)) netif_tx_wake_queue(tx_queue->core_txq); - } } /* Check whether the hardware queue is now empty */ -- cgit v1.2.3-70-g09d2 From 86ee53020abe4eb9c85e612129e3848ee98302fd Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:51:22 +0000 Subject: sfc: Use existing local variables instead of repeated indirect lookups Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 4f412fe22e8..c8e1c8a93ed 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -364,7 +364,7 @@ static int efx_probe_eventq(struct efx_channel *channel) struct efx_nic *efx = channel->efx; unsigned long entries; - netif_dbg(channel->efx, probe, channel->efx->net_dev, + netif_dbg(efx, probe, efx->net_dev, "chan %d create event queue\n", channel->channel); /* Build an event queue with room for one event per tx and rx buffer, @@ -1971,7 +1971,7 @@ static int efx_register_netdev(struct efx_nic *efx) } /* Always start with carrier off; PHY events will detect the link */ - netif_carrier_off(efx->net_dev); + netif_carrier_off(net_dev); rtnl_unlock(); -- cgit v1.2.3-70-g09d2 From 2aa9ef11e70c47ed26f831798f02ad3794e5ad41 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:53:41 +0000 Subject: sfc: Minor formatting fixes Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index c8e1c8a93ed..8ecddd05667 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -798,16 +798,14 @@ void efx_link_status_changed(struct efx_nic *efx) } /* Status message for kernel log */ - if (link_state->up) { + if (link_state->up) netif_info(efx, link, efx->net_dev, "link up at %uMbps %s-duplex (MTU %d)%s\n", link_state->speed, link_state->fd ? "full" : "half", efx->net_dev->mtu, (efx->promiscuous ? " [PROMISC]" : "")); - } else { + else netif_info(efx, link, efx->net_dev, "link down\n"); - } - } void efx_link_set_advertising(struct efx_nic *efx, u32 advertising) @@ -1741,7 +1739,8 @@ static int efx_net_stop(struct net_device *net_dev) } /* Context: process, dev_base_lock or RTNL held, non-blocking. */ -static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, struct rtnl_link_stats64 *stats) +static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) { struct efx_nic *efx = netdev_priv(net_dev); struct efx_mac_stats *mac_stats = &efx->mac_stats; -- cgit v1.2.3-70-g09d2 From 6c8eef4ac8dfd888be5b46e363f8e42b9f0d5b6a Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:54:16 +0000 Subject: sfc: Remove redundant 'rc' variable, always set to 0 Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index 8ecddd05667..fce42f428c6 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -1793,7 +1793,6 @@ static void efx_watchdog(struct net_device *net_dev) static int efx_change_mtu(struct net_device *net_dev, int new_mtu) { struct efx_nic *efx = netdev_priv(net_dev); - int rc = 0; EFX_ASSERT_RESET_SERIALISED(efx); @@ -1816,7 +1815,7 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) efx_init_channels(efx); efx_start_all(efx); - return rc; + return 0; } static int efx_set_mac_address(struct net_device *net_dev, void *data) -- cgit v1.2.3-70-g09d2 From 0fca8c97612f90a68ff6e1873e674b4d69a435db Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 9 Jan 2012 19:54:44 +0000 Subject: sfc: Rename implementation of ndo_set_rx_mode Rename efx_set_multicast_list() to efx_set_rx_mode(), in line with the operation name net_device_ops::ndo_set_rx_mode. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index fce42f428c6..a352c55cb54 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -852,7 +852,7 @@ int __efx_reconfigure_port(struct efx_nic *efx) WARN_ON(!mutex_is_locked(&efx->mac_lock)); - /* Serialise the promiscuous flag with efx_set_multicast_list. */ + /* Serialise the promiscuous flag with efx_set_rx_mode. */ netif_addr_lock_bh(efx->net_dev); netif_addr_unlock_bh(efx->net_dev); @@ -1844,7 +1844,7 @@ static int efx_set_mac_address(struct net_device *net_dev, void *data) } /* Context: netif_addr_lock held, BHs disabled. */ -static void efx_set_multicast_list(struct net_device *net_dev) +static void efx_set_rx_mode(struct net_device *net_dev) { struct efx_nic *efx = netdev_priv(net_dev); struct netdev_hw_addr *ha; @@ -1898,7 +1898,7 @@ static const struct net_device_ops efx_netdev_ops = { .ndo_do_ioctl = efx_ioctl, .ndo_change_mtu = efx_change_mtu, .ndo_set_mac_address = efx_set_mac_address, - .ndo_set_rx_mode = efx_set_multicast_list, + .ndo_set_rx_mode = efx_set_rx_mode, .ndo_set_features = efx_set_features, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = efx_netpoll, -- cgit v1.2.3-70-g09d2 From f9c762500ae77ab8940094be1325c8a2a1c8e5f5 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 12 Oct 2011 17:20:25 +0100 Subject: sfc: Make all MAC statistics consistently 64 bits wide Currently we use type u64 for byte counts, which can very quickly exceed 2^32, and unsigned long for packet counts, which do not. But it can still take only 20-something minutes to send or receive 2^32 packets, and not all tools properly handle overflow even if they sample more often than this. The MAC statistics are all updated synchronously, so it costs very little to make them all 64-bit regardless of native word size. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/ethtool.c | 117 ++++++++++++++++------------------ drivers/net/ethernet/sfc/net_driver.h | 110 ++++++++++++++++---------------- 2 files changed, 109 insertions(+), 118 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/ethtool.c b/drivers/net/ethernet/sfc/ethtool.c index ba901167801..f887f65e418 100644 --- a/drivers/net/ethernet/sfc/ethtool.c +++ b/drivers/net/ethernet/sfc/ethtool.c @@ -52,11 +52,6 @@ static u64 efx_get_uint_stat(void *field) return *(unsigned int *)field; } -static u64 efx_get_ulong_stat(void *field) -{ - return *(unsigned long *)field; -} - static u64 efx_get_u64_stat(void *field) { return *(u64 *) field; @@ -67,10 +62,6 @@ static u64 efx_get_atomic_stat(void *field) return atomic_read((atomic_t *) field); } -#define EFX_ETHTOOL_ULONG_MAC_STAT(field) \ - EFX_ETHTOOL_STAT(field, mac_stats, field, \ - unsigned long, efx_get_ulong_stat) - #define EFX_ETHTOOL_U64_MAC_STAT(field) \ EFX_ETHTOOL_STAT(field, mac_stats, field, \ u64, efx_get_u64_stat) @@ -95,32 +86,32 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(tx_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(tx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_single_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_multiple_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_late_collision), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_excessive_deferred), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_non_tcpudp), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_mac_src_error), - EFX_ETHTOOL_ULONG_MAC_STAT(tx_ip_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_packets), + EFX_ETHTOOL_U64_MAC_STAT(tx_bad), + EFX_ETHTOOL_U64_MAC_STAT(tx_pause), + EFX_ETHTOOL_U64_MAC_STAT(tx_control), + EFX_ETHTOOL_U64_MAC_STAT(tx_unicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_multicast), + EFX_ETHTOOL_U64_MAC_STAT(tx_broadcast), + EFX_ETHTOOL_U64_MAC_STAT(tx_lt64), + EFX_ETHTOOL_U64_MAC_STAT(tx_64), + EFX_ETHTOOL_U64_MAC_STAT(tx_65_to_127), + EFX_ETHTOOL_U64_MAC_STAT(tx_128_to_255), + EFX_ETHTOOL_U64_MAC_STAT(tx_256_to_511), + EFX_ETHTOOL_U64_MAC_STAT(tx_512_to_1023), + EFX_ETHTOOL_U64_MAC_STAT(tx_1024_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(tx_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(tx_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_single_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_multiple_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_late_collision), + EFX_ETHTOOL_U64_MAC_STAT(tx_excessive_deferred), + EFX_ETHTOOL_U64_MAC_STAT(tx_non_tcpudp), + EFX_ETHTOOL_U64_MAC_STAT(tx_mac_src_error), + EFX_ETHTOOL_U64_MAC_STAT(tx_ip_src_error), EFX_ETHTOOL_UINT_TXQ_STAT(tso_bursts), EFX_ETHTOOL_UINT_TXQ_STAT(tso_long_headers), EFX_ETHTOOL_UINT_TXQ_STAT(tso_packets), @@ -128,34 +119,34 @@ static const struct efx_ethtool_stat efx_ethtool_stats[] = { EFX_ETHTOOL_U64_MAC_STAT(rx_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_good_bytes), EFX_ETHTOOL_U64_MAC_STAT(rx_bad_bytes), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_packets), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_good), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_pause), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_control), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_unicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_multicast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_broadcast), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_65_to_127), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_128_to_255), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_256_to_511), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_512_to_1023), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_1024_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_lt64), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_64_to_15xx), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_15xx_to_jumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_bad_gtjumbo), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_overflow), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_missed), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_false_carrier), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_symbol_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_align_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_length_error), - EFX_ETHTOOL_ULONG_MAC_STAT(rx_internal_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_packets), + EFX_ETHTOOL_U64_MAC_STAT(rx_good), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad), + EFX_ETHTOOL_U64_MAC_STAT(rx_pause), + EFX_ETHTOOL_U64_MAC_STAT(rx_control), + EFX_ETHTOOL_U64_MAC_STAT(rx_unicast), + EFX_ETHTOOL_U64_MAC_STAT(rx_multicast), + EFX_ETHTOOL_U64_MAC_STAT(rx_broadcast), + EFX_ETHTOOL_U64_MAC_STAT(rx_lt64), + EFX_ETHTOOL_U64_MAC_STAT(rx_64), + EFX_ETHTOOL_U64_MAC_STAT(rx_65_to_127), + EFX_ETHTOOL_U64_MAC_STAT(rx_128_to_255), + EFX_ETHTOOL_U64_MAC_STAT(rx_256_to_511), + EFX_ETHTOOL_U64_MAC_STAT(rx_512_to_1023), + EFX_ETHTOOL_U64_MAC_STAT(rx_1024_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(rx_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_lt64), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_64_to_15xx), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_15xx_to_jumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_bad_gtjumbo), + EFX_ETHTOOL_U64_MAC_STAT(rx_overflow), + EFX_ETHTOOL_U64_MAC_STAT(rx_missed), + EFX_ETHTOOL_U64_MAC_STAT(rx_false_carrier), + EFX_ETHTOOL_U64_MAC_STAT(rx_symbol_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_align_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_length_error), + EFX_ETHTOOL_U64_MAC_STAT(rx_internal_error), EFX_ETHTOOL_UINT_NIC_STAT(rx_nodesc_drop_cnt), EFX_ETHTOOL_ATOMIC_NIC_ERROR_STAT(rx_reset), EFX_ETHTOOL_UINT_CHANNEL_STAT(rx_tobe_disc), diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 310c50f0645..c20483efc22 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -538,64 +538,64 @@ struct efx_mac_stats { u64 tx_bytes; u64 tx_good_bytes; u64 tx_bad_bytes; - unsigned long tx_packets; - unsigned long tx_bad; - unsigned long tx_pause; - unsigned long tx_control; - unsigned long tx_unicast; - unsigned long tx_multicast; - unsigned long tx_broadcast; - unsigned long tx_lt64; - unsigned long tx_64; - unsigned long tx_65_to_127; - unsigned long tx_128_to_255; - unsigned long tx_256_to_511; - unsigned long tx_512_to_1023; - unsigned long tx_1024_to_15xx; - unsigned long tx_15xx_to_jumbo; - unsigned long tx_gtjumbo; - unsigned long tx_collision; - unsigned long tx_single_collision; - unsigned long tx_multiple_collision; - unsigned long tx_excessive_collision; - unsigned long tx_deferred; - unsigned long tx_late_collision; - unsigned long tx_excessive_deferred; - unsigned long tx_non_tcpudp; - unsigned long tx_mac_src_error; - unsigned long tx_ip_src_error; + u64 tx_packets; + u64 tx_bad; + u64 tx_pause; + u64 tx_control; + u64 tx_unicast; + u64 tx_multicast; + u64 tx_broadcast; + u64 tx_lt64; + u64 tx_64; + u64 tx_65_to_127; + u64 tx_128_to_255; + u64 tx_256_to_511; + u64 tx_512_to_1023; + u64 tx_1024_to_15xx; + u64 tx_15xx_to_jumbo; + u64 tx_gtjumbo; + u64 tx_collision; + u64 tx_single_collision; + u64 tx_multiple_collision; + u64 tx_excessive_collision; + u64 tx_deferred; + u64 tx_late_collision; + u64 tx_excessive_deferred; + u64 tx_non_tcpudp; + u64 tx_mac_src_error; + u64 tx_ip_src_error; u64 rx_bytes; u64 rx_good_bytes; u64 rx_bad_bytes; - unsigned long rx_packets; - unsigned long rx_good; - unsigned long rx_bad; - unsigned long rx_pause; - unsigned long rx_control; - unsigned long rx_unicast; - unsigned long rx_multicast; - unsigned long rx_broadcast; - unsigned long rx_lt64; - unsigned long rx_64; - unsigned long rx_65_to_127; - unsigned long rx_128_to_255; - unsigned long rx_256_to_511; - unsigned long rx_512_to_1023; - unsigned long rx_1024_to_15xx; - unsigned long rx_15xx_to_jumbo; - unsigned long rx_gtjumbo; - unsigned long rx_bad_lt64; - unsigned long rx_bad_64_to_15xx; - unsigned long rx_bad_15xx_to_jumbo; - unsigned long rx_bad_gtjumbo; - unsigned long rx_overflow; - unsigned long rx_missed; - unsigned long rx_false_carrier; - unsigned long rx_symbol_error; - unsigned long rx_align_error; - unsigned long rx_length_error; - unsigned long rx_internal_error; - unsigned long rx_good_lt64; + u64 rx_packets; + u64 rx_good; + u64 rx_bad; + u64 rx_pause; + u64 rx_control; + u64 rx_unicast; + u64 rx_multicast; + u64 rx_broadcast; + u64 rx_lt64; + u64 rx_64; + u64 rx_65_to_127; + u64 rx_128_to_255; + u64 rx_256_to_511; + u64 rx_512_to_1023; + u64 rx_1024_to_15xx; + u64 rx_15xx_to_jumbo; + u64 rx_gtjumbo; + u64 rx_bad_lt64; + u64 rx_bad_64_to_15xx; + u64 rx_bad_15xx_to_jumbo; + u64 rx_bad_gtjumbo; + u64 rx_overflow; + u64 rx_missed; + u64 rx_false_carrier; + u64 rx_symbol_error; + u64 rx_align_error; + u64 rx_length_error; + u64 rx_internal_error; + u64 rx_good_lt64; }; /* Number of bits used in a multicast filter hash address */ -- cgit v1.2.3-70-g09d2 From 1ddceb4c69463e09b6929c750046c59589d45d82 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 23 Jan 2012 22:41:30 +0000 Subject: sfc: Move the end of the non-GRO RX path into its own function Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index 3572c34a79f..d97c6ebcf06 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -568,12 +568,30 @@ out: channel->rx_pkt_csummed = checksummed; } +static void efx_rx_deliver(struct efx_channel *channel, + struct efx_rx_buffer *rx_buf) +{ + struct sk_buff *skb; + + /* We now own the SKB */ + skb = rx_buf->u.skb; + rx_buf->u.skb = NULL; + + /* Set the SKB flags */ + skb_checksum_none_assert(skb); + + /* Pass the packet up */ + netif_receive_skb(skb); + + /* Update allocation strategy method */ + channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; +} + /* Handle a received packet. Second half: Touches packet payload. */ void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, bool checksummed) { struct efx_nic *efx = channel->efx; - struct sk_buff *skb; u8 *eh = efx_rx_buf_eh(efx, rx_buf); /* If we're in loopback test, then pass the packet directly to the @@ -586,7 +604,7 @@ void __efx_rx_packet(struct efx_channel *channel, } if (!rx_buf->is_page) { - skb = rx_buf->u.skb; + struct sk_buff *skb = rx_buf->u.skb; prefetch(skb_shinfo(skb)); @@ -606,23 +624,10 @@ void __efx_rx_packet(struct efx_channel *channel, if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) checksummed = false; - if (likely(checksummed || rx_buf->is_page)) { + if (likely(checksummed || rx_buf->is_page)) efx_rx_packet_gro(channel, rx_buf, eh, checksummed); - return; - } - - /* We now own the SKB */ - skb = rx_buf->u.skb; - rx_buf->u.skb = NULL; - - /* Set the SKB flags */ - skb_checksum_none_assert(skb); - - /* Pass the packet up */ - netif_receive_skb(skb); - - /* Update allocation strategy method */ - channel->rx_alloc_level += RX_ALLOC_FACTOR_SKB; + else + efx_rx_deliver(channel, rx_buf); } void efx_rx_strategy(struct efx_channel *channel) -- cgit v1.2.3-70-g09d2 From db3395697cad6e9dff8d21249e0b59dc9bb83b48 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 26 Aug 2011 18:05:11 +0100 Subject: sfc: Replace efx_rx_buffer::is_page and other booleans with a flags field Replace checksummed and discard booleans from efx_handle_rx_event() with a bitmask, added to the flags field. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 3 +- drivers/net/ethernet/sfc/efx.h | 4 +-- drivers/net/ethernet/sfc/net_driver.h | 16 +++++---- drivers/net/ethernet/sfc/nic.c | 32 ++++++++--------- drivers/net/ethernet/sfc/rx.c | 65 +++++++++++++++++------------------ 5 files changed, 59 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index a352c55cb54..952d0bf7695 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -229,8 +229,7 @@ static int efx_process_channel(struct efx_channel *channel, int budget) /* Deliver last RX packet. */ if (channel->rx_pkt) { - __efx_rx_packet(channel, channel->rx_pkt, - channel->rx_pkt_csummed); + __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = NULL; } diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index e0b66d158d7..7f546e2c39e 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -40,9 +40,9 @@ extern void efx_rx_strategy(struct efx_channel *channel); extern void efx_fast_push_rx_descriptors(struct efx_rx_queue *rx_queue); extern void efx_rx_slow_fill(unsigned long context); extern void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, bool checksummed); + struct efx_rx_buffer *rx_buf); extern void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, bool checksummed, bool discard); + unsigned int len, u16 flags); extern void efx_schedule_slow_fill(struct efx_rx_queue *rx_queue); #define EFX_MAX_DMAQ_SIZE 4096UL diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index c20483efc22..53864014c2b 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -205,12 +205,12 @@ struct efx_tx_queue { /** * struct efx_rx_buffer - An Efx RX data buffer * @dma_addr: DMA base address of the buffer - * @skb: The associated socket buffer, if any. - * If both this and page are %NULL, the buffer slot is currently free. - * @page: The associated page buffer, if any. - * If both this and skb are %NULL, the buffer slot is currently free. + * @skb: The associated socket buffer. Valid iff !(@flags & %EFX_RX_BUF_PAGE). + * Will be %NULL if the buffer slot is currently free. + * @page: The associated page buffer. Valif iff @flags & %EFX_RX_BUF_PAGE. + * Will be %NULL if the buffer slot is currently free. * @len: Buffer length, in bytes. - * @is_page: Indicates if @page is valid. If false, @skb is valid. + * @flags: Flags for buffer and packet state. */ struct efx_rx_buffer { dma_addr_t dma_addr; @@ -219,8 +219,11 @@ struct efx_rx_buffer { struct page *page; } u; unsigned int len; - bool is_page; + u16 flags; }; +#define EFX_RX_BUF_PAGE 0x0001 +#define EFX_RX_PKT_CSUMMED 0x0002 +#define EFX_RX_PKT_DISCARD 0x0004 /** * struct efx_rx_page_state - Page-based rx buffer state @@ -378,7 +381,6 @@ struct efx_channel { * access with prefetches. */ struct efx_rx_buffer *rx_pkt; - bool rx_pkt_csummed; struct efx_rx_queue rx_queue; struct efx_tx_queue tx_queue[EFX_TXQ_TYPES]; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index cd250f197b3..a43d1ca270c 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -743,10 +743,8 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event) } /* Detect errors included in the rx_evt_pkt_ok bit. */ -static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, - const efx_qword_t *event, - bool *rx_ev_pkt_ok, - bool *discard) +static u16 efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, + const efx_qword_t *event) { struct efx_channel *channel = efx_rx_queue_channel(rx_queue); struct efx_nic *efx = rx_queue->efx; @@ -791,10 +789,6 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, ++channel->n_rx_tcp_udp_chksum_err; } - /* The frame must be discarded if any of these are true. */ - *discard = (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | - rx_ev_tobe_disc | rx_ev_pause_frm); - /* TOBE_DISC is expected on unicast mismatches; don't print out an * error message. FRM_TRUNC indicates RXDP dropped the packet due * to a FIFO overflow. @@ -817,6 +811,11 @@ static void efx_handle_rx_not_ok(struct efx_rx_queue *rx_queue, rx_ev_pause_frm ? " [PAUSE]" : ""); } #endif + + /* The frame must be discarded if any of these are true. */ + return (rx_ev_eth_crc_err | rx_ev_frm_trunc | rx_ev_drib_nib | + rx_ev_tobe_disc | rx_ev_pause_frm) ? + EFX_RX_PKT_DISCARD : 0; } /* Handle receive events that are not in-order. */ @@ -849,7 +848,8 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) unsigned int rx_ev_desc_ptr, rx_ev_byte_cnt; unsigned int rx_ev_hdr_type, rx_ev_mcast_pkt; unsigned expected_ptr; - bool rx_ev_pkt_ok, discard = false, checksummed; + bool rx_ev_pkt_ok; + u16 flags; struct efx_rx_queue *rx_queue; /* Basic packet information */ @@ -872,12 +872,11 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) /* If packet is marked as OK and packet type is TCP/IP or * UDP/IP, then we can rely on the hardware checksum. */ - checksummed = - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || - rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP; + flags = (rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_TCP || + rx_ev_hdr_type == FSE_CZ_RX_EV_HDR_TYPE_IPV4V6_UDP) ? + EFX_RX_PKT_CSUMMED : 0; } else { - efx_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, &discard); - checksummed = false; + flags = efx_handle_rx_not_ok(rx_queue, event); } /* Detect multicast packets that didn't match the filter */ @@ -888,15 +887,14 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event) if (unlikely(!rx_ev_mcast_hash_match)) { ++channel->n_rx_mcast_mismatch; - discard = true; + flags |= EFX_RX_PKT_DISCARD; } } channel->irq_mod_score += 2; /* Handle received packet */ - efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, - checksummed, discard); + efx_rx_packet(rx_queue, rx_ev_desc_ptr, rx_ev_byte_cnt, flags); } static void diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index d97c6ebcf06..a33aef25ead 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -108,7 +108,7 @@ static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) static u8 *efx_rx_buf_eh(struct efx_nic *efx, struct efx_rx_buffer *buf) { - if (buf->is_page) + if (buf->flags & EFX_RX_BUF_PAGE) return page_address(buf->u.page) + efx_rx_buf_offset(efx, buf); else return (u8 *)buf->u.skb->data + efx->type->rx_buffer_hash_size; @@ -158,7 +158,7 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue) /* Adjust the SKB for padding and checksum */ skb_reserve(skb, NET_IP_ALIGN); rx_buf->len = skb_len - NET_IP_ALIGN; - rx_buf->is_page = false; + rx_buf->flags = 0; skb->ip_summed = CHECKSUM_UNNECESSARY; rx_buf->dma_addr = pci_map_single(efx->pci_dev, @@ -227,7 +227,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN; rx_buf->u.page = page; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; - rx_buf->is_page = true; + rx_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; ++rx_queue->alloc_page_count; ++state->refcnt; @@ -248,7 +248,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) static void efx_unmap_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if (rx_buf->is_page && rx_buf->u.page) { + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { struct efx_rx_page_state *state; state = page_address(rx_buf->u.page); @@ -258,7 +258,7 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, efx_rx_buf_size(efx), PCI_DMA_FROMDEVICE); } - } else if (!rx_buf->is_page && rx_buf->u.skb) { + } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { pci_unmap_single(efx->pci_dev, rx_buf->dma_addr, rx_buf->len, PCI_DMA_FROMDEVICE); } @@ -267,10 +267,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, static void efx_free_rx_buffer(struct efx_nic *efx, struct efx_rx_buffer *rx_buf) { - if (rx_buf->is_page && rx_buf->u.page) { + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { __free_pages(rx_buf->u.page, efx->rx_buffer_order); rx_buf->u.page = NULL; - } else if (!rx_buf->is_page && rx_buf->u.skb) { + } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { dev_kfree_skb_any(rx_buf->u.skb); rx_buf->u.skb = NULL; } @@ -310,7 +310,7 @@ static void efx_resurrect_rx_buffer(struct efx_rx_queue *rx_queue, new_buf->dma_addr = rx_buf->dma_addr ^ (PAGE_SIZE >> 1); new_buf->u.page = rx_buf->u.page; new_buf->len = rx_buf->len; - new_buf->is_page = true; + new_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; } @@ -324,7 +324,10 @@ static void efx_recycle_rx_buffer(struct efx_channel *channel, struct efx_rx_buffer *new_buf; unsigned index; - if (rx_buf->is_page && efx->rx_buffer_len <= EFX_RX_HALF_PAGE && + rx_buf->flags &= EFX_RX_BUF_PAGE; + + if ((rx_buf->flags & EFX_RX_BUF_PAGE) && + efx->rx_buffer_len <= EFX_RX_HALF_PAGE && page_count(rx_buf->u.page) == 1) efx_resurrect_rx_buffer(rx_queue, rx_buf); @@ -411,8 +414,7 @@ void efx_rx_slow_fill(unsigned long context) static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf, - int len, bool *discard, - bool *leak_packet) + int len, bool *leak_packet) { struct efx_nic *efx = rx_queue->efx; unsigned max_len = rx_buf->len - efx->type->rx_buffer_padding; @@ -423,7 +425,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, /* The packet must be discarded, but this is only a fatal error * if the caller indicated it was */ - *discard = true; + rx_buf->flags |= EFX_RX_PKT_DISCARD; if ((len > rx_buf->len) && EFX_WORKAROUND_8071(efx)) { if (net_ratelimit()) @@ -436,7 +438,7 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, * data at the end of the skb will be trashed. So * we have no choice but to leak the fragment. */ - *leak_packet = !rx_buf->is_page; + *leak_packet = !(rx_buf->flags & EFX_RX_BUF_PAGE); efx_schedule_reset(efx, RESET_TYPE_RX_RECOVERY); } else { if (net_ratelimit()) @@ -456,13 +458,13 @@ static void efx_rx_packet__check_len(struct efx_rx_queue *rx_queue, */ static void efx_rx_packet_gro(struct efx_channel *channel, struct efx_rx_buffer *rx_buf, - const u8 *eh, bool checksummed) + const u8 *eh) { struct napi_struct *napi = &channel->napi_str; gro_result_t gro_result; /* Pass the skb/page into the GRO engine */ - if (rx_buf->is_page) { + if (rx_buf->flags & EFX_RX_BUF_PAGE) { struct efx_nic *efx = channel->efx; struct page *page = rx_buf->u.page; struct sk_buff *skb; @@ -484,8 +486,8 @@ static void efx_rx_packet_gro(struct efx_channel *channel, skb->len = rx_buf->len; skb->data_len = rx_buf->len; skb->truesize += rx_buf->len; - skb->ip_summed = - checksummed ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE; + skb->ip_summed = ((rx_buf->flags & EFX_RX_PKT_CSUMMED) ? + CHECKSUM_UNNECESSARY : CHECKSUM_NONE); skb_record_rx_queue(skb, channel->channel); @@ -493,7 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, } else { struct sk_buff *skb = rx_buf->u.skb; - EFX_BUG_ON_PARANOID(!checksummed); + EFX_BUG_ON_PARANOID(!(rx_buf->flags & EFX_RX_PKT_CSUMMED)); rx_buf->u.skb = NULL; gro_result = napi_gro_receive(napi, skb); @@ -508,7 +510,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel, } void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, - unsigned int len, bool checksummed, bool discard) + unsigned int len, u16 flags) { struct efx_nic *efx = rx_queue->efx; struct efx_channel *channel = efx_rx_queue_channel(rx_queue); @@ -516,6 +518,7 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, bool leak_packet = false; rx_buf = efx_rx_buffer(rx_queue, index); + rx_buf->flags |= flags; /* This allows the refill path to post another buffer. * EFX_RXD_HEAD_ROOM ensures that the slot we are using @@ -524,18 +527,17 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_queue->removed_count++; /* Validate the length encoded in the event vs the descriptor pushed */ - efx_rx_packet__check_len(rx_queue, rx_buf, len, - &discard, &leak_packet); + efx_rx_packet__check_len(rx_queue, rx_buf, len, &leak_packet); netif_vdbg(efx, rx_status, efx->net_dev, "RX queue %d received id %x at %llx+%x %s%s\n", efx_rx_queue_index(rx_queue), index, (unsigned long long)rx_buf->dma_addr, len, - (checksummed ? " [SUMMED]" : ""), - (discard ? " [DISCARD]" : "")); + (rx_buf->flags & EFX_RX_PKT_CSUMMED) ? " [SUMMED]" : "", + (rx_buf->flags & EFX_RX_PKT_DISCARD) ? " [DISCARD]" : ""); /* Discard packet, if instructed to do so */ - if (unlikely(discard)) { + if (unlikely(rx_buf->flags & EFX_RX_PKT_DISCARD)) { if (unlikely(leak_packet)) channel->n_skbuff_leaks++; else @@ -562,10 +564,8 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, rx_buf->len = len - efx->type->rx_buffer_hash_size; out: if (channel->rx_pkt) - __efx_rx_packet(channel, - channel->rx_pkt, channel->rx_pkt_csummed); + __efx_rx_packet(channel, channel->rx_pkt); channel->rx_pkt = rx_buf; - channel->rx_pkt_csummed = checksummed; } static void efx_rx_deliver(struct efx_channel *channel, @@ -588,8 +588,7 @@ static void efx_rx_deliver(struct efx_channel *channel, } /* Handle a received packet. Second half: Touches packet payload. */ -void __efx_rx_packet(struct efx_channel *channel, - struct efx_rx_buffer *rx_buf, bool checksummed) +void __efx_rx_packet(struct efx_channel *channel, struct efx_rx_buffer *rx_buf) { struct efx_nic *efx = channel->efx; u8 *eh = efx_rx_buf_eh(efx, rx_buf); @@ -603,7 +602,7 @@ void __efx_rx_packet(struct efx_channel *channel, return; } - if (!rx_buf->is_page) { + if (!(rx_buf->flags & EFX_RX_BUF_PAGE)) { struct sk_buff *skb = rx_buf->u.skb; prefetch(skb_shinfo(skb)); @@ -622,10 +621,10 @@ void __efx_rx_packet(struct efx_channel *channel, } if (unlikely(!(efx->net_dev->features & NETIF_F_RXCSUM))) - checksummed = false; + rx_buf->flags &= ~EFX_RX_PKT_CSUMMED; - if (likely(checksummed || rx_buf->is_page)) - efx_rx_packet_gro(channel, rx_buf, eh, checksummed); + if (likely(rx_buf->flags & (EFX_RX_BUF_PAGE | EFX_RX_PKT_CSUMMED))) + efx_rx_packet_gro(channel, rx_buf, eh); else efx_rx_deliver(channel, rx_buf); } -- cgit v1.2.3-70-g09d2 From 3bd391f056df61e928de1680ff4a3e7e07e5b399 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:06 +0100 Subject: crypto: Add support for x86 cpuid auto loading for x86 crypto drivers Add support for auto-loading of crypto drivers based on cpuid features. This enables auto-loading of the VIA and Intel specific drivers for AES, hashing and CRCs. Requires the earlier infrastructure patch to add x86 modinfo. I kept it all in a single patch for now. I dropped the printks when the driver cpuid doesn't match (imho drivers never should print anything in such a case) One drawback is that udev doesn't know if the drivers are used or not, so they will be unconditionally loaded at boot up. That's better than not loading them at all, like it often happens. Cc: Dave Jones Cc: Kay Sievers Cc: Jen Axboe Cc: Herbert Xu Cc: Huang Ying Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- arch/x86/crypto/aesni-intel_glue.c | 12 +++++++++--- arch/x86/crypto/crc32c-intel.c | 11 ++++++++--- arch/x86/crypto/ghash-clmulni-intel_glue.c | 12 ++++++++---- drivers/crypto/padlock-aes.c | 9 ++++++++- drivers/crypto/padlock-sha.c | 16 ++++++++-------- 5 files changed, 41 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 545d0ce5981..b3350bd32c6 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1253,14 +1254,19 @@ static struct crypto_alg __rfc4106_alg = { }; #endif + +static const struct x86_cpu_id aesni_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_AES), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, aesni_cpu_id); + static int __init aesni_init(void) { int err; - if (!cpu_has_aes) { - printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); + if (!x86_match_cpu(aesni_cpu_id)) return -ENODEV; - } if ((err = crypto_fpu_init())) goto fpu_err; diff --git a/arch/x86/crypto/crc32c-intel.c b/arch/x86/crypto/crc32c-intel.c index b9d00261703..493f959261f 100644 --- a/arch/x86/crypto/crc32c-intel.c +++ b/arch/x86/crypto/crc32c-intel.c @@ -31,6 +31,7 @@ #include #include +#include #define CHKSUM_BLOCK_SIZE 1 #define CHKSUM_DIGEST_SIZE 4 @@ -173,13 +174,17 @@ static struct shash_alg alg = { } }; +static const struct x86_cpu_id crc32c_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_XMM4_2), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, crc32c_cpu_id); static int __init crc32c_intel_mod_init(void) { - if (cpu_has_xmm4_2) - return crypto_register_shash(&alg); - else + if (!x86_match_cpu(crc32c_cpu_id)) return -ENODEV; + return crypto_register_shash(&alg); } static void __exit crc32c_intel_mod_fini(void) diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index 976aa64d9a2..b4bf0a63b52 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c @@ -20,6 +20,7 @@ #include #include #include +#include #define GHASH_BLOCK_SIZE 16 #define GHASH_DIGEST_SIZE 16 @@ -294,15 +295,18 @@ static struct ahash_alg ghash_async_alg = { }, }; +static const struct x86_cpu_id pcmul_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_PCLMULQDQ), /* Pickle-Mickle-Duck */ + {} +}; +MODULE_DEVICE_TABLE(x86cpu, pcmul_cpu_id); + static int __init ghash_pclmulqdqni_mod_init(void) { int err; - if (!cpu_has_pclmulqdq) { - printk(KERN_INFO "Intel PCLMULQDQ-NI instructions are not" - " detected.\n"); + if (!x86_match_cpu(pcmul_cpu_id)) return -ENODEV; - } err = crypto_register_shash(&ghash_alg); if (err) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 29b9469f837..37b2e9406af 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -503,12 +504,18 @@ static struct crypto_alg cbc_aes_alg = { } }; +static struct x86_cpu_id padlock_cpu_id[] = { + X86_FEATURE_MATCH(X86_FEATURE_XCRYPT), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, padlock_cpu_id); + static int __init padlock_init(void) { int ret; struct cpuinfo_x86 *c = &cpu_data(0); - if (!cpu_has_xcrypt) + if (!x86_match_cpu(padlock_cpu_id)) return -ENODEV; if (!cpu_has_xcrypt_enabled) { diff --git a/drivers/crypto/padlock-sha.c b/drivers/crypto/padlock-sha.c index 06bdb4b2c6a..9266c0e2549 100644 --- a/drivers/crypto/padlock-sha.c +++ b/drivers/crypto/padlock-sha.c @@ -22,6 +22,7 @@ #include #include #include +#include #include struct padlock_sha_desc { @@ -526,6 +527,12 @@ static struct shash_alg sha256_alg_nano = { } }; +static struct x86_cpu_id padlock_sha_ids[] = { + X86_FEATURE_MATCH(X86_FEATURE_PHE), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, padlock_sha_ids); + static int __init padlock_init(void) { int rc = -ENODEV; @@ -533,15 +540,8 @@ static int __init padlock_init(void) struct shash_alg *sha1; struct shash_alg *sha256; - if (!cpu_has_phe) { - printk(KERN_NOTICE PFX "VIA PadLock Hash Engine not detected.\n"); - return -ENODEV; - } - - if (!cpu_has_phe_enabled) { - printk(KERN_NOTICE PFX "VIA PadLock detected, but not enabled. Hmm, strange...\n"); + if (!x86_match_cpu(padlock_sha_ids) || !cpu_has_phe_enabled) return -ENODEV; - } /* Register the newly added algorithm module if on * * VIA Nano processor, or else just do as before */ -- cgit v1.2.3-70-g09d2 From b66b8b9a4a79087dde1b358a016e5c8739ccf186 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:07 +0100 Subject: intel-idle: convert to x86_cpu_id auto probing With this it should be automatically loaded on suitable systems by udev. The old switch () is replaced with a table based approach, this also cleans up the code. Cc: Len Brown Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/idle/intel_idle.c | 116 ++++++++++++++++++++++++++-------------------- 1 file changed, 66 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 20bce51c2e8..ef6a409ff1a 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include @@ -81,18 +82,23 @@ static unsigned int mwait_substates; /* Reliable LAPIC Timer States, bit 1 for C1 etc. */ static unsigned int lapic_timer_reliable_states = (1 << 1); /* Default to only C1 */ +struct idle_cpu { + struct cpuidle_state *state_table; + + /* + * Hardware C-state auto-demotion may not always be optimal. + * Indicate which enable bits to clear here. + */ + unsigned long auto_demotion_disable_flags; +}; + +static const struct idle_cpu *icpu; static struct cpuidle_device __percpu *intel_idle_cpuidle_devices; static int intel_idle(struct cpuidle_device *dev, struct cpuidle_driver *drv, int index); static struct cpuidle_state *cpuidle_state_table; -/* - * Hardware C-state auto-demotion may not always be optimal. - * Indicate which enable bits to clear here. - */ -static unsigned long long auto_demotion_disable_flags; - /* * Set this flag for states where the HW flushes the TLB for us * and so we don't need cross-calls to keep it consistent. @@ -319,27 +325,72 @@ static void auto_demotion_disable(void *dummy) unsigned long long msr_bits; rdmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); - msr_bits &= ~auto_demotion_disable_flags; + msr_bits &= ~(icpu->auto_demotion_disable_flags); wrmsrl(MSR_NHM_SNB_PKG_CST_CFG_CTL, msr_bits); } +static const struct idle_cpu idle_cpu_nehalem = { + .state_table = nehalem_cstates, +}; + +static const struct idle_cpu idle_cpu_westmere = { + .state_table = nehalem_cstates, + .auto_demotion_disable_flags = NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE, +}; + +static const struct idle_cpu idle_cpu_atom = { + .state_table = atom_cstates, +}; + +static const struct idle_cpu idle_cpu_lincroft = { + .state_table = atom_cstates, + .auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE, +}; + +static const struct idle_cpu idle_cpu_snb = { + .state_table = snb_cstates, +}; + +#define ICPU(model, cpu) \ + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_MWAIT, (unsigned long)&cpu } + +static const struct x86_cpu_id intel_idle_ids[] = { + ICPU(0x1a, idle_cpu_nehalem), + ICPU(0x1e, idle_cpu_nehalem), + ICPU(0x1f, idle_cpu_nehalem), + ICPU(0x25, idle_cpu_westmere), + ICPU(0x2c, idle_cpu_westmere), + ICPU(0x2f, idle_cpu_westmere), + ICPU(0x1c, idle_cpu_atom), + ICPU(0x26, idle_cpu_lincroft), + ICPU(0x2f, idle_cpu_westmere), + ICPU(0x2a, idle_cpu_snb), + ICPU(0x2d, idle_cpu_snb), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, intel_idle_ids); + /* * intel_idle_probe() */ static int intel_idle_probe(void) { unsigned int eax, ebx, ecx; + const struct x86_cpu_id *id; if (max_cstate == 0) { pr_debug(PREFIX "disabled\n"); return -EPERM; } - if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - if (!boot_cpu_has(X86_FEATURE_MWAIT)) + id = x86_match_cpu(intel_idle_ids); + if (!id) { + if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && + boot_cpu_data.x86 == 6) + pr_debug(PREFIX "does not run on family %d model %d\n", + boot_cpu_data.x86, boot_cpu_data.x86_model); return -ENODEV; + } if (boot_cpu_data.cpuid_level < CPUID_MWAIT_LEAF) return -ENODEV; @@ -353,43 +404,8 @@ static int intel_idle_probe(void) pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); - - if (boot_cpu_data.x86 != 6) /* family 6 */ - return -ENODEV; - - switch (boot_cpu_data.x86_model) { - - case 0x1A: /* Core i7, Xeon 5500 series */ - case 0x1E: /* Core i7 and i5 Processor - Lynnfield Jasper Forest */ - case 0x1F: /* Core i7 and i5 Processor - Nehalem */ - case 0x2E: /* Nehalem-EX Xeon */ - case 0x2F: /* Westmere-EX Xeon */ - case 0x25: /* Westmere */ - case 0x2C: /* Westmere */ - cpuidle_state_table = nehalem_cstates; - auto_demotion_disable_flags = - (NHM_C1_AUTO_DEMOTE | NHM_C3_AUTO_DEMOTE); - break; - - case 0x1C: /* 28 - Atom Processor */ - cpuidle_state_table = atom_cstates; - break; - - case 0x26: /* 38 - Lincroft Atom Processor */ - cpuidle_state_table = atom_cstates; - auto_demotion_disable_flags = ATM_LNC_C6_AUTO_DEMOTE; - break; - - case 0x2A: /* SNB */ - case 0x2D: /* SNB Xeon */ - cpuidle_state_table = snb_cstates; - break; - - default: - pr_debug(PREFIX "does not run on family %d model %d\n", - boot_cpu_data.x86, boot_cpu_data.x86_model); - return -ENODEV; - } + icpu = (const struct idle_cpu *)id->driver_data; + cpuidle_state_table = icpu->state_table; if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ lapic_timer_reliable_states = LAPIC_TIMER_ALWAYS_RELIABLE; @@ -470,7 +486,7 @@ static int intel_idle_cpuidle_driver_init(void) drv->state_count += 1; } - if (auto_demotion_disable_flags) + if (icpu->auto_demotion_disable_flags) on_each_cpu(auto_demotion_disable, NULL, 1); return 0; @@ -522,7 +538,7 @@ int intel_idle_cpu_init(int cpu) return -EIO; } - if (auto_demotion_disable_flags) + if (icpu->auto_demotion_disable_flags) smp_call_function_single(cpu, auto_demotion_disable, NULL, 1); return 0; -- cgit v1.2.3-70-g09d2 From 9061e0e16700ef228837e96987ff51794c956197 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:08 +0100 Subject: ACPI: Load acpi-cpufreq from processor driver automatically The only left over hole in automatic cpufreq driver loading was the loading of ACPI cpufreq. This driver should be loaded when ACPI supports a _PDC method and the CPU vendor wants to use acpi cpufreq. Simply add a request module call to the acpi processor core driver when this is true. This seems like the simplest solution for this. Cc: Len Brown Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/processor_driver.c | 1 + drivers/acpi/processor_perflib.c | 22 ++++++++++++++++++++++ include/acpi/processor.h | 1 + 3 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 0034ede3871..e6920d0aca5 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -497,6 +497,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) #ifdef CONFIG_CPU_FREQ acpi_processor_ppc_has_changed(pr, 0); + acpi_processor_load_module(pr); #endif acpi_processor_get_throttling_info(pr); acpi_processor_get_limit_info(pr); diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 85b32376dad..0af48a8554c 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -240,6 +240,28 @@ void acpi_processor_ppc_exit(void) acpi_processor_ppc_status &= ~PPC_REGISTERED; } +/* + * Do a quick check if the systems looks like it should use ACPI + * cpufreq. We look at a _PCT method being available, but don't + * do a whole lot of sanity checks. + */ +void acpi_processor_load_module(struct acpi_processor *pr) +{ + static int requested; + acpi_status status = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + + if (!arch_has_acpi_pdc() || requested) + return; + status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer); + if (!ACPI_FAILURE(status)) { + printk(KERN_INFO PREFIX "Requesting acpi_cpufreq\n"); + request_module_nowait("acpi_cpufreq"); + requested = 1; + } + kfree(buffer.pointer); +} + static int acpi_processor_get_performance_control(struct acpi_processor *pr) { int result = 0; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 610f6fb1bbc..da57fdcc57d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -224,6 +224,7 @@ struct acpi_processor_errata { } piix4; }; +extern void acpi_processor_load_module(struct acpi_processor *pr); extern int acpi_processor_preregister_performance(struct acpi_processor_performance __percpu *performance); -- cgit v1.2.3-70-g09d2 From 267fc9788d0cdb77edafb506063f06961e1418f5 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:09 +0100 Subject: HWMON: Convert via-cputemp to x86 cpuid autoprobing Use the new x86 cpuid autoprobe interface. Cc: Jean Delvare Cc: Guenter Roeck Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/via-cputemp.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/via-cputemp.c b/drivers/hwmon/via-cputemp.c index 8eac67d769f..8689664ef03 100644 --- a/drivers/hwmon/via-cputemp.c +++ b/drivers/hwmon/via-cputemp.c @@ -37,6 +37,7 @@ #include #include #include +#include #define DRVNAME "via_cputemp" @@ -308,15 +309,20 @@ static struct notifier_block via_cputemp_cpu_notifier __refdata = { .notifier_call = via_cputemp_cpu_callback, }; +static const struct x86_cpu_id cputemp_ids[] = { + { X86_VENDOR_CENTAUR, 6, 0xa, }, /* C7 A */ + { X86_VENDOR_CENTAUR, 6, 0xd, }, /* C7 D */ + { X86_VENDOR_CENTAUR, 6, 0xf, }, /* Nano */ + {} +}; +MODULE_DEVICE_TABLE(x86cpu, cputemp_ids); + static int __init via_cputemp_init(void) { int i, err; - if (cpu_data(0).x86_vendor != X86_VENDOR_CENTAUR) { - printk(KERN_DEBUG DRVNAME ": Not a VIA CPU\n"); - err = -ENODEV; - goto exit; - } + if (!x86_match_cpu(cputemp_ids)) + return -ENODEV; err = platform_driver_register(&via_cputemp_driver); if (err) -- cgit v1.2.3-70-g09d2 From 9b38096fde5f9b93c3657911c3be7892cc155cbd Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:10 +0100 Subject: HWMON: Convert coretemp to x86 cpuid autoprobing Use the new x86 cpuid autoprobe interface for the Intel coretemp driver. Cc: Fenghua Yu Cc: Jean Delvare Cc: Guenter Roeck Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/hwmon/coretemp.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index a6c6ec36615..249ac460e3d 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c @@ -39,6 +39,7 @@ #include #include #include +#include #define DRVNAME "coretemp" @@ -759,13 +760,23 @@ static struct notifier_block coretemp_cpu_notifier __refdata = { .notifier_call = coretemp_cpu_callback, }; +static const struct x86_cpu_id coretemp_ids[] = { + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_DTS }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, coretemp_ids); + static int __init coretemp_init(void) { int i, err = -ENODEV; - /* quick check if we run Intel */ - if (cpu_data(0).x86_vendor != X86_VENDOR_INTEL) - goto exit; + /* + * CPUID.06H.EAX[0] indicates whether the CPU has thermal + * sensors. We check this bit only, all the early CPUs + * without thermal sensors will be filtered out. + */ + if (!x86_match_cpu(coretemp_ids)) + return -ENODEV; err = platform_driver_register(&coretemp_driver); if (err) -- cgit v1.2.3-70-g09d2 From fa8031aefec0cf7ea6c2387c93610d99d9659aa2 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 26 Jan 2012 00:09:12 +0100 Subject: cpufreq: Add support for x86 cpuinfo auto loading v4 This marks all the x86 cpuinfo tables to the CPU specific device drivers, to allow auto loading by udev. This should simplify the distribution startup scripts for this greatly. I didn't add MODULE_DEVICE_IDs to the centrino and p4-clockmod drivers, because those probably shouldn't be auto loaded and the acpi driver be used instead (not fully sure on that, would appreciate feedback) The old nforce drivers autoload based on the PCI ID. ACPI cpufreq is autoloaded in another patch. v3: Autoload gx based on PCI IDs only. Remove cpu check (Dave Jones) v4: Use newly introduce HW_PSTATE feature for powernow-k8 loading Cc: Dave Jones Cc: Kay Sievers Signed-off-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/cpufreq-nforce2.c | 8 ++++++++ drivers/cpufreq/e_powersaver.c | 20 +++++++++++--------- drivers/cpufreq/elanfreq.c | 14 +++++++------- drivers/cpufreq/gx-suspmod.c | 9 ++------- drivers/cpufreq/longhaul.c | 8 +++++++- drivers/cpufreq/longrun.c | 13 ++++++++----- drivers/cpufreq/p4-clockmod.c | 17 +++++++++++------ drivers/cpufreq/powernow-k6.c | 12 ++++++++---- drivers/cpufreq/powernow-k7.c | 14 ++++++++------ drivers/cpufreq/powernow-k8.c | 19 +++++++++++++------ drivers/cpufreq/sc520_freq.c | 14 ++++++++------ drivers/cpufreq/speedstep-centrino.c | 24 ++++++++++++++++++++---- drivers/cpufreq/speedstep-ich.c | 15 +++++++++++++++ drivers/cpufreq/speedstep-lib.c | 1 + drivers/cpufreq/speedstep-smi.c | 15 +++++++++++++++ 15 files changed, 142 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq-nforce2.c b/drivers/cpufreq/cpufreq-nforce2.c index 7bac808804f..13d311ee08b 100644 --- a/drivers/cpufreq/cpufreq-nforce2.c +++ b/drivers/cpufreq/cpufreq-nforce2.c @@ -385,6 +385,14 @@ static struct cpufreq_driver nforce2_driver = { .owner = THIS_MODULE, }; +#ifdef MODULE +static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = { + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2 }, + {} +}; +MODULE_DEVICE_TABLE(pci, nforce2_ids); +#endif + /** * nforce2_detect_chipset - detect the Southbridge which contains FSB PLL logic * diff --git a/drivers/cpufreq/e_powersaver.c b/drivers/cpufreq/e_powersaver.c index 4bd6815d317..3fffbe6025c 100644 --- a/drivers/cpufreq/e_powersaver.c +++ b/drivers/cpufreq/e_powersaver.c @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -437,18 +438,19 @@ static struct cpufreq_driver eps_driver = { .attr = eps_attr, }; + +/* This driver will work only on Centaur C7 processors with + * Enhanced SpeedStep/PowerSaver registers */ +static const struct x86_cpu_id eps_cpu_id[] = { + { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id); + static int __init eps_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - /* This driver will work only on Centaur C7 processors with - * Enhanced SpeedStep/PowerSaver registers */ - if (c->x86_vendor != X86_VENDOR_CENTAUR - || c->x86 != 6 || c->x86_model < 10) - return -ENODEV; - if (!cpu_has(c, X86_FEATURE_EST)) + if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10) return -ENODEV; - if (cpufreq_register_driver(&eps_driver)) return -EINVAL; return 0; diff --git a/drivers/cpufreq/elanfreq.c b/drivers/cpufreq/elanfreq.c index c587db472a7..960671fd3d7 100644 --- a/drivers/cpufreq/elanfreq.c +++ b/drivers/cpufreq/elanfreq.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -277,17 +278,16 @@ static struct cpufreq_driver elanfreq_driver = { .attr = elanfreq_attr, }; +static const struct x86_cpu_id elan_id[] = { + { X86_VENDOR_AMD, 4, 10, }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, elan_id); static int __init elanfreq_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - /* Test if we have the right hardware */ - if ((c->x86_vendor != X86_VENDOR_AMD) || - (c->x86 != 4) || (c->x86_model != 10)) { - printk(KERN_INFO "elanfreq: error: no Elan processor found!\n"); + if (!x86_match_cpu(elan_id)) return -ENODEV; - } return cpufreq_register_driver(&elanfreq_driver); } diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index ffe1f2c92ed..5a06c0ba245 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -82,6 +82,7 @@ #include #include +#include #include /* PCI config registers, all at F0 */ @@ -171,6 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; +MODULE_DEVICE_TABLE(gx_chipset_tbl); static void gx_write_byte(int reg, int value) { @@ -185,13 +187,6 @@ static __init struct pci_dev *gx_detect_chipset(void) { struct pci_dev *gx_pci = NULL; - /* check if CPU is a MediaGX or a Geode. */ - if ((boot_cpu_data.x86_vendor != X86_VENDOR_NSC) && - (boot_cpu_data.x86_vendor != X86_VENDOR_CYRIX)) { - pr_debug("error: no MediaGX/Geode processor found!\n"); - return NULL; - } - /* detect which companion chip is used */ for_each_pci_dev(gx_pci) { if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c index f47d26e2a13..53ddbc760af 100644 --- a/drivers/cpufreq/longhaul.c +++ b/drivers/cpufreq/longhaul.c @@ -35,6 +35,7 @@ #include #include +#include #include #include "longhaul.h" @@ -951,12 +952,17 @@ static struct cpufreq_driver longhaul_driver = { .attr = longhaul_attr, }; +static const struct x86_cpu_id longhaul_id[] = { + { X86_VENDOR_CENTAUR, 6 }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, longhaul_id); static int __init longhaul_init(void) { struct cpuinfo_x86 *c = &cpu_data(0); - if (c->x86_vendor != X86_VENDOR_CENTAUR || c->x86 != 6) + if (!x86_match_cpu(longhaul_id)) return -ENODEV; #ifdef CONFIG_SMP diff --git a/drivers/cpufreq/longrun.c b/drivers/cpufreq/longrun.c index 34ea359b370..8bc9f5fbbae 100644 --- a/drivers/cpufreq/longrun.c +++ b/drivers/cpufreq/longrun.c @@ -14,6 +14,7 @@ #include #include +#include static struct cpufreq_driver longrun_driver; @@ -288,6 +289,12 @@ static struct cpufreq_driver longrun_driver = { .owner = THIS_MODULE, }; +static const struct x86_cpu_id longrun_ids[] = { + { X86_VENDOR_TRANSMETA, X86_FAMILY_ANY, X86_MODEL_ANY, + X86_FEATURE_LONGRUN }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, longrun_ids); /** * longrun_init - initializes the Transmeta Crusoe LongRun CPUFreq driver @@ -296,12 +303,8 @@ static struct cpufreq_driver longrun_driver = { */ static int __init longrun_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if (c->x86_vendor != X86_VENDOR_TRANSMETA || - !cpu_has(c, X86_FEATURE_LONGRUN)) + if (!x86_match_cpu(longrun_ids)) return -ENODEV; - return cpufreq_register_driver(&longrun_driver); } diff --git a/drivers/cpufreq/p4-clockmod.c b/drivers/cpufreq/p4-clockmod.c index 6be3e0760c2..827629c9aad 100644 --- a/drivers/cpufreq/p4-clockmod.c +++ b/drivers/cpufreq/p4-clockmod.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "speedstep-lib.h" @@ -289,21 +290,25 @@ static struct cpufreq_driver p4clockmod_driver = { .attr = p4clockmod_attr, }; +static const struct x86_cpu_id cpufreq_p4_id[] = { + { X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ACC }, + {} +}; + +/* + * Intentionally no MODULE_DEVICE_TABLE here: this driver should not + * be auto loaded. Please don't add one. + */ static int __init cpufreq_p4_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); int ret; /* * THERM_CONTROL is architectural for IA32 now, so * we can rely on the capability checks */ - if (c->x86_vendor != X86_VENDOR_INTEL) - return -ENODEV; - - if (!test_cpu_cap(c, X86_FEATURE_ACPI) || - !test_cpu_cap(c, X86_FEATURE_ACC)) + if (!x86_match_cpu(cpufreq_p4_id) || !boot_cpu_has(X86_FEATURE_ACPI)) return -ENODEV; ret = cpufreq_register_driver(&p4clockmod_driver); diff --git a/drivers/cpufreq/powernow-k6.c b/drivers/cpufreq/powernow-k6.c index b3379d6a5c5..54dd031394f 100644 --- a/drivers/cpufreq/powernow-k6.c +++ b/drivers/cpufreq/powernow-k6.c @@ -16,6 +16,7 @@ #include #include +#include #include #define POWERNOW_IOPORT 0xfff0 /* it doesn't matter where, as long @@ -210,6 +211,12 @@ static struct cpufreq_driver powernow_k6_driver = { .attr = powernow_k6_attr, }; +static const struct x86_cpu_id powernow_k6_ids[] = { + { X86_VENDOR_AMD, 5, 12 }, + { X86_VENDOR_AMD, 5, 13 }, + {} +}; + /** * powernow_k6_init - initializes the k6 PowerNow! CPUFreq driver @@ -220,10 +227,7 @@ static struct cpufreq_driver powernow_k6_driver = { */ static int __init powernow_k6_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); - - if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 5) || - ((c->x86_model != 12) && (c->x86_model != 13))) + if (!x86_match_cpu(powernow_k6_ids)) return -ENODEV; if (!request_region(POWERNOW_IOPORT, 16, "PowerNow!")) { diff --git a/drivers/cpufreq/powernow-k7.c b/drivers/cpufreq/powernow-k7.c index d71d9f37235..501d167368d 100644 --- a/drivers/cpufreq/powernow-k7.c +++ b/drivers/cpufreq/powernow-k7.c @@ -28,6 +28,7 @@ #include /* Needed for recalibrate_cpu_khz() */ #include #include +#include #ifdef CONFIG_X86_POWERNOW_K7_ACPI #include @@ -110,18 +111,19 @@ static int check_fsb(unsigned int fsbspeed) return delta < 5; } +static const struct x86_cpu_id powernow_k7_cpuids[] = { + { X86_VENDOR_AMD, 7, }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids); + static int check_powernow(void) { struct cpuinfo_x86 *c = &cpu_data(0); unsigned int maxei, eax, ebx, ecx, edx; - if ((c->x86_vendor != X86_VENDOR_AMD) || (c->x86 != 6)) { -#ifdef MODULE - printk(KERN_INFO PFX "This module only works with " - "AMD K7 CPUs\n"); -#endif + if (!x86_match_cpu(powernow_k7_cpuids)) return 0; - } /* Get maximum capabilities */ maxei = cpuid_eax(0x80000000); diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c index 8f9b2ceeec8..c0e816468e3 100644 --- a/drivers/cpufreq/powernow-k8.c +++ b/drivers/cpufreq/powernow-k8.c @@ -40,6 +40,7 @@ #include #include +#include #include #include @@ -520,6 +521,15 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, return 0; } +static const struct x86_cpu_id powernow_k8_ids[] = { + /* IO based frequency switching */ + { X86_VENDOR_AMD, 0xf }, + /* MSR based frequency switching supported */ + X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE), + {} +}; +MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids); + static void check_supported_cpu(void *_rc) { u32 eax, ebx, ecx, edx; @@ -527,13 +537,7 @@ static void check_supported_cpu(void *_rc) *rc = -ENODEV; - if (__this_cpu_read(cpu_info.x86_vendor) != X86_VENDOR_AMD) - return; - eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); - if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) && - ((eax & CPUID_XFAM) < CPUID_XFAM_10H)) - return; if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || @@ -1553,6 +1557,9 @@ static int __cpuinit powernowk8_init(void) unsigned int i, supported_cpus = 0, cpu; int rv; + if (!x86_match_cpu(powernow_k8_ids)) + return -ENODEV; + for_each_online_cpu(i) { int rc; smp_call_function_single(i, check_supported_cpu, &rc, 1); diff --git a/drivers/cpufreq/sc520_freq.c b/drivers/cpufreq/sc520_freq.c index 1e205e6b172..e42e073cd9b 100644 --- a/drivers/cpufreq/sc520_freq.c +++ b/drivers/cpufreq/sc520_freq.c @@ -22,6 +22,7 @@ #include #include +#include #include #define MMCR_BASE 0xfffef000 /* The default base address */ @@ -150,18 +151,19 @@ static struct cpufreq_driver sc520_freq_driver = { .attr = sc520_freq_attr, }; +static const struct x86_cpu_id sc520_ids[] = { + { X86_VENDOR_AMD, 4, 9 }, + {} +}; +MODULE_DEVICE_TABLE(x86cpu, sc520_ids); static int __init sc520_freq_init(void) { - struct cpuinfo_x86 *c = &cpu_data(0); int err; - /* Test if we have the right hardware */ - if (c->x86_vendor != X86_VENDOR_AMD || - c->x86 != 4 || c->x86_model != 9) { - pr_debug("no Elan SC520 processor found!\n"); + if (!x86_match_cpu(sc520_ids)) return -ENODEV; - } + cpuctl = ioremap((unsigned long)(MMCR_BASE + OFFS_CPUCTL), 1); if (!cpuctl) { printk(KERN_ERR "sc520_freq: error: failed to remap memory\n"); diff --git a/drivers/cpufreq/speedstep-centrino.c b/drivers/cpufreq/speedstep-centrino.c index 6ea3455def2..3a953d519f4 100644 --- a/drivers/cpufreq/speedstep-centrino.c +++ b/drivers/cpufreq/speedstep-centrino.c @@ -25,6 +25,7 @@ #include #include #include +#include #define PFX "speedstep-centrino: " #define MAINTAINER "cpufreq@vger.kernel.org" @@ -595,6 +596,24 @@ static struct cpufreq_driver centrino_driver = { .owner = THIS_MODULE, }; +/* + * This doesn't replace the detailed checks above because + * the generic CPU IDs don't have a way to match for steppings + * or ASCII model IDs. + */ +static const struct x86_cpu_id centrino_ids[] = { + { X86_VENDOR_INTEL, 6, 9, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 6, 13, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 15, 3, X86_FEATURE_EST }, + { X86_VENDOR_INTEL, 15, 4, X86_FEATURE_EST }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE(x86cpu, centrino_ids); +#endif /** * centrino_init - initializes the Enhanced SpeedStep CPUFreq driver @@ -612,11 +631,8 @@ static struct cpufreq_driver centrino_driver = { */ static int __init centrino_init(void) { - struct cpuinfo_x86 *cpu = &cpu_data(0); - - if (!cpu_has(cpu, X86_FEATURE_EST)) + if (!x86_match_cpu(centrino_ids)) return -ENODEV; - return cpufreq_register_driver(¢rino_driver); } diff --git a/drivers/cpufreq/speedstep-ich.c b/drivers/cpufreq/speedstep-ich.c index a748ce782fe..7432b3a72cd 100644 --- a/drivers/cpufreq/speedstep-ich.c +++ b/drivers/cpufreq/speedstep-ich.c @@ -25,6 +25,8 @@ #include #include +#include + #include "speedstep-lib.h" @@ -388,6 +390,16 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + { X86_VENDOR_INTEL, 6, 0xb, }, + { X86_VENDOR_INTEL, 6, 0x8, }, + { X86_VENDOR_INTEL, 15, 2 }, + {} +}; +#if 0 +/* Autoload or not? Do not for now. */ +MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); +#endif /** * speedstep_init - initializes the SpeedStep CPUFreq driver @@ -398,6 +410,9 @@ static struct cpufreq_driver speedstep_driver = { */ static int __init speedstep_init(void) { + if (!x86_match_cpu(ss_smi_ids)) + return -ENODEV; + /* detect processor */ speedstep_processor = speedstep_detect_processor(); if (!speedstep_processor) { diff --git a/drivers/cpufreq/speedstep-lib.c b/drivers/cpufreq/speedstep-lib.c index 8af2d2fd9d5..7047821a7f8 100644 --- a/drivers/cpufreq/speedstep-lib.c +++ b/drivers/cpufreq/speedstep-lib.c @@ -249,6 +249,7 @@ EXPORT_SYMBOL_GPL(speedstep_get_frequency); * DETECT SPEEDSTEP-CAPABLE PROCESSOR * *********************************************************************/ +/* Keep in sync with the x86_cpu_id tables in the different modules */ unsigned int speedstep_detect_processor(void) { struct cpuinfo_x86 *c = &cpu_data(0); diff --git a/drivers/cpufreq/speedstep-smi.c b/drivers/cpufreq/speedstep-smi.c index c76ead3490b..6a457fcaaad 100644 --- a/drivers/cpufreq/speedstep-smi.c +++ b/drivers/cpufreq/speedstep-smi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "speedstep-lib.h" @@ -379,6 +380,17 @@ static struct cpufreq_driver speedstep_driver = { .attr = speedstep_attr, }; +static const struct x86_cpu_id ss_smi_ids[] = { + { X86_VENDOR_INTEL, 6, 0xb, }, + { X86_VENDOR_INTEL, 6, 0x8, }, + { X86_VENDOR_INTEL, 15, 2 }, + {} +}; +#if 0 +/* Not auto loaded currently */ +MODULE_DEVICE_TABLE(x86cpu, ss_smi_ids); +#endif + /** * speedstep_init - initializes the SpeedStep CPUFreq driver * @@ -388,6 +400,9 @@ static struct cpufreq_driver speedstep_driver = { */ static int __init speedstep_init(void) { + if (!x86_match_cpu(ss_smi_ids)) + return -ENODEV; + speedstep_processor = speedstep_detect_processor(); switch (speedstep_processor) { -- cgit v1.2.3-70-g09d2 From fad12ac8c8c2591c7f4e61d19b6a9d76cd49fafa Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Thu, 26 Jan 2012 00:09:14 +0100 Subject: CPU: Introduce ARCH_HAS_CPU_AUTOPROBE and X86 parts This patch is based on Andi Kleen's work: Implement autoprobing/loading of modules serving CPU specific features (x86cpu autoloading). And Kay Siever's work to get rid of sysdev cpu structures and making use of struct device instead. Before, the cpuid driver had to be loaded to get the x86cpu autoloading feature. With this patch autoloading works through the /sys/devices/system/cpu object Cc: Kay Sievers Cc: Dave Jones Cc: Jens Axboe Cc: Herbert Xu Cc: Huang Ying Cc: Len Brown Acked-by: Andi Kleen Signed-off-by: Thomas Renninger Acked-by: H. Peter Anvin Signed-off-by: Greg Kroah-Hartman --- arch/x86/Kconfig | 3 +++ arch/x86/kernel/cpu/match.c | 44 +++++++++++++++++++++++++++++++++ arch/x86/kernel/cpuid.c | 59 +-------------------------------------------- drivers/base/cpu.c | 11 +++++++++ include/linux/cpu.h | 7 ++++++ 5 files changed, 66 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 864cc6e6ac8..6baa1e66e1b 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -179,6 +179,9 @@ config ARCH_HAS_DEFAULT_IDLE config ARCH_HAS_CACHE_LINE_SIZE def_bool y +config ARCH_HAS_CPU_AUTOPROBE + def_bool y + config HAVE_SETUP_PER_CPU_AREA def_bool y diff --git a/arch/x86/kernel/cpu/match.c b/arch/x86/kernel/cpu/match.c index 7acc961422e..940e2d48307 100644 --- a/arch/x86/kernel/cpu/match.c +++ b/arch/x86/kernel/cpu/match.c @@ -2,6 +2,7 @@ #include #include #include +#include /** * x86_match_cpu - match current CPU again an array of x86_cpu_ids @@ -46,3 +47,46 @@ const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id *match) return NULL; } EXPORT_SYMBOL(x86_match_cpu); + +ssize_t arch_print_cpu_modalias(struct device *dev, + struct device_attribute *attr, + char *bufptr) +{ + int size = PAGE_SIZE; + int i, n; + char *buf = bufptr; + + n = snprintf(buf, size, "x86cpu:vendor:%04X:family:%04X:" + "model:%04X:feature:", + boot_cpu_data.x86_vendor, + boot_cpu_data.x86, + boot_cpu_data.x86_model); + size -= n; + buf += n; + size -= 2; + for (i = 0; i < NCAPINTS*32; i++) { + if (boot_cpu_has(i)) { + n = snprintf(buf, size, ",%04X", i); + if (n < 0) { + WARN(1, "x86 features overflow page\n"); + break; + } + size -= n; + buf += n; + } + } + *buf++ = ','; + *buf++ = '\n'; + return buf - bufptr; +} + +int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (buf) { + arch_print_cpu_modalias(NULL, NULL, buf); + add_uevent_var(env, "MODALIAS=%s", buf); + kfree(buf); + } + return 0; +} diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c index 7c89880eefd..a524353d93f 100644 --- a/arch/x86/kernel/cpuid.c +++ b/arch/x86/kernel/cpuid.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include @@ -139,57 +138,13 @@ static const struct file_operations cpuid_fops = { .open = cpuid_open, }; -static ssize_t print_cpu_modalias(struct device *dev, - struct device_attribute *attr, - char *bufptr) -{ - int size = PAGE_SIZE; - int i, n; - char *buf = bufptr; - - n = snprintf(buf, size, "x86cpu:vendor:%04X:family:" - "%04X:model:%04X:feature:", - boot_cpu_data.x86_vendor, - boot_cpu_data.x86, - boot_cpu_data.x86_model); - size -= n; - buf += n; - size -= 2; - for (i = 0; i < NCAPINTS*32; i++) { - if (boot_cpu_has(i)) { - n = snprintf(buf, size, ",%04X", i); - if (n < 0) { - WARN(1, "x86 features overflow page\n"); - break; - } - size -= n; - buf += n; - } - } - *buf++ = ','; - *buf++ = '\n'; - return buf - bufptr; -} - -static DEVICE_ATTR(modalias, 0444, print_cpu_modalias, NULL); - static __cpuinit int cpuid_device_create(int cpu) { struct device *dev; - int err; dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL, "cpu%d", cpu); - if (IS_ERR(dev)) - return PTR_ERR(dev); - - err = device_create_file(dev, &dev_attr_modalias); - if (err) { - /* keep device around on error. attribute is optional. */ - err = 0; - } - - return 0; + return IS_ERR(dev) ? PTR_ERR(dev) : 0; } static void cpuid_device_destroy(int cpu) @@ -227,17 +182,6 @@ static char *cpuid_devnode(struct device *dev, umode_t *mode) return kasprintf(GFP_KERNEL, "cpu/%u/cpuid", MINOR(dev->devt)); } -static int cpuid_dev_uevent(struct device *dev, struct kobj_uevent_env *env) -{ - char *buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (buf) { - print_cpu_modalias(NULL, NULL, buf); - add_uevent_var(env, "MODALIAS=%s", buf); - kfree(buf); - } - return 0; -} - static int __init cpuid_init(void) { int i, err = 0; @@ -256,7 +200,6 @@ static int __init cpuid_init(void) goto out_chrdev; } cpuid_class->devnode = cpuid_devnode; - cpuid_class->dev_uevent = cpuid_dev_uevent; for_each_online_cpu(i) { err = cpuid_device_create(i); if (err != 0) diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index db87e78d745..2a0c670c281 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "base.h" @@ -223,6 +224,9 @@ int __cpuinit register_cpu(struct cpu *cpu, int num) cpu->node_id = cpu_to_node(num); cpu->dev.id = num; cpu->dev.bus = &cpu_subsys; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + cpu->dev.bus->uevent = arch_cpu_uevent; +#endif error = device_register(&cpu->dev); if (!error && cpu->hotpluggable) register_cpu_control(cpu); @@ -247,6 +251,10 @@ struct device *get_cpu_device(unsigned cpu) } EXPORT_SYMBOL_GPL(get_cpu_device); +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +static DEVICE_ATTR(modalias, 0444, arch_print_cpu_modalias, NULL); +#endif + static struct attribute *cpu_root_attrs[] = { #ifdef CONFIG_ARCH_CPU_PROBE_RELEASE &dev_attr_probe.attr, @@ -257,6 +265,9 @@ static struct attribute *cpu_root_attrs[] = { &cpu_attrs[2].attr.attr, &dev_attr_kernel_max.attr, &dev_attr_offline.attr, +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE + &dev_attr_modalias.attr, +#endif NULL }; diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 1f6587590a1..6e53b4823d7 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h @@ -44,6 +44,13 @@ extern ssize_t arch_cpu_release(const char *, size_t); #endif struct notifier_block; +#ifdef CONFIG_ARCH_HAS_CPU_AUTOPROBE +extern int arch_cpu_uevent(struct device *dev, struct kobj_uevent_env *env); +extern ssize_t arch_print_cpu_modalias(struct device *dev, + struct device_attribute *attr, + char *bufptr); +#endif + /* * CPU notifier priorities. */ -- cgit v1.2.3-70-g09d2 From ed283e9f0a2cc0541870828c76c6c6997c51a318 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 24 Jan 2012 14:35:13 -0500 Subject: USB/PCI/PCMCIA: Clean up new_id and remove_id sysfs attribute routines This patch (as1514) cleans up some places where new_id and remove_id sysfs attributes are created and deleted. Handling both attributes in a single routine rather than a pair of routines makes the code smaller. It also prevents certain kinds of errors, like one we currently have in the USB subsystem: The removeid attribute is often created even when newid isn't (because the driver's no_dynamid_id flag is set). In the case of the PCMCIA subsystem, the newid attribute is created but never explicitly deleted. The patch adds a deletion routine. Signed-off-by: Alan Stern Acked-by: Jesse Barnes Acked-by: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci-driver.c | 50 +++++++++++++------------------------- drivers/pcmcia/ds.c | 6 +++++ drivers/usb/core/driver.c | 61 ++++++++++++++++------------------------------- 3 files changed, 43 insertions(+), 74 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index ff540477fe8..8d9616b821c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -188,43 +188,34 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); static int -pci_create_newid_file(struct pci_driver *drv) +pci_create_newid_files(struct pci_driver *drv) { int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->driver, &driver_attr_new_id); - return error; -} - -static void pci_remove_newid_file(struct pci_driver *drv) -{ - driver_remove_file(&drv->driver, &driver_attr_new_id); -} -static int -pci_create_removeid_file(struct pci_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->driver,&driver_attr_remove_id); + if (drv->probe != NULL) { + error = driver_create_file(&drv->driver, &driver_attr_new_id); + if (error == 0) { + error = driver_create_file(&drv->driver, + &driver_attr_remove_id); + if (error) + driver_remove_file(&drv->driver, + &driver_attr_new_id); + } + } return error; } -static void pci_remove_removeid_file(struct pci_driver *drv) +static void pci_remove_newid_files(struct pci_driver *drv) { driver_remove_file(&drv->driver, &driver_attr_remove_id); + driver_remove_file(&drv->driver, &driver_attr_new_id); } #else /* !CONFIG_HOTPLUG */ -static inline int pci_create_newid_file(struct pci_driver *drv) +static inline int pci_create_newid_files(struct pci_driver *drv) { return 0; } -static inline void pci_remove_newid_file(struct pci_driver *drv) {} -static inline int pci_create_removeid_file(struct pci_driver *drv) -{ - return 0; -} -static inline void pci_remove_removeid_file(struct pci_driver *drv) {} +static inline void pci_remove_newid_files(struct pci_driver *drv) {} #endif /** @@ -1136,18 +1127,12 @@ int __pci_register_driver(struct pci_driver *drv, struct module *owner, if (error) goto out; - error = pci_create_newid_file(drv); + error = pci_create_newid_files(drv); if (error) goto out_newid; - - error = pci_create_removeid_file(drv); - if (error) - goto out_removeid; out: return error; -out_removeid: - pci_remove_newid_file(drv); out_newid: driver_unregister(&drv->driver); goto out; @@ -1166,8 +1151,7 @@ out_newid: void pci_unregister_driver(struct pci_driver *drv) { - pci_remove_removeid_file(drv); - pci_remove_newid_file(drv); + pci_remove_newid_files(drv); driver_unregister(&drv->driver); pci_free_dynids(drv); } diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 059699f6363..249b8895807 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -157,6 +157,11 @@ pcmcia_create_newid_file(struct pcmcia_driver *drv) return error; } +static void +pcmcia_remove_newid_file(struct pcmcia_driver *drv) +{ + driver_remove_file(&drv->drv, &driver_attr_new_id); +} /** * pcmcia_register_driver - register a PCMCIA driver with the bus core @@ -201,6 +206,7 @@ EXPORT_SYMBOL(pcmcia_register_driver); void pcmcia_unregister_driver(struct pcmcia_driver *driver) { pr_debug("unregistering driver %s\n", driver->name); + pcmcia_remove_newid_file(driver); driver_unregister(&driver->drv); pcmcia_free_dynids(driver); } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 54c493b4226..4fee024ecc9 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -129,43 +129,39 @@ store_remove_id(struct device_driver *driver, const char *buf, size_t count) } static DRIVER_ATTR(remove_id, S_IWUSR, NULL, store_remove_id); -static int usb_create_newid_file(struct usb_driver *usb_drv) +static int usb_create_newid_files(struct usb_driver *usb_drv) { int error = 0; if (usb_drv->no_dynamic_id) goto exit; - if (usb_drv->probe != NULL) + if (usb_drv->probe != NULL) { error = driver_create_file(&usb_drv->drvwrap.driver, &driver_attr_new_id); + if (error == 0) { + error = driver_create_file(&usb_drv->drvwrap.driver, + &driver_attr_remove_id); + if (error) + driver_remove_file(&usb_drv->drvwrap.driver, + &driver_attr_new_id); + } + } exit: return error; } -static void usb_remove_newid_file(struct usb_driver *usb_drv) +static void usb_remove_newid_files(struct usb_driver *usb_drv) { if (usb_drv->no_dynamic_id) return; - if (usb_drv->probe != NULL) + if (usb_drv->probe != NULL) { driver_remove_file(&usb_drv->drvwrap.driver, - &driver_attr_new_id); -} - -static int -usb_create_removeid_file(struct usb_driver *drv) -{ - int error = 0; - if (drv->probe != NULL) - error = driver_create_file(&drv->drvwrap.driver, &driver_attr_remove_id); - return error; -} - -static void usb_remove_removeid_file(struct usb_driver *drv) -{ - driver_remove_file(&drv->drvwrap.driver, &driver_attr_remove_id); + driver_remove_file(&usb_drv->drvwrap.driver, + &driver_attr_new_id); + } } static void usb_free_dynids(struct usb_driver *usb_drv) @@ -180,22 +176,12 @@ static void usb_free_dynids(struct usb_driver *usb_drv) spin_unlock(&usb_drv->dynids.lock); } #else -static inline int usb_create_newid_file(struct usb_driver *usb_drv) -{ - return 0; -} - -static void usb_remove_newid_file(struct usb_driver *usb_drv) -{ -} - -static int -usb_create_removeid_file(struct usb_driver *drv) +static inline int usb_create_newid_files(struct usb_driver *usb_drv) { return 0; } -static void usb_remove_removeid_file(struct usb_driver *drv) +static void usb_remove_newid_files(struct usb_driver *usb_drv) { } @@ -872,22 +858,16 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner, usbfs_update_special(); - retval = usb_create_newid_file(new_driver); + retval = usb_create_newid_files(new_driver); if (retval) goto out_newid; - retval = usb_create_removeid_file(new_driver); - if (retval) - goto out_removeid; - pr_info("%s: registered new interface driver %s\n", usbcore_name, new_driver->name); out: return retval; -out_removeid: - usb_remove_newid_file(new_driver); out_newid: driver_unregister(&new_driver->drvwrap.driver); @@ -914,10 +894,9 @@ void usb_deregister(struct usb_driver *driver) pr_info("%s: deregistering interface driver %s\n", usbcore_name, driver->name); - usb_remove_removeid_file(driver); - usb_remove_newid_file(driver); - usb_free_dynids(driver); + usb_remove_newid_files(driver); driver_unregister(&driver->drvwrap.driver); + usb_free_dynids(driver); usbfs_update_special(); } -- cgit v1.2.3-70-g09d2 From d4e33fac2408d37f7b52e80ca2a89f9fb482914f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 26 Jan 2012 17:44:09 +0000 Subject: serial: Kill off NO_IRQ We transform the offenders into a test of irq <= 0 which will be ok while the ARM people get their platform sorted. Once that is done (or in a while if they don't do it anyway) then we will change them all to !irq checks. For arch specific drivers that are already using NO_IRQ = 0 we just test against zero so we don't need to re-review them later. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/hvc/hvc_beat.c | 2 +- drivers/tty/hvc/hvc_rtas.c | 2 +- drivers/tty/hvc/hvc_udbg.c | 2 +- drivers/tty/hvc/hvc_xen.c | 2 +- drivers/tty/hvc/hvcs.c | 4 ++-- drivers/tty/hvc/hvsi.c | 2 +- drivers/tty/serial/21285.c | 4 ++-- drivers/tty/serial/8250.c | 21 +++++++-------------- drivers/tty/serial/m32r_sio.c | 11 ++--------- drivers/tty/serial/mpc52xx_uart.c | 4 ++-- drivers/tty/serial/mux.c | 2 +- drivers/tty/serial/pmac_zilog.c | 2 +- drivers/tty/serial/sunzilog.c | 10 +++++----- drivers/tty/serial/ucc_uart.c | 2 +- drivers/tty/serial/vr41xx_siu.c | 4 ++-- 15 files changed, 30 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvc_beat.c b/drivers/tty/hvc/hvc_beat.c index 5fe4631e2a6..1560d235449 100644 --- a/drivers/tty/hvc/hvc_beat.c +++ b/drivers/tty/hvc/hvc_beat.c @@ -113,7 +113,7 @@ static int __init hvc_beat_init(void) if (!firmware_has_feature(FW_FEATURE_BEAT)) return -ENODEV; - hp = hvc_alloc(0, NO_IRQ, &hvc_beat_get_put_ops, 16); + hp = hvc_alloc(0, 0, &hvc_beat_get_put_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); hvc_beat_dev = hp; diff --git a/drivers/tty/hvc/hvc_rtas.c b/drivers/tty/hvc/hvc_rtas.c index 61c4a61558d..0069bb86ba4 100644 --- a/drivers/tty/hvc/hvc_rtas.c +++ b/drivers/tty/hvc/hvc_rtas.c @@ -94,7 +94,7 @@ static int __init hvc_rtas_init(void) /* Allocate an hvc_struct for the console device we instantiated * earlier. Save off hp so that we can return it on exit */ - hp = hvc_alloc(hvc_rtas_cookie, NO_IRQ, &hvc_rtas_get_put_ops, 16); + hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); diff --git a/drivers/tty/hvc/hvc_udbg.c b/drivers/tty/hvc/hvc_udbg.c index b0957e61a7b..4c9b13e7748 100644 --- a/drivers/tty/hvc/hvc_udbg.c +++ b/drivers/tty/hvc/hvc_udbg.c @@ -69,7 +69,7 @@ static int __init hvc_udbg_init(void) BUG_ON(hvc_udbg_dev); - hp = hvc_alloc(0, NO_IRQ, &hvc_udbg_ops, 16); + hp = hvc_alloc(0, 0, &hvc_udbg_ops, 16); if (IS_ERR(hp)) return PTR_ERR(hp); diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c index 52fdf60bdbe..a1b0a75c3ea 100644 --- a/drivers/tty/hvc/hvc_xen.c +++ b/drivers/tty/hvc/hvc_xen.c @@ -176,7 +176,7 @@ static int __init xen_hvc_init(void) xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); } if (xencons_irq < 0) - xencons_irq = 0; /* NO_IRQ */ + xencons_irq = 0; else irq_set_noprobe(xencons_irq); diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index b9040bec36b..df7e7a0a5e6 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -1203,7 +1203,7 @@ static void hvcs_close(struct tty_struct *tty, struct file *filp) { struct hvcs_struct *hvcsd; unsigned long flags; - int irq = NO_IRQ; + int irq; /* * Is someone trying to close the file associated with this device after @@ -1264,7 +1264,7 @@ static void hvcs_hangup(struct tty_struct * tty) struct hvcs_struct *hvcsd = tty->driver_data; unsigned long flags; int temp_open_count; - int irq = NO_IRQ; + int irq; spin_lock_irqsave(&hvcsd->lock, flags); /* Preserve this so that we know how many kref refs to put */ diff --git a/drivers/tty/hvc/hvsi.c b/drivers/tty/hvc/hvsi.c index cdfa3e02d62..1b5f28bd793 100644 --- a/drivers/tty/hvc/hvsi.c +++ b/drivers/tty/hvc/hvsi.c @@ -1237,7 +1237,7 @@ static int __init hvsi_console_init(void) hp->state = HVSI_CLOSED; hp->vtermno = *vtermno; hp->virq = irq_create_mapping(NULL, irq[0]); - if (hp->virq == NO_IRQ) { + if (hp->virq == 0) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", __func__, irq[0]); continue; diff --git a/drivers/tty/serial/21285.c b/drivers/tty/serial/21285.c index 1b37626e8f1..f899996b436 100644 --- a/drivers/tty/serial/21285.c +++ b/drivers/tty/serial/21285.c @@ -331,7 +331,7 @@ static int serial21285_verify_port(struct uart_port *port, struct serial_struct int ret = 0; if (ser->type != PORT_UNKNOWN && ser->type != PORT_21285) ret = -EINVAL; - if (ser->irq != NO_IRQ) + if (ser->irq <= 0) ret = -EINVAL; if (ser->baud_base != port->uartclk / 16) ret = -EINVAL; @@ -360,7 +360,7 @@ static struct uart_ops serial21285_ops = { static struct uart_port serial21285_port = { .mapbase = 0x42000160, .iotype = UPIO_MEM, - .irq = NO_IRQ, + .irq = 0, .fifosize = 16, .ops = &serial21285_ops, .flags = UPF_BOOT_AUTOCONF, diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index 9f50c4e3c2b..b0eb9613932 100644 --- a/drivers/tty/serial/8250.c +++ b/drivers/tty/serial/8250.c @@ -86,13 +86,6 @@ static unsigned int skip_txen_test; /* force skip of txen test at init time */ #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE) -/* - * We default to IRQ0 for the "no irq" hack. Some - * machine types want others as well - they're free - * to redefine this in their header file. - */ -#define is_real_interrupt(irq) ((irq) != 0) - #ifdef CONFIG_SERIAL_8250_DETECT_IRQ #define CONFIG_SERIAL_DETECT_IRQ 1 #endif @@ -1750,7 +1743,7 @@ static void serial8250_backup_timeout(unsigned long data) * Must disable interrupts or else we risk racing with the interrupt * based handler. */ - if (is_real_interrupt(up->port.irq)) { + if (up->port.irq) { ier = serial_in(up, UART_IER); serial_out(up, UART_IER, 0); } @@ -1775,7 +1768,7 @@ static void serial8250_backup_timeout(unsigned long data) if (!(iir & UART_IIR_NO_INT)) serial8250_tx_chars(up); - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) serial_out(up, UART_IER, ier); spin_unlock_irqrestore(&up->port.lock, flags); @@ -2028,7 +2021,7 @@ static int serial8250_startup(struct uart_port *port) serial_outp(up, UART_LCR, 0); } - if (is_real_interrupt(up->port.irq)) { + if (up->port.irq) { unsigned char iir1; /* * Test for UARTs that do not reassert THRE when the @@ -2083,7 +2076,7 @@ static int serial8250_startup(struct uart_port *port) * hardware interrupt, we use a timer-based system. The original * driver used to do this with IRQ0. */ - if (!is_real_interrupt(up->port.irq)) { + if (!up->port.irq) { up->timer.data = (unsigned long)up; mod_timer(&up->timer, jiffies + uart_poll_timeout(port)); } else { @@ -2099,13 +2092,13 @@ static int serial8250_startup(struct uart_port *port) spin_lock_irqsave(&up->port.lock, flags); if (up->port.flags & UPF_FOURPORT) { - if (!is_real_interrupt(up->port.irq)) + if (!up->port.irq) up->port.mctrl |= TIOCM_OUT1; } else /* * Most PC uarts need OUT2 raised to enable interrupts. */ - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) up->port.mctrl |= TIOCM_OUT2; serial8250_set_mctrl(&up->port, up->port.mctrl); @@ -2223,7 +2216,7 @@ static void serial8250_shutdown(struct uart_port *port) del_timer_sync(&up->timer); up->timer.function = serial8250_timeout; - if (is_real_interrupt(up->port.irq)) + if (up->port.irq) serial_unlink_irq_chain(up); } diff --git a/drivers/tty/serial/m32r_sio.c b/drivers/tty/serial/m32r_sio.c index 94a6792bf97..e465dda63ed 100644 --- a/drivers/tty/serial/m32r_sio.c +++ b/drivers/tty/serial/m32r_sio.c @@ -70,13 +70,6 @@ #define PASS_LIMIT 256 -/* - * We default to IRQ0 for the "no irq" hack. Some - * machine types want others as well - they're free - * to redefine this in their header file. - */ -#define is_real_interrupt(irq) ((irq) != 0) - #define BASE_BAUD 115200 /* Standard COM flags */ @@ -640,7 +633,7 @@ static int m32r_sio_startup(struct uart_port *port) * hardware interrupt, we use a timer-based system. The original * driver used to do this with IRQ0. */ - if (!is_real_interrupt(up->port.irq)) { + if (!up->port.irq) { unsigned int timeout = up->port.timeout; timeout = timeout > 6 ? (timeout / 2 - 2) : 1; @@ -687,7 +680,7 @@ static void m32r_sio_shutdown(struct uart_port *port) sio_init(); - if (!is_real_interrupt(up->port.irq)) + if (!up->port.irq) del_timer_sync(&up->timer); else serial_unlink_irq_chain(up); diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index 1093a88a1fe..e9a770d77a6 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -507,7 +507,7 @@ static int __init mpc512x_psc_fifoc_init(void) psc_fifoc_irq = irq_of_parse_and_map(np, 0); of_node_put(np); - if (psc_fifoc_irq == NO_IRQ) { + if (psc_fifoc_irq == 0) { pr_err("%s: Can't get FIFOC irq\n", __func__); iounmap(psc_fifoc); return -ENODEV; @@ -1354,7 +1354,7 @@ static int __devinit mpc52xx_uart_of_probe(struct platform_device *op) } psc_ops->get_irq(port, op->dev.of_node); - if (port->irq == NO_IRQ) { + if (port->irq == 0) { dev_dbg(&op->dev, "Could not get irq\n"); return -EINVAL; } diff --git a/drivers/tty/serial/mux.c b/drivers/tty/serial/mux.c index 06f6aefd5ba..c61d950e07c 100644 --- a/drivers/tty/serial/mux.c +++ b/drivers/tty/serial/mux.c @@ -499,7 +499,7 @@ static int __init mux_probe(struct parisc_device *dev) port->membase = ioremap_nocache(port->mapbase, MUX_LINE_OFFSET); port->iotype = UPIO_MEM; port->type = PORT_MUX; - port->irq = NO_IRQ; + port->irq = 0; port->uartclk = 0; port->fifosize = MUX_FIFO_SIZE; port->ops = &mux_pops; diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index e9c2dfe471a..08ebe901bb5 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c @@ -1506,7 +1506,7 @@ no_dma: * fixed up interrupt info, but we use the device-tree directly * here due to early probing so we need the fixup too. */ - if (uap->port.irq == NO_IRQ && + if (uap->port.irq == 0 && np->parent && np->parent->parent && of_device_is_compatible(np->parent->parent, "gatwick")) { /* IRQs on gatwick are offset by 64 */ diff --git a/drivers/tty/serial/sunzilog.c b/drivers/tty/serial/sunzilog.c index 8e916e76b7b..5a47d1b196d 100644 --- a/drivers/tty/serial/sunzilog.c +++ b/drivers/tty/serial/sunzilog.c @@ -1397,7 +1397,7 @@ static void __devinit sunzilog_init_hw(struct uart_sunzilog_port *up) #endif } -static int zilog_irq = -1; +static int zilog_irq; static int __devinit zs_probe(struct platform_device *op) { @@ -1425,7 +1425,7 @@ static int __devinit zs_probe(struct platform_device *op) rp = sunzilog_chip_regs[inst]; - if (zilog_irq == -1) + if (!zilog_irq) zilog_irq = op->archdata.irqs[0]; up = &sunzilog_port_table[inst * 2]; @@ -1580,7 +1580,7 @@ static int __init sunzilog_init(void) if (err) goto out_unregister_uart; - if (zilog_irq != -1) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED, "zs", sunzilog_irq_chain); @@ -1621,7 +1621,7 @@ static void __exit sunzilog_exit(void) { platform_driver_unregister(&zs_driver); - if (zilog_irq != -1) { + if (!zilog_irq) { struct uart_sunzilog_port *up = sunzilog_irq_chain; /* Disable Interrupts */ @@ -1637,7 +1637,7 @@ static void __exit sunzilog_exit(void) } free_irq(zilog_irq, sunzilog_irq_chain); - zilog_irq = -1; + zilog_irq = 0; } if (sunzilog_reg.nr) { diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c index 2ebe606a2db..f99b0c965f8 100644 --- a/drivers/tty/serial/ucc_uart.c +++ b/drivers/tty/serial/ucc_uart.c @@ -1360,7 +1360,7 @@ static int ucc_uart_probe(struct platform_device *ofdev) } qe_port->port.irq = irq_of_parse_and_map(np, 0); - if (qe_port->port.irq == NO_IRQ) { + if (qe_port->port.irq == 0) { dev_err(&ofdev->dev, "could not map IRQ for UCC%u\n", qe_port->ucc_num + 1); ret = -EINVAL; diff --git a/drivers/tty/serial/vr41xx_siu.c b/drivers/tty/serial/vr41xx_siu.c index 83148e79ca1..cf0d9485ec0 100644 --- a/drivers/tty/serial/vr41xx_siu.c +++ b/drivers/tty/serial/vr41xx_siu.c @@ -61,7 +61,7 @@ static struct uart_port siu_uart_ports[SIU_PORTS_MAX] = { [0 ... SIU_PORTS_MAX-1] = { .lock = __SPIN_LOCK_UNLOCKED(siu_uart_ports->lock), - .irq = -1, + .irq = 0, }, }; @@ -171,7 +171,7 @@ static inline unsigned int siu_check_type(struct uart_port *port) { if (port->line == 0) return PORT_VR41XX_SIU; - if (port->line == 1 && port->irq != -1) + if (port->line == 1 && port->irq) return PORT_VR41XX_DSIU; return PORT_UNKNOWN; -- cgit v1.2.3-70-g09d2 From 79d4e9087a6ecd6bf2103bf378bf8e0d79278b5a Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:27 +0000 Subject: e1000e: disable Early Receive DMA on ICH LOMs Internal stress testing with jumbo frames shows the reliability of ICH9 and ICH10D devices is improved in certain corner cases by disabling the Early Receive feature. To reduce the performance impact caused by disabling this feature, the packet buffer sizes and relevant flow control settings are modified accordingly. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 - drivers/net/ethernet/intel/e1000e/netdev.c | 60 ++++++++++++----------------- 3 files changed, 25 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 4b3a27670a6..70bc9e90273 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -420,7 +420,7 @@ struct e1000_info { #define FLAG_HAS_FLASH (1 << 1) #define FLAG_HAS_HW_VLAN_FILTER (1 << 2) #define FLAG_HAS_WOL (1 << 3) -#define FLAG_HAS_ERT (1 << 4) +/* reserved bit4 */ #define FLAG_HAS_CTRLEXT_ON_LOAD (1 << 5) #define FLAG_HAS_SWSM_ON_LOAD (1 << 6) #define FLAG_HAS_JUMBO_FRAMES (1 << 7) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 1b69c2d6b41..e446e058250 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -4110,7 +4110,6 @@ const struct e1000_info e1000_ich9_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, @@ -4128,7 +4127,6 @@ const struct e1000_info e1000_ich10_info = { | FLAG_HAS_WOL | FLAG_HAS_CTRLEXT_ON_LOAD | FLAG_HAS_AMT - | FLAG_HAS_ERT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, .pba = 10, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 89af6c02623..49b5ded2632 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -2947,8 +2947,7 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter) * per packet. */ pages = PAGE_USE_COUNT(adapter->netdev->mtu); - if (!(adapter->flags & FLAG_HAS_ERT) && (pages <= 3) && - (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) + if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE)) adapter->rx_ps_pages = pages; else adapter->rx_ps_pages = 0; @@ -3095,23 +3094,14 @@ static void e1000_configure_rx(struct e1000_adapter *adapter) } ew32(RXCSUM, rxcsum); - /* - * Enable early receives on supported devices, only takes effect when - * packet size is equal or larger than the specified value (in 8 byte - * units), e.g. using jumbo frames when setting to E1000_ERT_2048 - */ - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) { + if (adapter->hw.mac.type == e1000_pch2lan) { + /* + * With jumbo frames, excessive C-state transition + * latencies result in dropped transactions. + */ if (adapter->netdev->mtu > ETH_DATA_LEN) { u32 rxdctl = er32(RXDCTL(0)); ew32(RXDCTL(0), rxdctl | 0x3); - if (adapter->flags & FLAG_HAS_ERT) - ew32(ERT, E1000_ERT_2048 | (1 << 13)); - /* - * With jumbo frames and early-receive enabled, - * excessive C-state transition latencies result in - * dropped transactions. - */ pm_qos_update_request(&adapter->netdev->pm_qos_req, 55); } else { pm_qos_update_request(&adapter->netdev->pm_qos_req, @@ -3422,9 +3412,7 @@ void e1000e_reset(struct e1000_adapter *adapter) * if short on Rx space, Rx wins and must trump Tx * adjustment or use Early Receive if available */ - if ((pba < min_rx_space) && - (!(adapter->flags & FLAG_HAS_ERT))) - /* ERT enabled in e1000_configure_rx */ + if (pba < min_rx_space) pba = min_rx_space; } @@ -3438,8 +3426,6 @@ void e1000e_reset(struct e1000_adapter *adapter) * (or the size used for early receive) above it in the Rx FIFO. * Set it to the lower of: * - 90% of the Rx FIFO size, and - * - the full Rx FIFO size minus the early receive size (for parts - * with ERT support assuming ERT set to E1000_ERT_2048), or * - the full Rx FIFO size minus one full frame */ if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) @@ -3450,14 +3436,19 @@ void e1000e_reset(struct e1000_adapter *adapter) fc->current_mode = fc->requested_mode; switch (hw->mac.type) { + case e1000_ich9lan: + case e1000_ich10lan: + if (adapter->netdev->mtu > ETH_DATA_LEN) { + pba = 14; + ew32(PBA, pba); + fc->high_water = 0x2800; + fc->low_water = fc->high_water - 8; + break; + } + /* fall-through */ default: - if ((adapter->flags & FLAG_HAS_ERT) && - (adapter->netdev->mtu > ETH_DATA_LEN)) - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - (E1000_ERT_2048 << 3))); - else - hwm = min(((pba << 10) * 9 / 10), - ((pba << 10) - adapter->max_frame_size)); + hwm = min(((pba << 10) * 9 / 10), + ((pba << 10) - adapter->max_frame_size)); fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ fc->low_water = fc->high_water - 8; @@ -3490,11 +3481,10 @@ void e1000e_reset(struct e1000_adapter *adapter) /* * Disable Adaptive Interrupt Moderation if 2 full packets cannot - * fit in receive buffer and early-receive not supported. + * fit in receive buffer. */ if (adapter->itr_setting & 0x3) { - if (((adapter->max_frame_size * 2) > (pba << 10)) && - !(adapter->flags & FLAG_HAS_ERT)) { + if ((adapter->max_frame_size * 2) > (pba << 10)) { if (!(adapter->flags2 & FLAG2_DISABLE_AIM)) { dev_info(&adapter->pdev->dev, "Interrupt Throttle Rate turned off\n"); @@ -3862,9 +3852,8 @@ static int e1000_open(struct net_device *netdev) E1000_MNG_DHCP_COOKIE_STATUS_VLAN)) e1000_update_mng_vlan(adapter); - /* DMA latency requirement to workaround early-receive/jumbo issue */ - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) + /* DMA latency requirement to workaround jumbo issue */ + if (adapter->hw.mac.type == e1000_pch2lan) pm_qos_add_request(&adapter->netdev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); @@ -3975,8 +3964,7 @@ static int e1000_close(struct net_device *netdev) !test_bit(__E1000_TESTING, &adapter->state)) e1000e_release_hw_control(adapter); - if ((adapter->flags & FLAG_HAS_ERT) || - (adapter->hw.mac.type == e1000_pch2lan)) + if (adapter->hw.mac.type == e1000_pch2lan) pm_qos_remove_request(&adapter->netdev->pm_qos_req); pm_runtime_put_sync(&pdev->dev); -- cgit v1.2.3-70-g09d2 From 90b82984a4ce689d7b1d7132e50bc61ac6f8b74f Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:33 +0000 Subject: e1000e: update workaround for 82579 intermittently disabled during S0->Sx The workaround which toggles the LANPHYPC (LAN PHY Power Control) value bit to force the MAC-Phy interconnect into PCIe mode from SMBus mode during driver load and resume should always be done except if PHY resets are blocked by the Manageability Engine (ME). Previously, the toggle was done only if PHY resets are blocked and the ME was disabled. The rest of the patch is just indentation changes as a consequence of the updated workaround. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 103 +++++++++++++--------------- 1 file changed, 49 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index e446e058250..50a61fcf75c 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -306,7 +306,6 @@ static void e1000_toggle_lanphypc_value_ich8lan(struct e1000_hw *hw) static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) { struct e1000_phy_info *phy = &hw->phy; - u32 fwsm; s32 ret_val = 0; phy->addr = 1; @@ -325,14 +324,14 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) phy->ops.power_down = e1000_power_down_phy_copper_ich8lan; phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT; - /* - * The MAC-PHY interconnect may still be in SMBus mode - * after Sx->S0. If the manageability engine (ME) is - * disabled, then toggle the LANPHYPC Value bit to force - * the interconnect to PCIe mode. - */ - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) && !e1000_check_reset_block(hw)) { + if (!e1000_check_reset_block(hw)) { + u32 fwsm = er32(FWSM); + + /* + * The MAC-PHY interconnect may still be in SMBus mode after + * Sx->S0. If resetting the PHY is not blocked, toggle the + * LANPHYPC Value bit to force the interconnect to PCIe mode. + */ e1000_toggle_lanphypc_value_ich8lan(hw); msleep(50); @@ -340,25 +339,26 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) * Gate automatic PHY configuration by hardware on * non-managed 82579 */ - if (hw->mac.type == e1000_pch2lan) + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) e1000_gate_hw_phy_config_ich8lan(hw, true); - } - /* - * Reset the PHY before any access to it. Doing so, ensures that - * the PHY is in a known good state before we read/write PHY registers. - * The generic reset is sufficient here, because we haven't determined - * the PHY type yet. - */ - ret_val = e1000e_phy_hw_reset_generic(hw); - if (ret_val) - goto out; + /* + * Reset the PHY before any access to it. Doing so, ensures + * that the PHY is in a known good state before we read/write + * PHY registers. The generic reset is sufficient here, + * because we haven't determined the PHY type yet. + */ + ret_val = e1000e_phy_hw_reset_generic(hw); + if (ret_val) + goto out; - /* Ungate automatic PHY configuration on non-managed 82579 */ - if ((hw->mac.type == e1000_pch2lan) && - !(fwsm & E1000_ICH_FWSM_FW_VALID)) { - usleep_range(10000, 20000); - e1000_gate_hw_phy_config_ich8lan(hw, false); + /* Ungate automatic PHY configuration on non-managed 82579 */ + if ((hw->mac.type == e1000_pch2lan) && + !(fwsm & E1000_ICH_FWSM_FW_VALID)) { + usleep_range(10000, 20000); + e1000_gate_hw_phy_config_ich8lan(hw, false); + } } phy->id = e1000_phy_unknown; @@ -3736,42 +3736,37 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) **/ void e1000_resume_workarounds_pchlan(struct e1000_hw *hw) { - u32 fwsm; + u16 phy_id1, phy_id2; + s32 ret_val; - if (hw->mac.type != e1000_pch2lan) + if ((hw->mac.type != e1000_pch2lan) || e1000_check_reset_block(hw)) return; - fwsm = er32(FWSM); - if (!(fwsm & E1000_ICH_FWSM_FW_VALID) || !e1000_check_reset_block(hw)) { - u16 phy_id1, phy_id2; - s32 ret_val; - - ret_val = hw->phy.ops.acquire(hw); - if (ret_val) { - e_dbg("Failed to acquire PHY semaphore in resume\n"); - return; - } + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) { + e_dbg("Failed to acquire PHY semaphore in resume\n"); + return; + } - /* Test access to the PHY registers by reading the ID regs */ - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); - if (ret_val) - goto release; - ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); - if (ret_val) - goto release; + /* Test access to the PHY registers by reading the ID regs */ + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID1, &phy_id1); + if (ret_val) + goto release; + ret_val = hw->phy.ops.read_reg_locked(hw, PHY_ID2, &phy_id2); + if (ret_val) + goto release; - if (hw->phy.id == ((u32)(phy_id1 << 16) | - (u32)(phy_id2 & PHY_REVISION_MASK))) - goto release; + if (hw->phy.id == ((u32)(phy_id1 << 16) | + (u32)(phy_id2 & PHY_REVISION_MASK))) + goto release; - e1000_toggle_lanphypc_value_ich8lan(hw); + e1000_toggle_lanphypc_value_ich8lan(hw); - hw->phy.ops.release(hw); - msleep(50); - e1000_phy_hw_reset(hw); - msleep(50); - return; - } + hw->phy.ops.release(hw); + msleep(50); + e1000_phy_hw_reset(hw); + msleep(50); + return; release: hw->phy.ops.release(hw); -- cgit v1.2.3-70-g09d2 From c077a9065b8d4612e4d55bd53c3563ca10d5c944 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:38 +0000 Subject: e1000e: ICHx/PCHx LOMs should use LPLU setting in NVM when going to Sx When going to Sx with an ICHx/PCH device, the default Low Power Link Up (LPLU, a.k.a. reverse auto-negotiation) behavior should be whatever is set in the NVM. However, the function e1000_suspend_workarounds_ich8lan() called when going to Sx always enabled LPLU in all power states. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 50a61fcf75c..00b5e34fcfa 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -3698,9 +3698,10 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw) * * During S0 to Sx transition, it is possible the link remains at gig * instead of negotiating to a lower speed. Before going to Sx, set - * 'LPLU Enabled' and 'Gig Disable' to force link speed negotiation - * to a lower speed. For PCH and newer parts, the OEM bits PHY register - * (LED, GbE disable and LPLU configurations) also needs to be written. + * 'Gig Disable' to force link speed negotiation to a lower speed based on + * the LPLU setting in the NVM or custom setting. For PCH and newer parts, + * the OEM bits PHY register (LED, GbE disable and LPLU configurations) also + * needs to be written. **/ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) { @@ -3708,7 +3709,7 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) s32 ret_val; phy_ctrl = er32(PHY_CTRL); - phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU | E1000_PHY_CTRL_GBE_DISABLE; + phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; ew32(PHY_CTRL, phy_ctrl); if (hw->mac.type == e1000_ich8lan) -- cgit v1.2.3-70-g09d2 From 7f1557e1422a4cc842af641c6716714751c06865 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:43 +0000 Subject: e1000e: increase Rx PBA to prevent dropping received packets on 82566/82567 During bi-directional stress on some 82566/82567 devices, some received packets were dropped. Increasing the Receive Packet Buffer Allocation resolves this. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 00b5e34fcfa..d99548ce4da 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -4108,7 +4108,7 @@ const struct e1000_info e1000_ich9_info = { | FLAG_HAS_AMT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, @@ -4125,7 +4125,7 @@ const struct e1000_info e1000_ich10_info = { | FLAG_HAS_AMT | FLAG_HAS_FLASH | FLAG_APME_IN_WUC, - .pba = 10, + .pba = 18, .max_hw_frame_size = DEFAULT_JUMBO, .get_variants = e1000_get_variants_ich8lan, .mac_ops = &ich8_mac_ops, -- cgit v1.2.3-70-g09d2 From 464c85e37e6b2d2ad4f3bea23a59408c5595db15 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:49 +0000 Subject: e1000e: conditionally restart autoneg on 82577/8/9 when setting LPLU state When setting the Low Power Link Up (LPLU, a.k.a. reverse auto-negotiation) on 82577/8278/82579, do not restart auto-negotiation if reset of the Phy is blocked by the Manageability Engine. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index d99548ce4da..6a6e6f6d9e7 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1921,7 +1921,9 @@ static s32 e1000_set_lplu_state_pchlan(struct e1000_hw *hw, bool active) else oem_reg &= ~HV_OEM_BITS_LPLU; - oem_reg |= HV_OEM_BITS_RESTART_AN; + if (!e1000_check_reset_block(hw)) + oem_reg |= HV_OEM_BITS_RESTART_AN; + ret_val = e1e_wphy(hw, HV_OEM_BITS, oem_reg); out: -- cgit v1.2.3-70-g09d2 From 434f1392ae3a3934a33d2d16987d857c97951c3d Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:54 +0000 Subject: e1000e: concatenate long debug strings which span multiple lines To ease searching for debug message strings, concatenate strings that span multiple lines even if the resulting line exceeds 80 columns; these will not cause checkpatch warnings. Also, add '\n' and remove unnecessary '\r' from a few debug strings. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 3 +-- drivers/net/ethernet/intel/e1000e/ich8lan.c | 15 +++++---------- drivers/net/ethernet/intel/e1000e/lib.c | 20 ++++++++------------ drivers/net/ethernet/intel/e1000e/phy.c | 3 +-- 4 files changed, 15 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index b3a235c8ed8..f323ce507f5 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -667,8 +667,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw) udelay(1); if (hw->phy.autoneg_wait_to_complete) { - e_dbg("Waiting for forced speed/duplex link " - "on GG82563 phy.\n"); + e_dbg("Waiting for forced speed/duplex link on GG82563 phy.\n"); ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT, 100000, &link); diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 6a6e6f6d9e7..53e5447cbbc 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -902,8 +902,7 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) } if (!timeout) { - e_dbg("Failed to acquire the semaphore, FW or HW has it: " - "FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", + e_dbg("Failed to acquire the semaphore, FW or HW has it: FWSM=0x%8.8x EXTCNF_CTRL=0x%8.8x)\n", er32(FWSM), extcnf_ctrl); extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; ew32(EXTCNF_CTRL, extcnf_ctrl); @@ -2132,8 +2131,7 @@ static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank) return 0; } - e_dbg("Unable to determine valid NVM bank via EEC - " - "reading flash signature\n"); + e_dbg("Unable to determine valid NVM bank via EEC - reading flash signature\n"); /* fall-thru */ default: /* set bank to 0 in case flash read fails */ @@ -2245,8 +2243,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) /* Check if the flash descriptor is valid */ if (hsfsts.hsf_status.fldesvalid == 0) { - e_dbg("Flash descriptor invalid. " - "SW Sequencing must be used.\n"); + e_dbg("Flash descriptor invalid. SW Sequencing must be used.\n"); return -E1000_ERR_NVM; } @@ -2446,8 +2443,7 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; } else if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete.\n"); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } @@ -2798,8 +2794,7 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset, /* Repeat for some time before giving up. */ continue; if (hsfsts.hsf_status.flcdone == 0) { - e_dbg("Timeout error - flash cycle " - "did not complete."); + e_dbg("Timeout error - flash cycle did not complete.\n"); break; } } while (count++ < ICH_FLASH_CYCLE_REPEAT_COUNT); diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c index 78e3f4c0c36..e2678bda859 100644 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ b/drivers/net/ethernet/intel/e1000e/lib.c @@ -653,12 +653,10 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) if (rxcw & E1000_RXCW_SYNCH) { if (!(rxcw & E1000_RXCW_IV)) { mac->serdes_has_link = true; - e_dbg("SERDES: Link up - autoneg " - "completed successfully.\n"); + e_dbg("SERDES: Link up - autoneg completed successfully.\n"); } else { mac->serdes_has_link = false; - e_dbg("SERDES: Link down - invalid" - "codewords detected in autoneg.\n"); + e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); } } else { mac->serdes_has_link = false; @@ -1118,8 +1116,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) return ret_val; if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { - e_dbg("Copper PHY and Auto Neg " - "has not completed.\n"); + e_dbg("Copper PHY and Auto Neg has not completed.\n"); return ret_val; } @@ -1183,11 +1180,10 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) */ if (hw->fc.requested_mode == e1000_fc_full) { hw->fc.current_mode = e1000_fc_full; - e_dbg("Flow Control = FULL.\r\n"); + e_dbg("Flow Control = FULL.\n"); } else { hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = " - "Rx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Rx PAUSE frames only.\n"); } } /* @@ -1203,7 +1199,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_tx_pause; - e_dbg("Flow Control = Tx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Tx PAUSE frames only.\n"); } /* * For transmitting PAUSE frames ONLY. @@ -1218,14 +1214,14 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\r\n"); + e_dbg("Flow Control = Rx PAUSE frames only.\n"); } else { /* * Per the IEEE spec, at this point flow control * should be disabled. */ hw->fc.current_mode = e1000_fc_none; - e_dbg("Flow Control = NONE.\r\n"); + e_dbg("Flow Control = NONE.\n"); } /* diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index 8666476cb9b..ed70d08db5b 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1136,8 +1136,7 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw) if (phy->autoneg_wait_to_complete) { ret_val = e1000_wait_autoneg(hw); if (ret_val) { - e_dbg("Error while waiting for " - "autoneg to complete\n"); + e_dbg("Error while waiting for autoneg to complete\n"); return ret_val; } } -- cgit v1.2.3-70-g09d2 From f2315bf1d1c6e9e0e05262b7910a8f1491d2d60e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:46:59 +0000 Subject: e1000e: convert final strncpy() to strlcpy() Convert the last instances of strncpy() to the preferred strlcpy(). Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 49b5ded2632..d6b451f9a09 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5947,7 +5947,7 @@ static void e1000_print_device_info(struct e1000_adapter *adapter) ret_val = e1000_read_pba_string_generic(hw, pba_str, E1000_PBANUM_LENGTH); if (ret_val) - strncpy((char *)pba_str, "Unknown", sizeof(pba_str) - 1); + strlcpy((char *)pba_str, "Unknown", sizeof(pba_str)); e_info("MAC: %d, PHY: %d, PBA No: %s\n", hw->mac.type, hw->phy.type, pba_str); } @@ -6139,7 +6139,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, e1000e_set_ethtool_ops(netdev); netdev->watchdog_timeo = 5 * HZ; netif_napi_add(netdev, &adapter->napi, e1000_clean, 64); - strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1); + strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); netdev->mem_start = mmio_start; netdev->mem_end = mmio_start + mmio_len; @@ -6321,7 +6321,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev, if (!(adapter->flags & FLAG_HAS_AMT)) e1000e_get_hw_control(adapter); - strncpy(netdev->name, "eth%d", sizeof(netdev->name) - 1); + strlcpy(netdev->name, "eth%d", sizeof(netdev->name)); err = register_netdev(netdev); if (err) goto err_register; -- cgit v1.2.3-70-g09d2 From 058e8edd11fb2c694c3c6c9fd8407439eb3eb954 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Fri, 16 Dec 2011 00:47:04 +0000 Subject: e1000e: increase version number Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index d6b451f9a09..210d27ddd8c 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -56,7 +56,7 @@ #define DRV_EXTRAVERSION "-k" -#define DRV_VERSION "1.5.1" DRV_EXTRAVERSION +#define DRV_VERSION "1.9.5" DRV_EXTRAVERSION char e1000e_driver_name[] = "e1000e"; const char e1000e_driver_version[] = DRV_VERSION; -- cgit v1.2.3-70-g09d2 From c8243ee0488d9bc12995ca7ea02f651db820622e Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sat, 17 Dec 2011 08:32:57 +0000 Subject: e1000e: call er16flash() instead of __er16flash() __er16flash() is not meant to be called directly. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 53e5447cbbc..070a90f78aa 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -2279,7 +2279,7 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw) * cycle has a chance to end before giving up. */ for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) { - hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS); + hsfsts.regval = er16flash(ICH_FLASH_HSFSTS); if (hsfsts.hsf_status.flcinprog == 0) { ret_val = 0; break; -- cgit v1.2.3-70-g09d2 From fe2ddfb510f9d305a6654c7538c5c8faf326a16c Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 21 Dec 2011 09:47:10 +0000 Subject: e1000e: split lib.c into three more-appropriate files The generic lib.c file contains code relative to the various MACs, NVM and Manageability supported by the driver. This patch splits the file into three which are specific to those areas similar to how the PHY-specific code is in phy.c and code specific to the 80003es2lan, 8257x, and ichX MAC families are in their own files. The generic code that is applicable to all MAC/PHY parts supported by the driver remains in netdev.c, param.c and ethtool.c files. No change in functionality, just moving code around for ease of maintenance, with some whitespace and other checkpatch cleanups. Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/Makefile | 3 +- drivers/net/ethernet/intel/e1000e/lib.c | 2686 ---------------------------- drivers/net/ethernet/intel/e1000e/mac.c | 1717 ++++++++++++++++++ drivers/net/ethernet/intel/e1000e/manage.c | 377 ++++ drivers/net/ethernet/intel/e1000e/nvm.c | 647 +++++++ 5 files changed, 2743 insertions(+), 2687 deletions(-) delete mode 100644 drivers/net/ethernet/intel/e1000e/lib.c create mode 100644 drivers/net/ethernet/intel/e1000e/mac.c create mode 100644 drivers/net/ethernet/intel/e1000e/manage.c create mode 100644 drivers/net/ethernet/intel/e1000e/nvm.c (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile index 948c05db5d6..8b888e5f6a0 100644 --- a/drivers/net/ethernet/intel/e1000e/Makefile +++ b/drivers/net/ethernet/intel/e1000e/Makefile @@ -33,5 +33,6 @@ obj-$(CONFIG_E1000E) += e1000e.o e1000e-objs := 82571.o ich8lan.o 80003es2lan.o \ - lib.o phy.o param.o ethtool.o netdev.o + mac.o manage.o nvm.o phy.o \ + param.o ethtool.o netdev.o diff --git a/drivers/net/ethernet/intel/e1000e/lib.c b/drivers/net/ethernet/intel/e1000e/lib.c deleted file mode 100644 index e2678bda859..00000000000 --- a/drivers/net/ethernet/intel/e1000e/lib.c +++ /dev/null @@ -1,2686 +0,0 @@ -/******************************************************************************* - - Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. - - This program is free software; you can redistribute it and/or modify it - under the terms and conditions of the GNU General Public License, - version 2, as published by the Free Software Foundation. - - This program is distributed in the hope it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. - - The full GNU General Public License is included in this distribution in - the file called "COPYING". - - Contact Information: - Linux NICS - e1000-devel Mailing List - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include "e1000.h" - -enum e1000_mng_mode { - e1000_mng_mode_none = 0, - e1000_mng_mode_asf, - e1000_mng_mode_pt, - e1000_mng_mode_ipmi, - e1000_mng_mode_host_if_only -}; - -#define E1000_FACTPS_MNGCG 0x20000000 - -/* Intel(R) Active Management Technology signature */ -#define E1000_IAMT_SIGNATURE 0x544D4149 - -/** - * e1000e_get_bus_info_pcie - Get PCIe bus information - * @hw: pointer to the HW structure - * - * Determines and stores the system bus information for a particular - * network interface. The following bus information is determined and stored: - * bus speed, bus width, type (PCIe), and PCIe function. - **/ -s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - struct e1000_bus_info *bus = &hw->bus; - struct e1000_adapter *adapter = hw->adapter; - u16 pcie_link_status, cap_offset; - - cap_offset = adapter->pdev->pcie_cap; - if (!cap_offset) { - bus->width = e1000_bus_width_unknown; - } else { - pci_read_config_word(adapter->pdev, - cap_offset + PCIE_LINK_STATUS, - &pcie_link_status); - bus->width = (enum e1000_bus_width)((pcie_link_status & - PCIE_LINK_WIDTH_MASK) >> - PCIE_LINK_WIDTH_SHIFT); - } - - mac->ops.set_lan_id(hw); - - return 0; -} - -/** - * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices - * - * @hw: pointer to the HW structure - * - * Determines the LAN function id by reading memory-mapped registers - * and swaps the port value if requested. - **/ -void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) -{ - struct e1000_bus_info *bus = &hw->bus; - u32 reg; - - /* - * The status register reports the correct function number - * for the device regardless of function swap state. - */ - reg = er32(STATUS); - bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; -} - -/** - * e1000_set_lan_id_single_port - Set LAN id for a single port device - * @hw: pointer to the HW structure - * - * Sets the LAN function id to zero for a single port device. - **/ -void e1000_set_lan_id_single_port(struct e1000_hw *hw) -{ - struct e1000_bus_info *bus = &hw->bus; - - bus->func = 0; -} - -/** - * e1000_clear_vfta_generic - Clear VLAN filter table - * @hw: pointer to the HW structure - * - * Clears the register array which contains the VLAN filter table by - * setting all the values to 0. - **/ -void e1000_clear_vfta_generic(struct e1000_hw *hw) -{ - u32 offset; - - for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); - e1e_flush(); - } -} - -/** - * e1000_write_vfta_generic - Write value to VLAN filter table - * @hw: pointer to the HW structure - * @offset: register offset in VLAN filter table - * @value: register value written to VLAN filter table - * - * Writes value at the given offset in the register array which stores - * the VLAN filter table. - **/ -void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) -{ - E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); - e1e_flush(); -} - -/** - * e1000e_init_rx_addrs - Initialize receive address's - * @hw: pointer to the HW structure - * @rar_count: receive address registers - * - * Setup the receive address registers by setting the base receive address - * register to the devices MAC address and clearing all the other receive - * address registers to 0. - **/ -void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) -{ - u32 i; - u8 mac_addr[ETH_ALEN] = {0}; - - /* Setup the receive address */ - e_dbg("Programming MAC Address into RAR[0]\n"); - - e1000e_rar_set(hw, hw->mac.addr, 0); - - /* Zero out the other (rar_entry_count - 1) receive addresses */ - e_dbg("Clearing RAR[1-%u]\n", rar_count-1); - for (i = 1; i < rar_count; i++) - e1000e_rar_set(hw, mac_addr, i); -} - -/** - * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr - * @hw: pointer to the HW structure - * - * Checks the nvm for an alternate MAC address. An alternate MAC address - * can be setup by pre-boot software and must be treated like a permanent - * address and must override the actual permanent MAC address. If an - * alternate MAC address is found it is programmed into RAR0, replacing - * the permanent address that was installed into RAR0 by the Si on reset. - * This function will return SUCCESS unless it encounters an error while - * reading the EEPROM. - **/ -s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) -{ - u32 i; - s32 ret_val = 0; - u16 offset, nvm_alt_mac_addr_offset, nvm_data; - u8 alt_mac_addr[ETH_ALEN]; - - ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); - if (ret_val) - goto out; - - /* not supported on older hardware or 82573 */ - if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) - goto out; - - ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, - &nvm_alt_mac_addr_offset); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - if ((nvm_alt_mac_addr_offset == 0xFFFF) || - (nvm_alt_mac_addr_offset == 0x0000)) - /* There is no Alternate MAC Address */ - goto out; - - if (hw->bus.func == E1000_FUNC_1) - nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; - for (i = 0; i < ETH_ALEN; i += 2) { - offset = nvm_alt_mac_addr_offset + (i >> 1); - ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - alt_mac_addr[i] = (u8)(nvm_data & 0xFF); - alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); - } - - /* if multicast bit is set, the alternate address will not be used */ - if (is_multicast_ether_addr(alt_mac_addr)) { - e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); - goto out; - } - - /* - * We have a valid alternate MAC address, and we want to treat it the - * same as the normal permanent MAC address stored by the HW into the - * RAR. Do this by mapping this address into RAR0. - */ - e1000e_rar_set(hw, alt_mac_addr, 0); - -out: - return ret_val; -} - -/** - * e1000e_rar_set - Set receive address register - * @hw: pointer to the HW structure - * @addr: pointer to the receive address - * @index: receive address array register - * - * Sets the receive address array register at index to the address passed - * in by addr. - **/ -void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) -{ - u32 rar_low, rar_high; - - /* - * HW expects these in little endian so we reverse the byte order - * from network order (big endian) to little endian - */ - rar_low = ((u32) addr[0] | - ((u32) addr[1] << 8) | - ((u32) addr[2] << 16) | ((u32) addr[3] << 24)); - - rar_high = ((u32) addr[4] | ((u32) addr[5] << 8)); - - /* If MAC address zero, no need to set the AV bit */ - if (rar_low || rar_high) - rar_high |= E1000_RAH_AV; - - /* - * Some bridges will combine consecutive 32-bit writes into - * a single burst write, which will malfunction on some parts. - * The flushes avoid this. - */ - ew32(RAL(index), rar_low); - e1e_flush(); - ew32(RAH(index), rar_high); - e1e_flush(); -} - -/** - * e1000_hash_mc_addr - Generate a multicast hash value - * @hw: pointer to the HW structure - * @mc_addr: pointer to a multicast address - * - * Generates a multicast address hash value which is used to determine - * the multicast filter table array address and new table value. See - * e1000_mta_set_generic() - **/ -static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) -{ - u32 hash_value, hash_mask; - u8 bit_shift = 0; - - /* Register count multiplied by bits per register */ - hash_mask = (hw->mac.mta_reg_count * 32) - 1; - - /* - * For a mc_filter_type of 0, bit_shift is the number of left-shifts - * where 0xFF would still fall within the hash mask. - */ - while (hash_mask >> bit_shift != 0xFF) - bit_shift++; - - /* - * The portion of the address that is used for the hash table - * is determined by the mc_filter_type setting. - * The algorithm is such that there is a total of 8 bits of shifting. - * The bit_shift for a mc_filter_type of 0 represents the number of - * left-shifts where the MSB of mc_addr[5] would still fall within - * the hash_mask. Case 0 does this exactly. Since there are a total - * of 8 bits of shifting, then mc_addr[4] will shift right the - * remaining number of bits. Thus 8 - bit_shift. The rest of the - * cases are a variation of this algorithm...essentially raising the - * number of bits to shift mc_addr[5] left, while still keeping the - * 8-bit shifting total. - * - * For example, given the following Destination MAC Address and an - * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), - * we can see that the bit_shift for case 0 is 4. These are the hash - * values resulting from each mc_filter_type... - * [0] [1] [2] [3] [4] [5] - * 01 AA 00 12 34 56 - * LSB MSB - * - * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 - * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 - * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 - * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 - */ - switch (hw->mac.mc_filter_type) { - default: - case 0: - break; - case 1: - bit_shift += 1; - break; - case 2: - bit_shift += 2; - break; - case 3: - bit_shift += 4; - break; - } - - hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | - (((u16) mc_addr[5]) << bit_shift))); - - return hash_value; -} - -/** - * e1000e_update_mc_addr_list_generic - Update Multicast addresses - * @hw: pointer to the HW structure - * @mc_addr_list: array of multicast addresses to program - * @mc_addr_count: number of multicast addresses to program - * - * Updates entire Multicast Table Array. - * The caller must have a packed mc_addr_list of multicast addresses. - **/ -void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, - u8 *mc_addr_list, u32 mc_addr_count) -{ - u32 hash_value, hash_bit, hash_reg; - int i; - - /* clear mta_shadow */ - memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); - - /* update mta_shadow from mc_addr_list */ - for (i = 0; (u32) i < mc_addr_count; i++) { - hash_value = e1000_hash_mc_addr(hw, mc_addr_list); - - hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); - hash_bit = hash_value & 0x1F; - - hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); - mc_addr_list += (ETH_ALEN); - } - - /* replace the entire MTA table */ - for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) - E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); - e1e_flush(); -} - -/** - * e1000e_clear_hw_cntrs_base - Clear base hardware counters - * @hw: pointer to the HW structure - * - * Clears the base hardware counters by reading the counter registers. - **/ -void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) -{ - er32(CRCERRS); - er32(SYMERRS); - er32(MPC); - er32(SCC); - er32(ECOL); - er32(MCC); - er32(LATECOL); - er32(COLC); - er32(DC); - er32(SEC); - er32(RLEC); - er32(XONRXC); - er32(XONTXC); - er32(XOFFRXC); - er32(XOFFTXC); - er32(FCRUC); - er32(GPRC); - er32(BPRC); - er32(MPRC); - er32(GPTC); - er32(GORCL); - er32(GORCH); - er32(GOTCL); - er32(GOTCH); - er32(RNBC); - er32(RUC); - er32(RFC); - er32(ROC); - er32(RJC); - er32(TORL); - er32(TORH); - er32(TOTL); - er32(TOTH); - er32(TPR); - er32(TPT); - er32(MPTC); - er32(BPTC); -} - -/** - * e1000e_check_for_copper_link - Check for link (Copper) - * @hw: pointer to the HW structure - * - * Checks to see of the link status of the hardware has changed. If a - * change in link status has been detected, then we read the PHY registers - * to get the current speed/duplex if link exists. - **/ -s32 e1000e_check_for_copper_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - bool link; - - /* - * We only want to go out to the PHY registers to see if Auto-Neg - * has completed and/or if our link status has changed. The - * get_link_status flag is set upon receiving a Link Status - * Change or Rx Sequence Error interrupt. - */ - if (!mac->get_link_status) - return 0; - - /* - * First we want to see if the MII Status Register reports - * link. If so, then we want to get the current speed/duplex - * of the PHY. - */ - ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); - if (ret_val) - return ret_val; - - if (!link) - return ret_val; /* No link detected */ - - mac->get_link_status = false; - - /* - * Check if there was DownShift, must be checked - * immediately after link-up - */ - e1000e_check_downshift(hw); - - /* - * If we are forcing speed/duplex, then we simply return since - * we have already determined whether we have link or not. - */ - if (!mac->autoneg) { - ret_val = -E1000_ERR_CONFIG; - return ret_val; - } - - /* - * Auto-Neg is enabled. Auto Speed Detection takes care - * of MAC speed/duplex configuration. So we only need to - * configure Collision Distance in the MAC. - */ - e1000e_config_collision_dist(hw); - - /* - * Configure Flow Control now that Auto-Neg has completed. - * First, we need to restore the desired flow control - * settings because we may have had to re-autoneg with a - * different link partner. - */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) - e_dbg("Error configuring flow control\n"); - - return ret_val; -} - -/** - * e1000e_check_for_fiber_link - Check for link (Fiber) - * @hw: pointer to the HW structure - * - * Checks for link up on the hardware. If link is not up and we have - * a signal, then we need to force link up. - **/ -s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 rxcw; - u32 ctrl; - u32 status; - s32 ret_val; - - ctrl = er32(CTRL); - status = er32(STATUS); - rxcw = er32(RXCW); - - /* - * If we don't have link (auto-negotiation failed or link partner - * cannot auto-negotiate), the cable is plugged in (we have signal), - * and our link partner is not trying to auto-negotiate with us (we - * are receiving idles or data), we need to force link up. We also - * need to give auto-negotiation time to complete, in case the cable - * was just plugged in. The autoneg_failed flag does this. - */ - /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && - (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - return 0; - } - e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); - - /* Disable auto-negotiation in the TXCW register */ - ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); - - /* Force link-up and also force full-duplex. */ - ctrl = er32(CTRL); - ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); - ew32(CTRL, ctrl); - - /* Configure Flow Control after forcing link up. */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { - e_dbg("Error configuring flow control\n"); - return ret_val; - } - } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* - * If we are forcing link and we are receiving /C/ ordered - * sets, re-enable auto-negotiation in the TXCW register - * and disable forced link in the Device Control register - * in an attempt to auto-negotiate with our link partner. - */ - e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); - ew32(TXCW, mac->txcw); - ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); - - mac->serdes_has_link = true; - } - - return 0; -} - -/** - * e1000e_check_for_serdes_link - Check for link (Serdes) - * @hw: pointer to the HW structure - * - * Checks for link up on the hardware. If link is not up and we have - * a signal, then we need to force link up. - **/ -s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 rxcw; - u32 ctrl; - u32 status; - s32 ret_val; - - ctrl = er32(CTRL); - status = er32(STATUS); - rxcw = er32(RXCW); - - /* - * If we don't have link (auto-negotiation failed or link partner - * cannot auto-negotiate), and our link partner is not trying to - * auto-negotiate with us (we are receiving idles or data), - * we need to force link up. We also need to give auto-negotiation - * time to complete. - */ - /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ - if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { - if (mac->autoneg_failed == 0) { - mac->autoneg_failed = 1; - return 0; - } - e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); - - /* Disable auto-negotiation in the TXCW register */ - ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); - - /* Force link-up and also force full-duplex. */ - ctrl = er32(CTRL); - ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); - ew32(CTRL, ctrl); - - /* Configure Flow Control after forcing link up. */ - ret_val = e1000e_config_fc_after_link_up(hw); - if (ret_val) { - e_dbg("Error configuring flow control\n"); - return ret_val; - } - } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { - /* - * If we are forcing link and we are receiving /C/ ordered - * sets, re-enable auto-negotiation in the TXCW register - * and disable forced link in the Device Control register - * in an attempt to auto-negotiate with our link partner. - */ - e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); - ew32(TXCW, mac->txcw); - ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); - - mac->serdes_has_link = true; - } else if (!(E1000_TXCW_ANE & er32(TXCW))) { - /* - * If we force link for non-auto-negotiation switch, check - * link status based on MAC synchronization for internal - * serdes media type. - */ - /* SYNCH bit and IV bit are sticky. */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_SYNCH) { - if (!(rxcw & E1000_RXCW_IV)) { - mac->serdes_has_link = true; - e_dbg("SERDES: Link up - forced.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - force failed.\n"); - } - } - - if (E1000_TXCW_ANE & er32(TXCW)) { - status = er32(STATUS); - if (status & E1000_STATUS_LU) { - /* SYNCH bit and IV bit are sticky, so reread rxcw. */ - udelay(10); - rxcw = er32(RXCW); - if (rxcw & E1000_RXCW_SYNCH) { - if (!(rxcw & E1000_RXCW_IV)) { - mac->serdes_has_link = true; - e_dbg("SERDES: Link up - autoneg completed successfully.\n"); - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - no sync.\n"); - } - } else { - mac->serdes_has_link = false; - e_dbg("SERDES: Link down - autoneg failed\n"); - } - } - - return 0; -} - -/** - * e1000_set_default_fc_generic - Set flow control default values - * @hw: pointer to the HW structure - * - * Read the EEPROM for the default values for flow control and store the - * values. - **/ -static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 nvm_data; - - /* - * Read and store word 0x0F of the EEPROM. This word contains bits - * that determine the hardware's default PAUSE (flow control) mode, - * a bit that determines whether the HW defaults to enabling or - * disabling auto-negotiation, and the direction of the - * SW defined pins. If there is no SW over-ride of the flow - * control setting, then the variable hw->fc will - * be initialized based on a value in the EEPROM. - */ - ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); - - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - - if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) - hw->fc.requested_mode = e1000_fc_none; - else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == - NVM_WORD0F_ASM_DIR) - hw->fc.requested_mode = e1000_fc_tx_pause; - else - hw->fc.requested_mode = e1000_fc_full; - - return 0; -} - -/** - * e1000e_setup_link - Setup flow control and link settings - * @hw: pointer to the HW structure - * - * Determines which flow control settings to use, then configures flow - * control. Calls the appropriate media-specific link configuration - * function. Assuming the adapter has a valid link partner, a valid link - * should be established. Assumes the hardware has previously been reset - * and the transmitter and receiver are not enabled. - **/ -s32 e1000e_setup_link(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - - /* - * In the case of the phy reset being blocked, we already have a link. - * We do not need to set it up again. - */ - if (e1000_check_reset_block(hw)) - return 0; - - /* - * If requested flow control is set to default, set flow control - * based on the EEPROM flow control settings. - */ - if (hw->fc.requested_mode == e1000_fc_default) { - ret_val = e1000_set_default_fc_generic(hw); - if (ret_val) - return ret_val; - } - - /* - * Save off the requested flow control mode for use later. Depending - * on the link partner's capabilities, we may or may not use this mode. - */ - hw->fc.current_mode = hw->fc.requested_mode; - - e_dbg("After fix-ups FlowControl is now = %x\n", - hw->fc.current_mode); - - /* Call the necessary media_type subroutine to configure the link. */ - ret_val = mac->ops.setup_physical_interface(hw); - if (ret_val) - return ret_val; - - /* - * Initialize the flow control address, type, and PAUSE timer - * registers to their default values. This is done even if flow - * control is disabled, because it does not hurt anything to - * initialize these registers. - */ - e_dbg("Initializing the Flow Control address, type and timer regs\n"); - ew32(FCT, FLOW_CONTROL_TYPE); - ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH); - ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW); - - ew32(FCTTV, hw->fc.pause_time); - - return e1000e_set_fc_watermarks(hw); -} - -/** - * e1000_commit_fc_settings_generic - Configure flow control - * @hw: pointer to the HW structure - * - * Write the flow control settings to the Transmit Config Word Register (TXCW) - * base on the flow control settings in e1000_mac_info. - **/ -static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 txcw; - - /* - * Check for a software override of the flow control settings, and - * setup the device accordingly. If auto-negotiation is enabled, then - * software will have to set the "PAUSE" bits to the correct value in - * the Transmit Config Word Register (TXCW) and re-start auto- - * negotiation. However, if auto-negotiation is disabled, then - * software will have to manually configure the two flow control enable - * bits in the CTRL register. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause frames, - * but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames but we - * do not support receiving pause frames). - * 3: Both Rx and Tx flow control (symmetric) are enabled. - */ - switch (hw->fc.current_mode) { - case e1000_fc_none: - /* Flow control completely disabled by a software over-ride. */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); - break; - case e1000_fc_rx_pause: - /* - * Rx Flow control is enabled and Tx Flow control is disabled - * by a software over-ride. Since there really isn't a way to - * advertise that we are capable of Rx Pause ONLY, we will - * advertise that we support both symmetric and asymmetric Rx - * PAUSE. Later, we will disable the adapter's ability to send - * PAUSE frames. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - case e1000_fc_tx_pause: - /* - * Tx Flow control is enabled, and Rx Flow control is disabled, - * by a software over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); - break; - case e1000_fc_full: - /* - * Flow control (both Rx and Tx) is enabled by a software - * over-ride. - */ - txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); - break; - default: - e_dbg("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - break; - } - - ew32(TXCW, txcw); - mac->txcw = txcw; - - return 0; -} - -/** - * e1000_poll_fiber_serdes_link_generic - Poll for link up - * @hw: pointer to the HW structure - * - * Polls for link up by reading the status register, if link fails to come - * up with auto-negotiation, then the link is forced if a signal is detected. - **/ -static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - u32 i, status; - s32 ret_val; - - /* - * If we have a signal (the cable is plugged in, or assumed true for - * serdes media) then poll for a "Link-Up" indication in the Device - * Status Register. Time-out if a link isn't seen in 500 milliseconds - * seconds (Auto-negotiation should complete in less than 500 - * milliseconds even if the other end is doing it in SW). - */ - for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { - usleep_range(10000, 20000); - status = er32(STATUS); - if (status & E1000_STATUS_LU) - break; - } - if (i == FIBER_LINK_UP_LIMIT) { - e_dbg("Never got a valid link from auto-neg!!!\n"); - mac->autoneg_failed = 1; - /* - * AutoNeg failed to achieve a link, so we'll call - * mac->check_for_link. This routine will force the - * link up if we detect a signal. This will allow us to - * communicate with non-autonegotiating link partners. - */ - ret_val = mac->ops.check_for_link(hw); - if (ret_val) { - e_dbg("Error while checking for link\n"); - return ret_val; - } - mac->autoneg_failed = 0; - } else { - mac->autoneg_failed = 0; - e_dbg("Valid Link Found\n"); - } - - return 0; -} - -/** - * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes - * @hw: pointer to the HW structure - * - * Configures collision distance and flow control for fiber and serdes - * links. Upon successful setup, poll for link. - **/ -s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) -{ - u32 ctrl; - s32 ret_val; - - ctrl = er32(CTRL); - - /* Take the link out of reset */ - ctrl &= ~E1000_CTRL_LRST; - - e1000e_config_collision_dist(hw); - - ret_val = e1000_commit_fc_settings_generic(hw); - if (ret_val) - return ret_val; - - /* - * Since auto-negotiation is enabled, take the link out of reset (the - * link will be in reset, because we previously reset the chip). This - * will restart auto-negotiation. If auto-negotiation is successful - * then the link-up status bit will be set and the flow control enable - * bits (RFCE and TFCE) will be set according to their negotiated value. - */ - e_dbg("Auto-negotiation enabled\n"); - - ew32(CTRL, ctrl); - e1e_flush(); - usleep_range(1000, 2000); - - /* - * For these adapters, the SW definable pin 1 is set when the optics - * detect a signal. If we have a signal, then poll for a "Link-Up" - * indication. - */ - if (hw->phy.media_type == e1000_media_type_internal_serdes || - (er32(CTRL) & E1000_CTRL_SWDPIN1)) { - ret_val = e1000_poll_fiber_serdes_link_generic(hw); - } else { - e_dbg("No signal detected\n"); - } - - return 0; -} - -/** - * e1000e_config_collision_dist - Configure collision distance - * @hw: pointer to the HW structure - * - * Configures the collision distance to the default value and is used - * during link setup. Currently no func pointer exists and all - * implementations are handled in the generic version of this function. - **/ -void e1000e_config_collision_dist(struct e1000_hw *hw) -{ - u32 tctl; - - tctl = er32(TCTL); - - tctl &= ~E1000_TCTL_COLD; - tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; - - ew32(TCTL, tctl); - e1e_flush(); -} - -/** - * e1000e_set_fc_watermarks - Set flow control high/low watermarks - * @hw: pointer to the HW structure - * - * Sets the flow control high/low threshold (watermark) registers. If - * flow control XON frame transmission is enabled, then set XON frame - * transmission as well. - **/ -s32 e1000e_set_fc_watermarks(struct e1000_hw *hw) -{ - u32 fcrtl = 0, fcrth = 0; - - /* - * Set the flow control receive threshold registers. Normally, - * these registers will be set to a default threshold that may be - * adjusted later by the driver's runtime code. However, if the - * ability to transmit pause frames is not enabled, then these - * registers will be set to 0. - */ - if (hw->fc.current_mode & e1000_fc_tx_pause) { - /* - * We need to set up the Receive Threshold high and low water - * marks as well as (optionally) enabling the transmission of - * XON frames. - */ - fcrtl = hw->fc.low_water; - fcrtl |= E1000_FCRTL_XONE; - fcrth = hw->fc.high_water; - } - ew32(FCRTL, fcrtl); - ew32(FCRTH, fcrth); - - return 0; -} - -/** - * e1000e_force_mac_fc - Force the MAC's flow control settings - * @hw: pointer to the HW structure - * - * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the - * device control register to reflect the adapter settings. TFCE and RFCE - * need to be explicitly set by software when a copper PHY is used because - * autonegotiation is managed by the PHY rather than the MAC. Software must - * also configure these bits when link is forced on a fiber connection. - **/ -s32 e1000e_force_mac_fc(struct e1000_hw *hw) -{ - u32 ctrl; - - ctrl = er32(CTRL); - - /* - * Because we didn't get link via the internal auto-negotiation - * mechanism (we either forced link or we got link via PHY - * auto-neg), we have to manually enable/disable transmit an - * receive flow control. - * - * The "Case" statement below enables/disable flow control - * according to the "hw->fc.current_mode" parameter. - * - * The possible values of the "fc" parameter are: - * 0: Flow control is completely disabled - * 1: Rx flow control is enabled (we can receive pause - * frames but not send pause frames). - * 2: Tx flow control is enabled (we can send pause frames - * frames but we do not receive pause frames). - * 3: Both Rx and Tx flow control (symmetric) is enabled. - * other: No other values should be possible at this point. - */ - e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode); - - switch (hw->fc.current_mode) { - case e1000_fc_none: - ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); - break; - case e1000_fc_rx_pause: - ctrl &= (~E1000_CTRL_TFCE); - ctrl |= E1000_CTRL_RFCE; - break; - case e1000_fc_tx_pause: - ctrl &= (~E1000_CTRL_RFCE); - ctrl |= E1000_CTRL_TFCE; - break; - case e1000_fc_full: - ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); - break; - default: - e_dbg("Flow control param set incorrectly\n"); - return -E1000_ERR_CONFIG; - } - - ew32(CTRL, ctrl); - - return 0; -} - -/** - * e1000e_config_fc_after_link_up - Configures flow control after link - * @hw: pointer to the HW structure - * - * Checks the status of auto-negotiation after link up to ensure that the - * speed and duplex were not forced. If the link needed to be forced, then - * flow control needs to be forced also. If auto-negotiation is enabled - * and did not fail, then we configure flow control based on our link - * partner. - **/ -s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val = 0; - u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; - u16 speed, duplex; - - /* - * Check for the case where we have fiber media and auto-neg failed - * so we had to force link. In this case, we need to force the - * configuration of the MAC to match the "fc" parameter. - */ - if (mac->autoneg_failed) { - if (hw->phy.media_type == e1000_media_type_fiber || - hw->phy.media_type == e1000_media_type_internal_serdes) - ret_val = e1000e_force_mac_fc(hw); - } else { - if (hw->phy.media_type == e1000_media_type_copper) - ret_val = e1000e_force_mac_fc(hw); - } - - if (ret_val) { - e_dbg("Error forcing flow control settings\n"); - return ret_val; - } - - /* - * Check for the case where we have copper media and auto-neg is - * enabled. In this case, we need to check and see if Auto-Neg - * has completed, and if so, how the PHY and link partner has - * flow control configured. - */ - if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { - /* - * Read the MII Status Register and check to see if AutoNeg - * has completed. We read this twice because this reg has - * some "sticky" (latched) bits. - */ - ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) - return ret_val; - ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); - if (ret_val) - return ret_val; - - if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { - e_dbg("Copper PHY and Auto Neg has not completed.\n"); - return ret_val; - } - - /* - * The AutoNeg process has completed, so we now need to - * read both the Auto Negotiation Advertisement - * Register (Address 4) and the Auto_Negotiation Base - * Page Ability Register (Address 5) to determine how - * flow control was negotiated. - */ - ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); - if (ret_val) - return ret_val; - ret_val = - e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); - if (ret_val) - return ret_val; - - /* - * Two bits in the Auto Negotiation Advertisement Register - * (Address 4) and two bits in the Auto Negotiation Base - * Page Ability Register (Address 5) determine flow control - * for both the PHY and the link partner. The following - * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, - * 1999, describes these PAUSE resolution bits and how flow - * control is determined based upon these settings. - * NOTE: DC = Don't Care - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution - *-------|---------|-------|---------|-------------------- - * 0 | 0 | DC | DC | e1000_fc_none - * 0 | 1 | 0 | DC | e1000_fc_none - * 0 | 1 | 1 | 0 | e1000_fc_none - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - * 1 | 0 | 0 | DC | e1000_fc_none - * 1 | DC | 1 | DC | e1000_fc_full - * 1 | 1 | 0 | 0 | e1000_fc_none - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - * - * Are both PAUSE bits set to 1? If so, this implies - * Symmetric Flow Control is enabled at both ends. The - * ASM_DIR bits are irrelevant per the spec. - * - * For Symmetric Flow Control: - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | DC | 1 | DC | E1000_fc_full - * - */ - if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { - /* - * Now we need to check if the user selected Rx ONLY - * of pause frames. In this case, we had to advertise - * FULL flow control because we could not advertise Rx - * ONLY. Hence, we must now check to see if we need to - * turn OFF the TRANSMISSION of PAUSE frames. - */ - if (hw->fc.requested_mode == e1000_fc_full) { - hw->fc.current_mode = e1000_fc_full; - e_dbg("Flow Control = FULL.\n"); - } else { - hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\n"); - } - } - /* - * For receiving PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 0 | 1 | 1 | 1 | e1000_fc_tx_pause - */ - else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - hw->fc.current_mode = e1000_fc_tx_pause; - e_dbg("Flow Control = Tx PAUSE frames only.\n"); - } - /* - * For transmitting PAUSE frames ONLY. - * - * LOCAL DEVICE | LINK PARTNER - * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result - *-------|---------|-------|---------|-------------------- - * 1 | 1 | 0 | 1 | e1000_fc_rx_pause - */ - else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && - (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && - !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && - (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { - hw->fc.current_mode = e1000_fc_rx_pause; - e_dbg("Flow Control = Rx PAUSE frames only.\n"); - } else { - /* - * Per the IEEE spec, at this point flow control - * should be disabled. - */ - hw->fc.current_mode = e1000_fc_none; - e_dbg("Flow Control = NONE.\n"); - } - - /* - * Now we need to do one last check... If we auto- - * negotiated to HALF DUPLEX, flow control should not be - * enabled per IEEE 802.3 spec. - */ - ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); - if (ret_val) { - e_dbg("Error getting link speed and duplex\n"); - return ret_val; - } - - if (duplex == HALF_DUPLEX) - hw->fc.current_mode = e1000_fc_none; - - /* - * Now we call a subroutine to actually force the MAC - * controller to use the correct flow control settings. - */ - ret_val = e1000e_force_mac_fc(hw); - if (ret_val) { - e_dbg("Error forcing flow control settings\n"); - return ret_val; - } - } - - return 0; -} - -/** - * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex - * @hw: pointer to the HW structure - * @speed: stores the current speed - * @duplex: stores the current duplex - * - * Read the status register for the current speed/duplex and store the current - * speed and duplex for copper connections. - **/ -s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, u16 *duplex) -{ - u32 status; - - status = er32(STATUS); - if (status & E1000_STATUS_SPEED_1000) - *speed = SPEED_1000; - else if (status & E1000_STATUS_SPEED_100) - *speed = SPEED_100; - else - *speed = SPEED_10; - - if (status & E1000_STATUS_FD) - *duplex = FULL_DUPLEX; - else - *duplex = HALF_DUPLEX; - - e_dbg("%u Mbps, %s Duplex\n", - *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10, - *duplex == FULL_DUPLEX ? "Full" : "Half"); - - return 0; -} - -/** - * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex - * @hw: pointer to the HW structure - * @speed: stores the current speed - * @duplex: stores the current duplex - * - * Sets the speed and duplex to gigabit full duplex (the only possible option) - * for fiber/serdes links. - **/ -s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, u16 *duplex) -{ - *speed = SPEED_1000; - *duplex = FULL_DUPLEX; - - return 0; -} - -/** - * e1000e_get_hw_semaphore - Acquire hardware semaphore - * @hw: pointer to the HW structure - * - * Acquire the HW semaphore to access the PHY or NVM - **/ -s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - s32 timeout = hw->nvm.word_size + 1; - s32 i = 0; - - /* Get the SW semaphore */ - while (i < timeout) { - swsm = er32(SWSM); - if (!(swsm & E1000_SWSM_SMBI)) - break; - - udelay(50); - i++; - } - - if (i == timeout) { - e_dbg("Driver can't access device - SMBI bit is set.\n"); - return -E1000_ERR_NVM; - } - - /* Get the FW semaphore. */ - for (i = 0; i < timeout; i++) { - swsm = er32(SWSM); - ew32(SWSM, swsm | E1000_SWSM_SWESMBI); - - /* Semaphore acquired if bit latched */ - if (er32(SWSM) & E1000_SWSM_SWESMBI) - break; - - udelay(50); - } - - if (i == timeout) { - /* Release semaphores */ - e1000e_put_hw_semaphore(hw); - e_dbg("Driver can't access the NVM\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000e_put_hw_semaphore - Release hardware semaphore - * @hw: pointer to the HW structure - * - * Release hardware semaphore used to access the PHY or NVM - **/ -void e1000e_put_hw_semaphore(struct e1000_hw *hw) -{ - u32 swsm; - - swsm = er32(SWSM); - swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); - ew32(SWSM, swsm); -} - -/** - * e1000e_get_auto_rd_done - Check for auto read completion - * @hw: pointer to the HW structure - * - * Check EEPROM for Auto Read done bit. - **/ -s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) -{ - s32 i = 0; - - while (i < AUTO_READ_DONE_TIMEOUT) { - if (er32(EECD) & E1000_EECD_AUTO_RD) - break; - usleep_range(1000, 2000); - i++; - } - - if (i == AUTO_READ_DONE_TIMEOUT) { - e_dbg("Auto read by HW from NVM has not completed.\n"); - return -E1000_ERR_RESET; - } - - return 0; -} - -/** - * e1000e_valid_led_default - Verify a valid default LED config - * @hw: pointer to the HW structure - * @data: pointer to the NVM (EEPROM) - * - * Read the EEPROM for the current default LED configuration. If the - * LED configuration is not valid, set to a valid LED configuration. - **/ -s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data) -{ - s32 ret_val; - - ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - - if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) - *data = ID_LED_DEFAULT; - - return 0; -} - -/** - * e1000e_id_led_init - - * @hw: pointer to the HW structure - * - **/ -s32 e1000e_id_led_init(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - s32 ret_val; - const u32 ledctl_mask = 0x000000FF; - const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; - const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; - u16 data, i, temp; - const u16 led_mask = 0x0F; - - ret_val = hw->nvm.ops.valid_led_default(hw, &data); - if (ret_val) - return ret_val; - - mac->ledctl_default = er32(LEDCTL); - mac->ledctl_mode1 = mac->ledctl_default; - mac->ledctl_mode2 = mac->ledctl_default; - - for (i = 0; i < 4; i++) { - temp = (data >> (i << 2)) & led_mask; - switch (temp) { - case ID_LED_ON1_DEF2: - case ID_LED_ON1_ON2: - case ID_LED_ON1_OFF2: - mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode1 |= ledctl_on << (i << 3); - break; - case ID_LED_OFF1_DEF2: - case ID_LED_OFF1_ON2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode1 |= ledctl_off << (i << 3); - break; - default: - /* Do nothing */ - break; - } - switch (temp) { - case ID_LED_DEF1_ON2: - case ID_LED_ON1_ON2: - case ID_LED_OFF1_ON2: - mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode2 |= ledctl_on << (i << 3); - break; - case ID_LED_DEF1_OFF2: - case ID_LED_ON1_OFF2: - case ID_LED_OFF1_OFF2: - mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); - mac->ledctl_mode2 |= ledctl_off << (i << 3); - break; - default: - /* Do nothing */ - break; - } - } - - return 0; -} - -/** - * e1000e_setup_led_generic - Configures SW controllable LED - * @hw: pointer to the HW structure - * - * This prepares the SW controllable LED for use and saves the current state - * of the LED so it can be later restored. - **/ -s32 e1000e_setup_led_generic(struct e1000_hw *hw) -{ - u32 ledctl; - - if (hw->mac.ops.setup_led != e1000e_setup_led_generic) - return -E1000_ERR_CONFIG; - - if (hw->phy.media_type == e1000_media_type_fiber) { - ledctl = er32(LEDCTL); - hw->mac.ledctl_default = ledctl; - /* Turn off LED0 */ - ledctl &= ~(E1000_LEDCTL_LED0_IVRT | - E1000_LEDCTL_LED0_BLINK | - E1000_LEDCTL_LED0_MODE_MASK); - ledctl |= (E1000_LEDCTL_MODE_LED_OFF << - E1000_LEDCTL_LED0_MODE_SHIFT); - ew32(LEDCTL, ledctl); - } else if (hw->phy.media_type == e1000_media_type_copper) { - ew32(LEDCTL, hw->mac.ledctl_mode1); - } - - return 0; -} - -/** - * e1000e_cleanup_led_generic - Set LED config to default operation - * @hw: pointer to the HW structure - * - * Remove the current LED configuration and set the LED configuration - * to the default value, saved from the EEPROM. - **/ -s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) -{ - ew32(LEDCTL, hw->mac.ledctl_default); - return 0; -} - -/** - * e1000e_blink_led_generic - Blink LED - * @hw: pointer to the HW structure - * - * Blink the LEDs which are set to be on. - **/ -s32 e1000e_blink_led_generic(struct e1000_hw *hw) -{ - u32 ledctl_blink = 0; - u32 i; - - if (hw->phy.media_type == e1000_media_type_fiber) { - /* always blink LED0 for PCI-E fiber */ - ledctl_blink = E1000_LEDCTL_LED0_BLINK | - (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); - } else { - /* - * set the blink bit for each LED that's "on" (0x0E) - * in ledctl_mode2 - */ - ledctl_blink = hw->mac.ledctl_mode2; - for (i = 0; i < 4; i++) - if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == - E1000_LEDCTL_MODE_LED_ON) - ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << - (i * 8)); - } - - ew32(LEDCTL, ledctl_blink); - - return 0; -} - -/** - * e1000e_led_on_generic - Turn LED on - * @hw: pointer to the HW structure - * - * Turn LED on. - **/ -s32 e1000e_led_on_generic(struct e1000_hw *hw) -{ - u32 ctrl; - - switch (hw->phy.media_type) { - case e1000_media_type_fiber: - ctrl = er32(CTRL); - ctrl &= ~E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - ew32(CTRL, ctrl); - break; - case e1000_media_type_copper: - ew32(LEDCTL, hw->mac.ledctl_mode2); - break; - default: - break; - } - - return 0; -} - -/** - * e1000e_led_off_generic - Turn LED off - * @hw: pointer to the HW structure - * - * Turn LED off. - **/ -s32 e1000e_led_off_generic(struct e1000_hw *hw) -{ - u32 ctrl; - - switch (hw->phy.media_type) { - case e1000_media_type_fiber: - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_SWDPIN0; - ctrl |= E1000_CTRL_SWDPIO0; - ew32(CTRL, ctrl); - break; - case e1000_media_type_copper: - ew32(LEDCTL, hw->mac.ledctl_mode1); - break; - default: - break; - } - - return 0; -} - -/** - * e1000e_set_pcie_no_snoop - Set PCI-express capabilities - * @hw: pointer to the HW structure - * @no_snoop: bitmap of snoop events - * - * Set the PCI-express register to snoop for events enabled in 'no_snoop'. - **/ -void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) -{ - u32 gcr; - - if (no_snoop) { - gcr = er32(GCR); - gcr &= ~(PCIE_NO_SNOOP_ALL); - gcr |= no_snoop; - ew32(GCR, gcr); - } -} - -/** - * e1000e_disable_pcie_master - Disables PCI-express master access - * @hw: pointer to the HW structure - * - * Returns 0 if successful, else returns -10 - * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused - * the master requests to be disabled. - * - * Disables PCI-Express master access and verifies there are no pending - * requests. - **/ -s32 e1000e_disable_pcie_master(struct e1000_hw *hw) -{ - u32 ctrl; - s32 timeout = MASTER_DISABLE_TIMEOUT; - - ctrl = er32(CTRL); - ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; - ew32(CTRL, ctrl); - - while (timeout) { - if (!(er32(STATUS) & - E1000_STATUS_GIO_MASTER_ENABLE)) - break; - udelay(100); - timeout--; - } - - if (!timeout) { - e_dbg("Master requests are pending.\n"); - return -E1000_ERR_MASTER_REQUESTS_PENDING; - } - - return 0; -} - -/** - * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing - * @hw: pointer to the HW structure - * - * Reset the Adaptive Interframe Spacing throttle to default values. - **/ -void e1000e_reset_adaptive(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - - if (!mac->adaptive_ifs) { - e_dbg("Not in Adaptive IFS mode!\n"); - goto out; - } - - mac->current_ifs_val = 0; - mac->ifs_min_val = IFS_MIN; - mac->ifs_max_val = IFS_MAX; - mac->ifs_step_size = IFS_STEP; - mac->ifs_ratio = IFS_RATIO; - - mac->in_ifs_mode = false; - ew32(AIT, 0); -out: - return; -} - -/** - * e1000e_update_adaptive - Update Adaptive Interframe Spacing - * @hw: pointer to the HW structure - * - * Update the Adaptive Interframe Spacing Throttle value based on the - * time between transmitted packets and time between collisions. - **/ -void e1000e_update_adaptive(struct e1000_hw *hw) -{ - struct e1000_mac_info *mac = &hw->mac; - - if (!mac->adaptive_ifs) { - e_dbg("Not in Adaptive IFS mode!\n"); - goto out; - } - - if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { - if (mac->tx_packet_delta > MIN_NUM_XMITS) { - mac->in_ifs_mode = true; - if (mac->current_ifs_val < mac->ifs_max_val) { - if (!mac->current_ifs_val) - mac->current_ifs_val = mac->ifs_min_val; - else - mac->current_ifs_val += - mac->ifs_step_size; - ew32(AIT, mac->current_ifs_val); - } - } - } else { - if (mac->in_ifs_mode && - (mac->tx_packet_delta <= MIN_NUM_XMITS)) { - mac->current_ifs_val = 0; - mac->in_ifs_mode = false; - ew32(AIT, 0); - } - } -out: - return; -} - -/** - * e1000_raise_eec_clk - Raise EEPROM clock - * @hw: pointer to the HW structure - * @eecd: pointer to the EEPROM - * - * Enable/Raise the EEPROM clock bit. - **/ -static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) -{ - *eecd = *eecd | E1000_EECD_SK; - ew32(EECD, *eecd); - e1e_flush(); - udelay(hw->nvm.delay_usec); -} - -/** - * e1000_lower_eec_clk - Lower EEPROM clock - * @hw: pointer to the HW structure - * @eecd: pointer to the EEPROM - * - * Clear/Lower the EEPROM clock bit. - **/ -static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) -{ - *eecd = *eecd & ~E1000_EECD_SK; - ew32(EECD, *eecd); - e1e_flush(); - udelay(hw->nvm.delay_usec); -} - -/** - * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM - * @hw: pointer to the HW structure - * @data: data to send to the EEPROM - * @count: number of bits to shift out - * - * We need to shift 'count' bits out to the EEPROM. So, the value in the - * "data" parameter will be shifted out to the EEPROM one bit at a time. - * In order to do this, "data" must be broken down into bits. - **/ -static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - u32 mask; - - mask = 0x01 << (count - 1); - if (nvm->type == e1000_nvm_eeprom_spi) - eecd |= E1000_EECD_DO; - - do { - eecd &= ~E1000_EECD_DI; - - if (data & mask) - eecd |= E1000_EECD_DI; - - ew32(EECD, eecd); - e1e_flush(); - - udelay(nvm->delay_usec); - - e1000_raise_eec_clk(hw, &eecd); - e1000_lower_eec_clk(hw, &eecd); - - mask >>= 1; - } while (mask); - - eecd &= ~E1000_EECD_DI; - ew32(EECD, eecd); -} - -/** - * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM - * @hw: pointer to the HW structure - * @count: number of bits to shift in - * - * In order to read a register from the EEPROM, we need to shift 'count' bits - * in from the EEPROM. Bits are "shifted in" by raising the clock input to - * the EEPROM (setting the SK bit), and then reading the value of the data out - * "DO" bit. During this "shifting in" process the data in "DI" bit should - * always be clear. - **/ -static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) -{ - u32 eecd; - u32 i; - u16 data; - - eecd = er32(EECD); - - eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); - data = 0; - - for (i = 0; i < count; i++) { - data <<= 1; - e1000_raise_eec_clk(hw, &eecd); - - eecd = er32(EECD); - - eecd &= ~E1000_EECD_DI; - if (eecd & E1000_EECD_DO) - data |= 1; - - e1000_lower_eec_clk(hw, &eecd); - } - - return data; -} - -/** - * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion - * @hw: pointer to the HW structure - * @ee_reg: EEPROM flag for polling - * - * Polls the EEPROM status bit for either read or write completion based - * upon the value of 'ee_reg'. - **/ -s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) -{ - u32 attempts = 100000; - u32 i, reg = 0; - - for (i = 0; i < attempts; i++) { - if (ee_reg == E1000_NVM_POLL_READ) - reg = er32(EERD); - else - reg = er32(EEWR); - - if (reg & E1000_NVM_RW_REG_DONE) - return 0; - - udelay(5); - } - - return -E1000_ERR_NVM; -} - -/** - * e1000e_acquire_nvm - Generic request for access to EEPROM - * @hw: pointer to the HW structure - * - * Set the EEPROM access request bit and wait for EEPROM access grant bit. - * Return successful if access grant bit set, else clear the request for - * EEPROM access and return -E1000_ERR_NVM (-1). - **/ -s32 e1000e_acquire_nvm(struct e1000_hw *hw) -{ - u32 eecd = er32(EECD); - s32 timeout = E1000_NVM_GRANT_ATTEMPTS; - - ew32(EECD, eecd | E1000_EECD_REQ); - eecd = er32(EECD); - - while (timeout) { - if (eecd & E1000_EECD_GNT) - break; - udelay(5); - eecd = er32(EECD); - timeout--; - } - - if (!timeout) { - eecd &= ~E1000_EECD_REQ; - ew32(EECD, eecd); - e_dbg("Could not acquire NVM grant\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000_standby_nvm - Return EEPROM to standby state - * @hw: pointer to the HW structure - * - * Return the EEPROM to a standby state. - **/ -static void e1000_standby_nvm(struct e1000_hw *hw) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - - if (nvm->type == e1000_nvm_eeprom_spi) { - /* Toggle CS to flush commands */ - eecd |= E1000_EECD_CS; - ew32(EECD, eecd); - e1e_flush(); - udelay(nvm->delay_usec); - eecd &= ~E1000_EECD_CS; - ew32(EECD, eecd); - e1e_flush(); - udelay(nvm->delay_usec); - } -} - -/** - * e1000_stop_nvm - Terminate EEPROM command - * @hw: pointer to the HW structure - * - * Terminates the current command by inverting the EEPROM's chip select pin. - **/ -static void e1000_stop_nvm(struct e1000_hw *hw) -{ - u32 eecd; - - eecd = er32(EECD); - if (hw->nvm.type == e1000_nvm_eeprom_spi) { - /* Pull CS high */ - eecd |= E1000_EECD_CS; - e1000_lower_eec_clk(hw, &eecd); - } -} - -/** - * e1000e_release_nvm - Release exclusive access to EEPROM - * @hw: pointer to the HW structure - * - * Stop any current commands to the EEPROM and clear the EEPROM request bit. - **/ -void e1000e_release_nvm(struct e1000_hw *hw) -{ - u32 eecd; - - e1000_stop_nvm(hw); - - eecd = er32(EECD); - eecd &= ~E1000_EECD_REQ; - ew32(EECD, eecd); -} - -/** - * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write - * @hw: pointer to the HW structure - * - * Setups the EEPROM for reading and writing. - **/ -static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 eecd = er32(EECD); - u8 spi_stat_reg; - - if (nvm->type == e1000_nvm_eeprom_spi) { - u16 timeout = NVM_MAX_RETRY_SPI; - - /* Clear SK and CS */ - eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); - ew32(EECD, eecd); - e1e_flush(); - udelay(1); - - /* - * Read "Status Register" repeatedly until the LSB is cleared. - * The EEPROM will signal that the command has been completed - * by clearing bit 0 of the internal status register. If it's - * not cleared within 'timeout', then error out. - */ - while (timeout) { - e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, - hw->nvm.opcode_bits); - spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); - if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) - break; - - udelay(5); - e1000_standby_nvm(hw); - timeout--; - } - - if (!timeout) { - e_dbg("SPI NVM Status error\n"); - return -E1000_ERR_NVM; - } - } - - return 0; -} - -/** - * e1000e_read_nvm_eerd - Reads EEPROM using EERD register - * @hw: pointer to the HW structure - * @offset: offset of word in the EEPROM to read - * @words: number of words to read - * @data: word read from the EEPROM - * - * Reads a 16 bit word from the EEPROM using the EERD register. - **/ -s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - u32 i, eerd = 0; - s32 ret_val = 0; - - /* - * A check for invalid values: offset too large, too many words, - * too many words for the offset, and not enough words. - */ - if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || - (words == 0)) { - e_dbg("nvm parameter(s) out of bounds\n"); - return -E1000_ERR_NVM; - } - - for (i = 0; i < words; i++) { - eerd = ((offset+i) << E1000_NVM_RW_ADDR_SHIFT) + - E1000_NVM_RW_REG_START; - - ew32(EERD, eerd); - ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); - if (ret_val) - break; - - data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA); - } - - return ret_val; -} - -/** - * e1000e_write_nvm_spi - Write to EEPROM using SPI - * @hw: pointer to the HW structure - * @offset: offset within the EEPROM to be written to - * @words: number of words to write - * @data: 16 bit word(s) to be written to the EEPROM - * - * Writes data to EEPROM at offset using SPI interface. - * - * If e1000e_update_nvm_checksum is not called after this function , the - * EEPROM will most likely contain an invalid checksum. - **/ -s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) -{ - struct e1000_nvm_info *nvm = &hw->nvm; - s32 ret_val; - u16 widx = 0; - - /* - * A check for invalid values: offset too large, too many words, - * and not enough words. - */ - if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || - (words == 0)) { - e_dbg("nvm parameter(s) out of bounds\n"); - return -E1000_ERR_NVM; - } - - ret_val = nvm->ops.acquire(hw); - if (ret_val) - return ret_val; - - while (widx < words) { - u8 write_opcode = NVM_WRITE_OPCODE_SPI; - - ret_val = e1000_ready_nvm_eeprom(hw); - if (ret_val) { - nvm->ops.release(hw); - return ret_val; - } - - e1000_standby_nvm(hw); - - /* Send the WRITE ENABLE command (8 bit opcode) */ - e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, - nvm->opcode_bits); - - e1000_standby_nvm(hw); - - /* - * Some SPI eeproms use the 8th address bit embedded in the - * opcode - */ - if ((nvm->address_bits == 8) && (offset >= 128)) - write_opcode |= NVM_A8_OPCODE_SPI; - - /* Send the Write command (8-bit opcode + addr) */ - e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); - e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), - nvm->address_bits); - - /* Loop to allow for up to whole page write of eeprom */ - while (widx < words) { - u16 word_out = data[widx]; - word_out = (word_out >> 8) | (word_out << 8); - e1000_shift_out_eec_bits(hw, word_out, 16); - widx++; - - if ((((offset + widx) * 2) % nvm->page_size) == 0) { - e1000_standby_nvm(hw); - break; - } - } - } - - usleep_range(10000, 20000); - nvm->ops.release(hw); - return 0; -} - -/** - * e1000_read_pba_string_generic - Read device part number - * @hw: pointer to the HW structure - * @pba_num: pointer to device part number - * @pba_num_size: size of part number buffer - * - * Reads the product board assembly (PBA) number from the EEPROM and stores - * the value in pba_num. - **/ -s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, - u32 pba_num_size) -{ - s32 ret_val; - u16 nvm_data; - u16 pba_ptr; - u16 offset; - u16 length; - - if (pba_num == NULL) { - e_dbg("PBA string buffer was null\n"); - ret_val = E1000_ERR_INVALID_ARGUMENT; - goto out; - } - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - /* - * if nvm_data is not ptr guard the PBA must be in legacy format which - * means pba_ptr is actually our second data word for the PBA number - * and we can decode it into an ascii string - */ - if (nvm_data != NVM_PBA_PTR_GUARD) { - e_dbg("NVM PBA number is not stored as string\n"); - - /* we will need 11 characters to store the PBA */ - if (pba_num_size < 11) { - e_dbg("PBA string buffer too small\n"); - return E1000_ERR_NO_SPACE; - } - - /* extract hex string from data and pba_ptr */ - pba_num[0] = (nvm_data >> 12) & 0xF; - pba_num[1] = (nvm_data >> 8) & 0xF; - pba_num[2] = (nvm_data >> 4) & 0xF; - pba_num[3] = nvm_data & 0xF; - pba_num[4] = (pba_ptr >> 12) & 0xF; - pba_num[5] = (pba_ptr >> 8) & 0xF; - pba_num[6] = '-'; - pba_num[7] = 0; - pba_num[8] = (pba_ptr >> 4) & 0xF; - pba_num[9] = pba_ptr & 0xF; - - /* put a null character on the end of our string */ - pba_num[10] = '\0'; - - /* switch all the data but the '-' to hex char */ - for (offset = 0; offset < 10; offset++) { - if (pba_num[offset] < 0xA) - pba_num[offset] += '0'; - else if (pba_num[offset] < 0x10) - pba_num[offset] += 'A' - 0xA; - } - - goto out; - } - - ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - - if (length == 0xFFFF || length == 0) { - e_dbg("NVM PBA number section invalid length\n"); - ret_val = E1000_ERR_NVM_PBA_SECTION; - goto out; - } - /* check if pba_num buffer is big enough */ - if (pba_num_size < (((u32)length * 2) - 1)) { - e_dbg("PBA string buffer too small\n"); - ret_val = E1000_ERR_NO_SPACE; - goto out; - } - - /* trim pba length from start of string */ - pba_ptr++; - length--; - - for (offset = 0; offset < length; offset++) { - ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - goto out; - } - pba_num[offset * 2] = (u8)(nvm_data >> 8); - pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); - } - pba_num[offset * 2] = '\0'; - -out: - return ret_val; -} - -/** - * e1000_read_mac_addr_generic - Read device MAC address - * @hw: pointer to the HW structure - * - * Reads the device MAC address from the EEPROM and stores the value. - * Since devices with two ports use the same EEPROM, we increment the - * last bit in the MAC address for the second port. - **/ -s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) -{ - u32 rar_high; - u32 rar_low; - u16 i; - - rar_high = er32(RAH(0)); - rar_low = er32(RAL(0)); - - for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) - hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8)); - - for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) - hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8)); - - for (i = 0; i < ETH_ALEN; i++) - hw->mac.addr[i] = hw->mac.perm_addr[i]; - - return 0; -} - -/** - * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum - * @hw: pointer to the HW structure - * - * Calculates the EEPROM checksum by reading/adding each word of the EEPROM - * and then verifies that the sum of the EEPROM is equal to 0xBABA. - **/ -s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 checksum = 0; - u16 i, nvm_data; - - for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error\n"); - return ret_val; - } - checksum += nvm_data; - } - - if (checksum != (u16) NVM_SUM) { - e_dbg("NVM Checksum Invalid\n"); - return -E1000_ERR_NVM; - } - - return 0; -} - -/** - * e1000e_update_nvm_checksum_generic - Update EEPROM checksum - * @hw: pointer to the HW structure - * - * Updates the EEPROM checksum by reading/adding each word of the EEPROM - * up to the checksum. Then calculates the EEPROM checksum and writes the - * value to the EEPROM. - **/ -s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw) -{ - s32 ret_val; - u16 checksum = 0; - u16 i, nvm_data; - - for (i = 0; i < NVM_CHECKSUM_REG; i++) { - ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); - if (ret_val) { - e_dbg("NVM Read Error while updating checksum.\n"); - return ret_val; - } - checksum += nvm_data; - } - checksum = (u16) NVM_SUM - checksum; - ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); - if (ret_val) - e_dbg("NVM Write Error while updating checksum.\n"); - - return ret_val; -} - -/** - * e1000e_reload_nvm - Reloads EEPROM - * @hw: pointer to the HW structure - * - * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the - * extended control register. - **/ -void e1000e_reload_nvm(struct e1000_hw *hw) -{ - u32 ctrl_ext; - - udelay(10); - ctrl_ext = er32(CTRL_EXT); - ctrl_ext |= E1000_CTRL_EXT_EE_RST; - ew32(CTRL_EXT, ctrl_ext); - e1e_flush(); -} - -/** - * e1000_calculate_checksum - Calculate checksum for buffer - * @buffer: pointer to EEPROM - * @length: size of EEPROM to calculate a checksum for - * - * Calculates the checksum for some buffer on a specified length. The - * checksum calculated is returned. - **/ -static u8 e1000_calculate_checksum(u8 *buffer, u32 length) -{ - u32 i; - u8 sum = 0; - - if (!buffer) - return 0; - - for (i = 0; i < length; i++) - sum += buffer[i]; - - return (u8) (0 - sum); -} - -/** - * e1000_mng_enable_host_if - Checks host interface is enabled - * @hw: pointer to the HW structure - * - * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND - * - * This function checks whether the HOST IF is enabled for command operation - * and also checks whether the previous command is completed. It busy waits - * in case of previous command is not completed. - **/ -static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) -{ - u32 hicr; - u8 i; - - if (!(hw->mac.arc_subsystem_valid)) { - e_dbg("ARC subsystem not valid.\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - - /* Check that the host interface is enabled. */ - hicr = er32(HICR); - if ((hicr & E1000_HICR_EN) == 0) { - e_dbg("E1000_HOST_EN bit disabled.\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - /* check the previous command is completed */ - for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { - hicr = er32(HICR); - if (!(hicr & E1000_HICR_C)) - break; - mdelay(1); - } - - if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { - e_dbg("Previous command timeout failed .\n"); - return -E1000_ERR_HOST_INTERFACE_COMMAND; - } - - return 0; -} - -/** - * e1000e_check_mng_mode_generic - check management mode - * @hw: pointer to the HW structure - * - * Reads the firmware semaphore register and returns true (>0) if - * manageability is enabled, else false (0). - **/ -bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) -{ - u32 fwsm = er32(FWSM); - - return (fwsm & E1000_FWSM_MODE_MASK) == - (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); -} - -/** - * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx - * @hw: pointer to the HW structure - * - * Enables packet filtering on transmit packets if manageability is enabled - * and host interface is enabled. - **/ -bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) -{ - struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; - u32 *buffer = (u32 *)&hw->mng_cookie; - u32 offset; - s32 ret_val, hdr_csum, csum; - u8 i, len; - - hw->mac.tx_pkt_filtering = true; - - /* No manageability, no filtering */ - if (!e1000e_check_mng_mode(hw)) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - - /* - * If we can't read from the host interface for whatever - * reason, disable filtering. - */ - ret_val = e1000_mng_enable_host_if(hw); - if (ret_val) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - - /* Read in the header. Length and offset are in dwords. */ - len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; - offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; - for (i = 0; i < len; i++) - *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset + i); - hdr_csum = hdr->checksum; - hdr->checksum = 0; - csum = e1000_calculate_checksum((u8 *)hdr, - E1000_MNG_DHCP_COOKIE_LENGTH); - /* - * If either the checksums or signature don't match, then - * the cookie area isn't considered valid, in which case we - * take the safe route of assuming Tx filtering is enabled. - */ - if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { - hw->mac.tx_pkt_filtering = true; - goto out; - } - - /* Cookie area is valid, make the final check for filtering. */ - if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { - hw->mac.tx_pkt_filtering = false; - goto out; - } - -out: - return hw->mac.tx_pkt_filtering; -} - -/** - * e1000_mng_write_cmd_header - Writes manageability command header - * @hw: pointer to the HW structure - * @hdr: pointer to the host interface command header - * - * Writes the command header after does the checksum calculation. - **/ -static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, - struct e1000_host_mng_command_header *hdr) -{ - u16 i, length = sizeof(struct e1000_host_mng_command_header); - - /* Write the whole command header structure with new checksum. */ - - hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); - - length >>= 2; - /* Write the relevant command block into the ram area. */ - for (i = 0; i < length; i++) { - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, - *((u32 *) hdr + i)); - e1e_flush(); - } - - return 0; -} - -/** - * e1000_mng_host_if_write - Write to the manageability host interface - * @hw: pointer to the HW structure - * @buffer: pointer to the host interface buffer - * @length: size of the buffer - * @offset: location in the buffer to write to - * @sum: sum of the data (not checksum) - * - * This function writes the buffer content at the offset given on the host if. - * It also does alignment considerations to do the writes in most efficient - * way. Also fills up the sum of the buffer in *buffer parameter. - **/ -static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, - u16 length, u16 offset, u8 *sum) -{ - u8 *tmp; - u8 *bufptr = buffer; - u32 data = 0; - u16 remaining, i, j, prev_bytes; - - /* sum = only sum of the data and it is not checksum */ - - if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) - return -E1000_ERR_PARAM; - - tmp = (u8 *)&data; - prev_bytes = offset & 0x3; - offset >>= 2; - - if (prev_bytes) { - data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); - for (j = prev_bytes; j < sizeof(u32); j++) { - *(tmp + j) = *bufptr++; - *sum += *(tmp + j); - } - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); - length -= j - prev_bytes; - offset++; - } - - remaining = length & 0x3; - length -= remaining; - - /* Calculate length in DWORDs */ - length >>= 2; - - /* - * The device driver writes the relevant command block into the - * ram area. - */ - for (i = 0; i < length; i++) { - for (j = 0; j < sizeof(u32); j++) { - *(tmp + j) = *bufptr++; - *sum += *(tmp + j); - } - - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); - } - if (remaining) { - for (j = 0; j < sizeof(u32); j++) { - if (j < remaining) - *(tmp + j) = *bufptr++; - else - *(tmp + j) = 0; - - *sum += *(tmp + j); - } - E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); - } - - return 0; -} - -/** - * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface - * @hw: pointer to the HW structure - * @buffer: pointer to the host interface - * @length: size of the buffer - * - * Writes the DHCP information to the host interface. - **/ -s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) -{ - struct e1000_host_mng_command_header hdr; - s32 ret_val; - u32 hicr; - - hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; - hdr.command_length = length; - hdr.reserved1 = 0; - hdr.reserved2 = 0; - hdr.checksum = 0; - - /* Enable the host interface */ - ret_val = e1000_mng_enable_host_if(hw); - if (ret_val) - return ret_val; - - /* Populate the host interface with the contents of "buffer". */ - ret_val = e1000_mng_host_if_write(hw, buffer, length, - sizeof(hdr), &(hdr.checksum)); - if (ret_val) - return ret_val; - - /* Write the manageability command header */ - ret_val = e1000_mng_write_cmd_header(hw, &hdr); - if (ret_val) - return ret_val; - - /* Tell the ARC a new command is pending. */ - hicr = er32(HICR); - ew32(HICR, hicr | E1000_HICR_C); - - return 0; -} - -/** - * e1000e_enable_mng_pass_thru - Check if management passthrough is needed - * @hw: pointer to the HW structure - * - * Verifies the hardware needs to leave interface enabled so that frames can - * be directed to and from the management interface. - **/ -bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) -{ - u32 manc; - u32 fwsm, factps; - bool ret_val = false; - - manc = er32(MANC); - - if (!(manc & E1000_MANC_RCV_TCO_EN)) - goto out; - - if (hw->mac.has_fwsm) { - fwsm = er32(FWSM); - factps = er32(FACTPS); - - if (!(factps & E1000_FACTPS_MNGCG) && - ((fwsm & E1000_FWSM_MODE_MASK) == - (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { - ret_val = true; - goto out; - } - } else if ((hw->mac.type == e1000_82574) || - (hw->mac.type == e1000_82583)) { - u16 data; - - factps = er32(FACTPS); - e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); - - if (!(factps & E1000_FACTPS_MNGCG) && - ((data & E1000_NVM_INIT_CTRL2_MNGM) == - (e1000_mng_mode_pt << 13))) { - ret_val = true; - goto out; - } - } else if ((manc & E1000_MANC_SMBUS_EN) && - !(manc & E1000_MANC_ASF_EN)) { - ret_val = true; - goto out; - } - -out: - return ret_val; -} diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c new file mode 100644 index 00000000000..64b6f439338 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -0,0 +1,1717 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +/** + * e1000e_get_bus_info_pcie - Get PCIe bus information + * @hw: pointer to the HW structure + * + * Determines and stores the system bus information for a particular + * network interface. The following bus information is determined and stored: + * bus speed, bus width, type (PCIe), and PCIe function. + **/ +s32 e1000e_get_bus_info_pcie(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + struct e1000_bus_info *bus = &hw->bus; + struct e1000_adapter *adapter = hw->adapter; + u16 pcie_link_status, cap_offset; + + cap_offset = adapter->pdev->pcie_cap; + if (!cap_offset) { + bus->width = e1000_bus_width_unknown; + } else { + pci_read_config_word(adapter->pdev, + cap_offset + PCIE_LINK_STATUS, + &pcie_link_status); + bus->width = (enum e1000_bus_width)((pcie_link_status & + PCIE_LINK_WIDTH_MASK) >> + PCIE_LINK_WIDTH_SHIFT); + } + + mac->ops.set_lan_id(hw); + + return 0; +} + +/** + * e1000_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices + * + * @hw: pointer to the HW structure + * + * Determines the LAN function id by reading memory-mapped registers + * and swaps the port value if requested. + **/ +void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + u32 reg; + + /* + * The status register reports the correct function number + * for the device regardless of function swap state. + */ + reg = er32(STATUS); + bus->func = (reg & E1000_STATUS_FUNC_MASK) >> E1000_STATUS_FUNC_SHIFT; +} + +/** + * e1000_set_lan_id_single_port - Set LAN id for a single port device + * @hw: pointer to the HW structure + * + * Sets the LAN function id to zero for a single port device. + **/ +void e1000_set_lan_id_single_port(struct e1000_hw *hw) +{ + struct e1000_bus_info *bus = &hw->bus; + + bus->func = 0; +} + +/** + * e1000_clear_vfta_generic - Clear VLAN filter table + * @hw: pointer to the HW structure + * + * Clears the register array which contains the VLAN filter table by + * setting all the values to 0. + **/ +void e1000_clear_vfta_generic(struct e1000_hw *hw) +{ + u32 offset; + + for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) { + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, 0); + e1e_flush(); + } +} + +/** + * e1000_write_vfta_generic - Write value to VLAN filter table + * @hw: pointer to the HW structure + * @offset: register offset in VLAN filter table + * @value: register value written to VLAN filter table + * + * Writes value at the given offset in the register array which stores + * the VLAN filter table. + **/ +void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value) +{ + E1000_WRITE_REG_ARRAY(hw, E1000_VFTA, offset, value); + e1e_flush(); +} + +/** + * e1000e_init_rx_addrs - Initialize receive address's + * @hw: pointer to the HW structure + * @rar_count: receive address registers + * + * Setup the receive address registers by setting the base receive address + * register to the devices MAC address and clearing all the other receive + * address registers to 0. + **/ +void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count) +{ + u32 i; + u8 mac_addr[ETH_ALEN] = { 0 }; + + /* Setup the receive address */ + e_dbg("Programming MAC Address into RAR[0]\n"); + + e1000e_rar_set(hw, hw->mac.addr, 0); + + /* Zero out the other (rar_entry_count - 1) receive addresses */ + e_dbg("Clearing RAR[1-%u]\n", rar_count - 1); + for (i = 1; i < rar_count; i++) + e1000e_rar_set(hw, mac_addr, i); +} + +/** + * e1000_check_alt_mac_addr_generic - Check for alternate MAC addr + * @hw: pointer to the HW structure + * + * Checks the nvm for an alternate MAC address. An alternate MAC address + * can be setup by pre-boot software and must be treated like a permanent + * address and must override the actual permanent MAC address. If an + * alternate MAC address is found it is programmed into RAR0, replacing + * the permanent address that was installed into RAR0 by the Si on reset. + * This function will return SUCCESS unless it encounters an error while + * reading the EEPROM. + **/ +s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw) +{ + u32 i; + s32 ret_val = 0; + u16 offset, nvm_alt_mac_addr_offset, nvm_data; + u8 alt_mac_addr[ETH_ALEN]; + + ret_val = e1000_read_nvm(hw, NVM_COMPAT, 1, &nvm_data); + if (ret_val) + goto out; + + /* not supported on older hardware or 82573 */ + if ((hw->mac.type < e1000_82571) || (hw->mac.type == e1000_82573)) + goto out; + + ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1, + &nvm_alt_mac_addr_offset); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if ((nvm_alt_mac_addr_offset == 0xFFFF) || + (nvm_alt_mac_addr_offset == 0x0000)) + /* There is no Alternate MAC Address */ + goto out; + + if (hw->bus.func == E1000_FUNC_1) + nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1; + for (i = 0; i < ETH_ALEN; i += 2) { + offset = nvm_alt_mac_addr_offset + (i >> 1); + ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + alt_mac_addr[i] = (u8)(nvm_data & 0xFF); + alt_mac_addr[i + 1] = (u8)(nvm_data >> 8); + } + + /* if multicast bit is set, the alternate address will not be used */ + if (is_multicast_ether_addr(alt_mac_addr)) { + e_dbg("Ignoring Alternate Mac Address with MC bit set\n"); + goto out; + } + + /* + * We have a valid alternate MAC address, and we want to treat it the + * same as the normal permanent MAC address stored by the HW into the + * RAR. Do this by mapping this address into RAR0. + */ + e1000e_rar_set(hw, alt_mac_addr, 0); + +out: + return ret_val; +} + +/** + * e1000e_rar_set - Set receive address register + * @hw: pointer to the HW structure + * @addr: pointer to the receive address + * @index: receive address array register + * + * Sets the receive address array register at index to the address passed + * in by addr. + **/ +void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index) +{ + u32 rar_low, rar_high; + + /* + * HW expects these in little endian so we reverse the byte order + * from network order (big endian) to little endian + */ + rar_low = ((u32)addr[0] | ((u32)addr[1] << 8) | + ((u32)addr[2] << 16) | ((u32)addr[3] << 24)); + + rar_high = ((u32)addr[4] | ((u32)addr[5] << 8)); + + /* If MAC address zero, no need to set the AV bit */ + if (rar_low || rar_high) + rar_high |= E1000_RAH_AV; + + /* + * Some bridges will combine consecutive 32-bit writes into + * a single burst write, which will malfunction on some parts. + * The flushes avoid this. + */ + ew32(RAL(index), rar_low); + e1e_flush(); + ew32(RAH(index), rar_high); + e1e_flush(); +} + +/** + * e1000_hash_mc_addr - Generate a multicast hash value + * @hw: pointer to the HW structure + * @mc_addr: pointer to a multicast address + * + * Generates a multicast address hash value which is used to determine + * the multicast filter table array address and new table value. See + * e1000_mta_set_generic() + **/ +static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr) +{ + u32 hash_value, hash_mask; + u8 bit_shift = 0; + + /* Register count multiplied by bits per register */ + hash_mask = (hw->mac.mta_reg_count * 32) - 1; + + /* + * For a mc_filter_type of 0, bit_shift is the number of left-shifts + * where 0xFF would still fall within the hash mask. + */ + while (hash_mask >> bit_shift != 0xFF) + bit_shift++; + + /* + * The portion of the address that is used for the hash table + * is determined by the mc_filter_type setting. + * The algorithm is such that there is a total of 8 bits of shifting. + * The bit_shift for a mc_filter_type of 0 represents the number of + * left-shifts where the MSB of mc_addr[5] would still fall within + * the hash_mask. Case 0 does this exactly. Since there are a total + * of 8 bits of shifting, then mc_addr[4] will shift right the + * remaining number of bits. Thus 8 - bit_shift. The rest of the + * cases are a variation of this algorithm...essentially raising the + * number of bits to shift mc_addr[5] left, while still keeping the + * 8-bit shifting total. + * + * For example, given the following Destination MAC Address and an + * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask), + * we can see that the bit_shift for case 0 is 4. These are the hash + * values resulting from each mc_filter_type... + * [0] [1] [2] [3] [4] [5] + * 01 AA 00 12 34 56 + * LSB MSB + * + * case 0: hash_value = ((0x34 >> 4) | (0x56 << 4)) & 0xFFF = 0x563 + * case 1: hash_value = ((0x34 >> 3) | (0x56 << 5)) & 0xFFF = 0xAC6 + * case 2: hash_value = ((0x34 >> 2) | (0x56 << 6)) & 0xFFF = 0x163 + * case 3: hash_value = ((0x34 >> 0) | (0x56 << 8)) & 0xFFF = 0x634 + */ + switch (hw->mac.mc_filter_type) { + default: + case 0: + break; + case 1: + bit_shift += 1; + break; + case 2: + bit_shift += 2; + break; + case 3: + bit_shift += 4; + break; + } + + hash_value = hash_mask & (((mc_addr[4] >> (8 - bit_shift)) | + (((u16)mc_addr[5]) << bit_shift))); + + return hash_value; +} + +/** + * e1000e_update_mc_addr_list_generic - Update Multicast addresses + * @hw: pointer to the HW structure + * @mc_addr_list: array of multicast addresses to program + * @mc_addr_count: number of multicast addresses to program + * + * Updates entire Multicast Table Array. + * The caller must have a packed mc_addr_list of multicast addresses. + **/ +void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw, + u8 *mc_addr_list, u32 mc_addr_count) +{ + u32 hash_value, hash_bit, hash_reg; + int i; + + /* clear mta_shadow */ + memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow)); + + /* update mta_shadow from mc_addr_list */ + for (i = 0; (u32)i < mc_addr_count; i++) { + hash_value = e1000_hash_mc_addr(hw, mc_addr_list); + + hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1); + hash_bit = hash_value & 0x1F; + + hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit); + mc_addr_list += (ETH_ALEN); + } + + /* replace the entire MTA table */ + for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) + E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]); + e1e_flush(); +} + +/** + * e1000e_clear_hw_cntrs_base - Clear base hardware counters + * @hw: pointer to the HW structure + * + * Clears the base hardware counters by reading the counter registers. + **/ +void e1000e_clear_hw_cntrs_base(struct e1000_hw *hw) +{ + er32(CRCERRS); + er32(SYMERRS); + er32(MPC); + er32(SCC); + er32(ECOL); + er32(MCC); + er32(LATECOL); + er32(COLC); + er32(DC); + er32(SEC); + er32(RLEC); + er32(XONRXC); + er32(XONTXC); + er32(XOFFRXC); + er32(XOFFTXC); + er32(FCRUC); + er32(GPRC); + er32(BPRC); + er32(MPRC); + er32(GPTC); + er32(GORCL); + er32(GORCH); + er32(GOTCL); + er32(GOTCH); + er32(RNBC); + er32(RUC); + er32(RFC); + er32(ROC); + er32(RJC); + er32(TORL); + er32(TORH); + er32(TOTL); + er32(TOTH); + er32(TPR); + er32(TPT); + er32(MPTC); + er32(BPTC); +} + +/** + * e1000e_check_for_copper_link - Check for link (Copper) + * @hw: pointer to the HW structure + * + * Checks to see of the link status of the hardware has changed. If a + * change in link status has been detected, then we read the PHY registers + * to get the current speed/duplex if link exists. + **/ +s32 e1000e_check_for_copper_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + bool link; + + /* + * We only want to go out to the PHY registers to see if Auto-Neg + * has completed and/or if our link status has changed. The + * get_link_status flag is set upon receiving a Link Status + * Change or Rx Sequence Error interrupt. + */ + if (!mac->get_link_status) + return 0; + + /* + * First we want to see if the MII Status Register reports + * link. If so, then we want to get the current speed/duplex + * of the PHY. + */ + ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link); + if (ret_val) + return ret_val; + + if (!link) + return ret_val; /* No link detected */ + + mac->get_link_status = false; + + /* + * Check if there was DownShift, must be checked + * immediately after link-up + */ + e1000e_check_downshift(hw); + + /* + * If we are forcing speed/duplex, then we simply return since + * we have already determined whether we have link or not. + */ + if (!mac->autoneg) { + ret_val = -E1000_ERR_CONFIG; + return ret_val; + } + + /* + * Auto-Neg is enabled. Auto Speed Detection takes care + * of MAC speed/duplex configuration. So we only need to + * configure Collision Distance in the MAC. + */ + e1000e_config_collision_dist(hw); + + /* + * Configure Flow Control now that Auto-Neg has completed. + * First, we need to restore the desired flow control + * settings because we may have had to re-autoneg with a + * different link partner. + */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) + e_dbg("Error configuring flow control\n"); + + return ret_val; +} + +/** + * e1000e_check_for_fiber_link - Check for link (Fiber) + * @hw: pointer to the HW structure + * + * Checks for link up on the hardware. If link is not up and we have + * a signal, then we need to force link up. + **/ +s32 e1000e_check_for_fiber_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 rxcw; + u32 ctrl; + u32 status; + s32 ret_val; + + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); + + /* + * If we don't have link (auto-negotiation failed or link partner + * cannot auto-negotiate), the cable is plugged in (we have signal), + * and our link partner is not trying to auto-negotiate with us (we + * are receiving idles or data), we need to force link up. We also + * need to give auto-negotiation time to complete, in case the cable + * was just plugged in. The autoneg_failed flag does this. + */ + /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ + if ((ctrl & E1000_CTRL_SWDPIN1) && (!(status & E1000_STATUS_LU)) && + (!(rxcw & E1000_RXCW_C))) { + if (mac->autoneg_failed == 0) { + mac->autoneg_failed = 1; + return 0; + } + e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); + + /* Disable auto-negotiation in the TXCW register */ + ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); + + /* Force link-up and also force full-duplex. */ + ctrl = er32(CTRL); + ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); + ew32(CTRL, ctrl); + + /* Configure Flow Control after forcing link up. */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) { + e_dbg("Error configuring flow control\n"); + return ret_val; + } + } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { + /* + * If we are forcing link and we are receiving /C/ ordered + * sets, re-enable auto-negotiation in the TXCW register + * and disable forced link in the Device Control register + * in an attempt to auto-negotiate with our link partner. + */ + e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); + ew32(TXCW, mac->txcw); + ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); + + mac->serdes_has_link = true; + } + + return 0; +} + +/** + * e1000e_check_for_serdes_link - Check for link (Serdes) + * @hw: pointer to the HW structure + * + * Checks for link up on the hardware. If link is not up and we have + * a signal, then we need to force link up. + **/ +s32 e1000e_check_for_serdes_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 rxcw; + u32 ctrl; + u32 status; + s32 ret_val; + + ctrl = er32(CTRL); + status = er32(STATUS); + rxcw = er32(RXCW); + + /* + * If we don't have link (auto-negotiation failed or link partner + * cannot auto-negotiate), and our link partner is not trying to + * auto-negotiate with us (we are receiving idles or data), + * we need to force link up. We also need to give auto-negotiation + * time to complete. + */ + /* (ctrl & E1000_CTRL_SWDPIN1) == 1 == have signal */ + if ((!(status & E1000_STATUS_LU)) && (!(rxcw & E1000_RXCW_C))) { + if (mac->autoneg_failed == 0) { + mac->autoneg_failed = 1; + return 0; + } + e_dbg("NOT Rx'ing /C/, disable AutoNeg and force link.\n"); + + /* Disable auto-negotiation in the TXCW register */ + ew32(TXCW, (mac->txcw & ~E1000_TXCW_ANE)); + + /* Force link-up and also force full-duplex. */ + ctrl = er32(CTRL); + ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FD); + ew32(CTRL, ctrl); + + /* Configure Flow Control after forcing link up. */ + ret_val = e1000e_config_fc_after_link_up(hw); + if (ret_val) { + e_dbg("Error configuring flow control\n"); + return ret_val; + } + } else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) { + /* + * If we are forcing link and we are receiving /C/ ordered + * sets, re-enable auto-negotiation in the TXCW register + * and disable forced link in the Device Control register + * in an attempt to auto-negotiate with our link partner. + */ + e_dbg("Rx'ing /C/, enable AutoNeg and stop forcing link.\n"); + ew32(TXCW, mac->txcw); + ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); + + mac->serdes_has_link = true; + } else if (!(E1000_TXCW_ANE & er32(TXCW))) { + /* + * If we force link for non-auto-negotiation switch, check + * link status based on MAC synchronization for internal + * serdes media type. + */ + /* SYNCH bit and IV bit are sticky. */ + udelay(10); + rxcw = er32(RXCW); + if (rxcw & E1000_RXCW_SYNCH) { + if (!(rxcw & E1000_RXCW_IV)) { + mac->serdes_has_link = true; + e_dbg("SERDES: Link up - forced.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - force failed.\n"); + } + } + + if (E1000_TXCW_ANE & er32(TXCW)) { + status = er32(STATUS); + if (status & E1000_STATUS_LU) { + /* SYNCH bit and IV bit are sticky, so reread rxcw. */ + udelay(10); + rxcw = er32(RXCW); + if (rxcw & E1000_RXCW_SYNCH) { + if (!(rxcw & E1000_RXCW_IV)) { + mac->serdes_has_link = true; + e_dbg("SERDES: Link up - autoneg completed successfully.\n"); + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - invalid codewords detected in autoneg.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - no sync.\n"); + } + } else { + mac->serdes_has_link = false; + e_dbg("SERDES: Link down - autoneg failed\n"); + } + } + + return 0; +} + +/** + * e1000_set_default_fc_generic - Set flow control default values + * @hw: pointer to the HW structure + * + * Read the EEPROM for the default values for flow control and store the + * values. + **/ +static s32 e1000_set_default_fc_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 nvm_data; + + /* + * Read and store word 0x0F of the EEPROM. This word contains bits + * that determine the hardware's default PAUSE (flow control) mode, + * a bit that determines whether the HW defaults to enabling or + * disabling auto-negotiation, and the direction of the + * SW defined pins. If there is no SW over-ride of the flow + * control setting, then the variable hw->fc will + * be initialized based on a value in the EEPROM. + */ + ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &nvm_data); + + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + + if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0) + hw->fc.requested_mode = e1000_fc_none; + else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == NVM_WORD0F_ASM_DIR) + hw->fc.requested_mode = e1000_fc_tx_pause; + else + hw->fc.requested_mode = e1000_fc_full; + + return 0; +} + +/** + * e1000e_setup_link - Setup flow control and link settings + * @hw: pointer to the HW structure + * + * Determines which flow control settings to use, then configures flow + * control. Calls the appropriate media-specific link configuration + * function. Assuming the adapter has a valid link partner, a valid link + * should be established. Assumes the hardware has previously been reset + * and the transmitter and receiver are not enabled. + **/ +s32 e1000e_setup_link(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + + /* + * In the case of the phy reset being blocked, we already have a link. + * We do not need to set it up again. + */ + if (e1000_check_reset_block(hw)) + return 0; + + /* + * If requested flow control is set to default, set flow control + * based on the EEPROM flow control settings. + */ + if (hw->fc.requested_mode == e1000_fc_default) { + ret_val = e1000_set_default_fc_generic(hw); + if (ret_val) + return ret_val; + } + + /* + * Save off the requested flow control mode for use later. Depending + * on the link partner's capabilities, we may or may not use this mode. + */ + hw->fc.current_mode = hw->fc.requested_mode; + + e_dbg("After fix-ups FlowControl is now = %x\n", hw->fc.current_mode); + + /* Call the necessary media_type subroutine to configure the link. */ + ret_val = mac->ops.setup_physical_interface(hw); + if (ret_val) + return ret_val; + + /* + * Initialize the flow control address, type, and PAUSE timer + * registers to their default values. This is done even if flow + * control is disabled, because it does not hurt anything to + * initialize these registers. + */ + e_dbg("Initializing the Flow Control address, type and timer regs\n"); + ew32(FCT, FLOW_CONTROL_TYPE); + ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH); + ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW); + + ew32(FCTTV, hw->fc.pause_time); + + return e1000e_set_fc_watermarks(hw); +} + +/** + * e1000_commit_fc_settings_generic - Configure flow control + * @hw: pointer to the HW structure + * + * Write the flow control settings to the Transmit Config Word Register (TXCW) + * base on the flow control settings in e1000_mac_info. + **/ +static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 txcw; + + /* + * Check for a software override of the flow control settings, and + * setup the device accordingly. If auto-negotiation is enabled, then + * software will have to set the "PAUSE" bits to the correct value in + * the Transmit Config Word Register (TXCW) and re-start auto- + * negotiation. However, if auto-negotiation is disabled, then + * software will have to manually configure the two flow control enable + * bits in the CTRL register. + * + * The possible values of the "fc" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause frames, + * but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames but we + * do not support receiving pause frames). + * 3: Both Rx and Tx flow control (symmetric) are enabled. + */ + switch (hw->fc.current_mode) { + case e1000_fc_none: + /* Flow control completely disabled by a software over-ride. */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD); + break; + case e1000_fc_rx_pause: + /* + * Rx Flow control is enabled and Tx Flow control is disabled + * by a software over-ride. Since there really isn't a way to + * advertise that we are capable of Rx Pause ONLY, we will + * advertise that we support both symmetric and asymmetric Rx + * PAUSE. Later, we will disable the adapter's ability to send + * PAUSE frames. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + case e1000_fc_tx_pause: + /* + * Tx Flow control is enabled, and Rx Flow control is disabled, + * by a software over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR); + break; + case e1000_fc_full: + /* + * Flow control (both Rx and Tx) is enabled by a software + * over-ride. + */ + txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK); + break; + default: + e_dbg("Flow control param set incorrectly\n"); + return -E1000_ERR_CONFIG; + break; + } + + ew32(TXCW, txcw); + mac->txcw = txcw; + + return 0; +} + +/** + * e1000_poll_fiber_serdes_link_generic - Poll for link up + * @hw: pointer to the HW structure + * + * Polls for link up by reading the status register, if link fails to come + * up with auto-negotiation, then the link is forced if a signal is detected. + **/ +static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + u32 i, status; + s32 ret_val; + + /* + * If we have a signal (the cable is plugged in, or assumed true for + * serdes media) then poll for a "Link-Up" indication in the Device + * Status Register. Time-out if a link isn't seen in 500 milliseconds + * seconds (Auto-negotiation should complete in less than 500 + * milliseconds even if the other end is doing it in SW). + */ + for (i = 0; i < FIBER_LINK_UP_LIMIT; i++) { + usleep_range(10000, 20000); + status = er32(STATUS); + if (status & E1000_STATUS_LU) + break; + } + if (i == FIBER_LINK_UP_LIMIT) { + e_dbg("Never got a valid link from auto-neg!!!\n"); + mac->autoneg_failed = 1; + /* + * AutoNeg failed to achieve a link, so we'll call + * mac->check_for_link. This routine will force the + * link up if we detect a signal. This will allow us to + * communicate with non-autonegotiating link partners. + */ + ret_val = mac->ops.check_for_link(hw); + if (ret_val) { + e_dbg("Error while checking for link\n"); + return ret_val; + } + mac->autoneg_failed = 0; + } else { + mac->autoneg_failed = 0; + e_dbg("Valid Link Found\n"); + } + + return 0; +} + +/** + * e1000e_setup_fiber_serdes_link - Setup link for fiber/serdes + * @hw: pointer to the HW structure + * + * Configures collision distance and flow control for fiber and serdes + * links. Upon successful setup, poll for link. + **/ +s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw) +{ + u32 ctrl; + s32 ret_val; + + ctrl = er32(CTRL); + + /* Take the link out of reset */ + ctrl &= ~E1000_CTRL_LRST; + + e1000e_config_collision_dist(hw); + + ret_val = e1000_commit_fc_settings_generic(hw); + if (ret_val) + return ret_val; + + /* + * Since auto-negotiation is enabled, take the link out of reset (the + * link will be in reset, because we previously reset the chip). This + * will restart auto-negotiation. If auto-negotiation is successful + * then the link-up status bit will be set and the flow control enable + * bits (RFCE and TFCE) will be set according to their negotiated value. + */ + e_dbg("Auto-negotiation enabled\n"); + + ew32(CTRL, ctrl); + e1e_flush(); + usleep_range(1000, 2000); + + /* + * For these adapters, the SW definable pin 1 is set when the optics + * detect a signal. If we have a signal, then poll for a "Link-Up" + * indication. + */ + if (hw->phy.media_type == e1000_media_type_internal_serdes || + (er32(CTRL) & E1000_CTRL_SWDPIN1)) { + ret_val = e1000_poll_fiber_serdes_link_generic(hw); + } else { + e_dbg("No signal detected\n"); + } + + return 0; +} + +/** + * e1000e_config_collision_dist - Configure collision distance + * @hw: pointer to the HW structure + * + * Configures the collision distance to the default value and is used + * during link setup. Currently no func pointer exists and all + * implementations are handled in the generic version of this function. + **/ +void e1000e_config_collision_dist(struct e1000_hw *hw) +{ + u32 tctl; + + tctl = er32(TCTL); + + tctl &= ~E1000_TCTL_COLD; + tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; + + ew32(TCTL, tctl); + e1e_flush(); +} + +/** + * e1000e_set_fc_watermarks - Set flow control high/low watermarks + * @hw: pointer to the HW structure + * + * Sets the flow control high/low threshold (watermark) registers. If + * flow control XON frame transmission is enabled, then set XON frame + * transmission as well. + **/ +s32 e1000e_set_fc_watermarks(struct e1000_hw *hw) +{ + u32 fcrtl = 0, fcrth = 0; + + /* + * Set the flow control receive threshold registers. Normally, + * these registers will be set to a default threshold that may be + * adjusted later by the driver's runtime code. However, if the + * ability to transmit pause frames is not enabled, then these + * registers will be set to 0. + */ + if (hw->fc.current_mode & e1000_fc_tx_pause) { + /* + * We need to set up the Receive Threshold high and low water + * marks as well as (optionally) enabling the transmission of + * XON frames. + */ + fcrtl = hw->fc.low_water; + fcrtl |= E1000_FCRTL_XONE; + fcrth = hw->fc.high_water; + } + ew32(FCRTL, fcrtl); + ew32(FCRTH, fcrth); + + return 0; +} + +/** + * e1000e_force_mac_fc - Force the MAC's flow control settings + * @hw: pointer to the HW structure + * + * Force the MAC's flow control settings. Sets the TFCE and RFCE bits in the + * device control register to reflect the adapter settings. TFCE and RFCE + * need to be explicitly set by software when a copper PHY is used because + * autonegotiation is managed by the PHY rather than the MAC. Software must + * also configure these bits when link is forced on a fiber connection. + **/ +s32 e1000e_force_mac_fc(struct e1000_hw *hw) +{ + u32 ctrl; + + ctrl = er32(CTRL); + + /* + * Because we didn't get link via the internal auto-negotiation + * mechanism (we either forced link or we got link via PHY + * auto-neg), we have to manually enable/disable transmit an + * receive flow control. + * + * The "Case" statement below enables/disable flow control + * according to the "hw->fc.current_mode" parameter. + * + * The possible values of the "fc" parameter are: + * 0: Flow control is completely disabled + * 1: Rx flow control is enabled (we can receive pause + * frames but not send pause frames). + * 2: Tx flow control is enabled (we can send pause frames + * frames but we do not receive pause frames). + * 3: Both Rx and Tx flow control (symmetric) is enabled. + * other: No other values should be possible at this point. + */ + e_dbg("hw->fc.current_mode = %u\n", hw->fc.current_mode); + + switch (hw->fc.current_mode) { + case e1000_fc_none: + ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE)); + break; + case e1000_fc_rx_pause: + ctrl &= (~E1000_CTRL_TFCE); + ctrl |= E1000_CTRL_RFCE; + break; + case e1000_fc_tx_pause: + ctrl &= (~E1000_CTRL_RFCE); + ctrl |= E1000_CTRL_TFCE; + break; + case e1000_fc_full: + ctrl |= (E1000_CTRL_TFCE | E1000_CTRL_RFCE); + break; + default: + e_dbg("Flow control param set incorrectly\n"); + return -E1000_ERR_CONFIG; + } + + ew32(CTRL, ctrl); + + return 0; +} + +/** + * e1000e_config_fc_after_link_up - Configures flow control after link + * @hw: pointer to the HW structure + * + * Checks the status of auto-negotiation after link up to ensure that the + * speed and duplex were not forced. If the link needed to be forced, then + * flow control needs to be forced also. If auto-negotiation is enabled + * and did not fail, then we configure flow control based on our link + * partner. + **/ +s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val = 0; + u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg; + u16 speed, duplex; + + /* + * Check for the case where we have fiber media and auto-neg failed + * so we had to force link. In this case, we need to force the + * configuration of the MAC to match the "fc" parameter. + */ + if (mac->autoneg_failed) { + if (hw->phy.media_type == e1000_media_type_fiber || + hw->phy.media_type == e1000_media_type_internal_serdes) + ret_val = e1000e_force_mac_fc(hw); + } else { + if (hw->phy.media_type == e1000_media_type_copper) + ret_val = e1000e_force_mac_fc(hw); + } + + if (ret_val) { + e_dbg("Error forcing flow control settings\n"); + return ret_val; + } + + /* + * Check for the case where we have copper media and auto-neg is + * enabled. In this case, we need to check and see if Auto-Neg + * has completed, and if so, how the PHY and link partner has + * flow control configured. + */ + if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) { + /* + * Read the MII Status Register and check to see if AutoNeg + * has completed. We read this twice because this reg has + * some "sticky" (latched) bits. + */ + ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); + if (ret_val) + return ret_val; + ret_val = e1e_rphy(hw, PHY_STATUS, &mii_status_reg); + if (ret_val) + return ret_val; + + if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) { + e_dbg("Copper PHY and Auto Neg has not completed.\n"); + return ret_val; + } + + /* + * The AutoNeg process has completed, so we now need to + * read both the Auto Negotiation Advertisement + * Register (Address 4) and the Auto_Negotiation Base + * Page Ability Register (Address 5) to determine how + * flow control was negotiated. + */ + ret_val = e1e_rphy(hw, PHY_AUTONEG_ADV, &mii_nway_adv_reg); + if (ret_val) + return ret_val; + ret_val = + e1e_rphy(hw, PHY_LP_ABILITY, &mii_nway_lp_ability_reg); + if (ret_val) + return ret_val; + + /* + * Two bits in the Auto Negotiation Advertisement Register + * (Address 4) and two bits in the Auto Negotiation Base + * Page Ability Register (Address 5) determine flow control + * for both the PHY and the link partner. The following + * table, taken out of the IEEE 802.3ab/D6.0 dated March 25, + * 1999, describes these PAUSE resolution bits and how flow + * control is determined based upon these settings. + * NOTE: DC = Don't Care + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | NIC Resolution + *-------|---------|-------|---------|-------------------- + * 0 | 0 | DC | DC | e1000_fc_none + * 0 | 1 | 0 | DC | e1000_fc_none + * 0 | 1 | 1 | 0 | e1000_fc_none + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause + * 1 | 0 | 0 | DC | e1000_fc_none + * 1 | DC | 1 | DC | e1000_fc_full + * 1 | 1 | 0 | 0 | e1000_fc_none + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause + * + * Are both PAUSE bits set to 1? If so, this implies + * Symmetric Flow Control is enabled at both ends. The + * ASM_DIR bits are irrelevant per the spec. + * + * For Symmetric Flow Control: + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 1 | DC | 1 | DC | E1000_fc_full + * + */ + if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) { + /* + * Now we need to check if the user selected Rx ONLY + * of pause frames. In this case, we had to advertise + * FULL flow control because we could not advertise Rx + * ONLY. Hence, we must now check to see if we need to + * turn OFF the TRANSMISSION of PAUSE frames. + */ + if (hw->fc.requested_mode == e1000_fc_full) { + hw->fc.current_mode = e1000_fc_full; + e_dbg("Flow Control = FULL.\n"); + } else { + hw->fc.current_mode = e1000_fc_rx_pause; + e_dbg("Flow Control = Rx PAUSE frames only.\n"); + } + } + /* + * For receiving PAUSE frames ONLY. + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 0 | 1 | 1 | 1 | e1000_fc_tx_pause + */ + else if (!(mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + hw->fc.current_mode = e1000_fc_tx_pause; + e_dbg("Flow Control = Tx PAUSE frames only.\n"); + } + /* + * For transmitting PAUSE frames ONLY. + * + * LOCAL DEVICE | LINK PARTNER + * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result + *-------|---------|-------|---------|-------------------- + * 1 | 1 | 0 | 1 | e1000_fc_rx_pause + */ + else if ((mii_nway_adv_reg & NWAY_AR_PAUSE) && + (mii_nway_adv_reg & NWAY_AR_ASM_DIR) && + !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && + (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { + hw->fc.current_mode = e1000_fc_rx_pause; + e_dbg("Flow Control = Rx PAUSE frames only.\n"); + } else { + /* + * Per the IEEE spec, at this point flow control + * should be disabled. + */ + hw->fc.current_mode = e1000_fc_none; + e_dbg("Flow Control = NONE.\n"); + } + + /* + * Now we need to do one last check... If we auto- + * negotiated to HALF DUPLEX, flow control should not be + * enabled per IEEE 802.3 spec. + */ + ret_val = mac->ops.get_link_up_info(hw, &speed, &duplex); + if (ret_val) { + e_dbg("Error getting link speed and duplex\n"); + return ret_val; + } + + if (duplex == HALF_DUPLEX) + hw->fc.current_mode = e1000_fc_none; + + /* + * Now we call a subroutine to actually force the MAC + * controller to use the correct flow control settings. + */ + ret_val = e1000e_force_mac_fc(hw); + if (ret_val) { + e_dbg("Error forcing flow control settings\n"); + return ret_val; + } + } + + return 0; +} + +/** + * e1000e_get_speed_and_duplex_copper - Retrieve current speed/duplex + * @hw: pointer to the HW structure + * @speed: stores the current speed + * @duplex: stores the current duplex + * + * Read the status register for the current speed/duplex and store the current + * speed and duplex for copper connections. + **/ +s32 e1000e_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed, + u16 *duplex) +{ + u32 status; + + status = er32(STATUS); + if (status & E1000_STATUS_SPEED_1000) + *speed = SPEED_1000; + else if (status & E1000_STATUS_SPEED_100) + *speed = SPEED_100; + else + *speed = SPEED_10; + + if (status & E1000_STATUS_FD) + *duplex = FULL_DUPLEX; + else + *duplex = HALF_DUPLEX; + + e_dbg("%u Mbps, %s Duplex\n", + *speed == SPEED_1000 ? 1000 : *speed == SPEED_100 ? 100 : 10, + *duplex == FULL_DUPLEX ? "Full" : "Half"); + + return 0; +} + +/** + * e1000e_get_speed_and_duplex_fiber_serdes - Retrieve current speed/duplex + * @hw: pointer to the HW structure + * @speed: stores the current speed + * @duplex: stores the current duplex + * + * Sets the speed and duplex to gigabit full duplex (the only possible option) + * for fiber/serdes links. + **/ +s32 e1000e_get_speed_and_duplex_fiber_serdes(struct e1000_hw *hw, u16 *speed, + u16 *duplex) +{ + *speed = SPEED_1000; + *duplex = FULL_DUPLEX; + + return 0; +} + +/** + * e1000e_get_hw_semaphore - Acquire hardware semaphore + * @hw: pointer to the HW structure + * + * Acquire the HW semaphore to access the PHY or NVM + **/ +s32 e1000e_get_hw_semaphore(struct e1000_hw *hw) +{ + u32 swsm; + s32 timeout = hw->nvm.word_size + 1; + s32 i = 0; + + /* Get the SW semaphore */ + while (i < timeout) { + swsm = er32(SWSM); + if (!(swsm & E1000_SWSM_SMBI)) + break; + + udelay(50); + i++; + } + + if (i == timeout) { + e_dbg("Driver can't access device - SMBI bit is set.\n"); + return -E1000_ERR_NVM; + } + + /* Get the FW semaphore. */ + for (i = 0; i < timeout; i++) { + swsm = er32(SWSM); + ew32(SWSM, swsm | E1000_SWSM_SWESMBI); + + /* Semaphore acquired if bit latched */ + if (er32(SWSM) & E1000_SWSM_SWESMBI) + break; + + udelay(50); + } + + if (i == timeout) { + /* Release semaphores */ + e1000e_put_hw_semaphore(hw); + e_dbg("Driver can't access the NVM\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000e_put_hw_semaphore - Release hardware semaphore + * @hw: pointer to the HW structure + * + * Release hardware semaphore used to access the PHY or NVM + **/ +void e1000e_put_hw_semaphore(struct e1000_hw *hw) +{ + u32 swsm; + + swsm = er32(SWSM); + swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); + ew32(SWSM, swsm); +} + +/** + * e1000e_get_auto_rd_done - Check for auto read completion + * @hw: pointer to the HW structure + * + * Check EEPROM for Auto Read done bit. + **/ +s32 e1000e_get_auto_rd_done(struct e1000_hw *hw) +{ + s32 i = 0; + + while (i < AUTO_READ_DONE_TIMEOUT) { + if (er32(EECD) & E1000_EECD_AUTO_RD) + break; + usleep_range(1000, 2000); + i++; + } + + if (i == AUTO_READ_DONE_TIMEOUT) { + e_dbg("Auto read by HW from NVM has not completed.\n"); + return -E1000_ERR_RESET; + } + + return 0; +} + +/** + * e1000e_valid_led_default - Verify a valid default LED config + * @hw: pointer to the HW structure + * @data: pointer to the NVM (EEPROM) + * + * Read the EEPROM for the current default LED configuration. If the + * LED configuration is not valid, set to a valid LED configuration. + **/ +s32 e1000e_valid_led_default(struct e1000_hw *hw, u16 *data) +{ + s32 ret_val; + + ret_val = e1000_read_nvm(hw, NVM_ID_LED_SETTINGS, 1, data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + + if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) + *data = ID_LED_DEFAULT; + + return 0; +} + +/** + * e1000e_id_led_init - + * @hw: pointer to the HW structure + * + **/ +s32 e1000e_id_led_init(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + s32 ret_val; + const u32 ledctl_mask = 0x000000FF; + const u32 ledctl_on = E1000_LEDCTL_MODE_LED_ON; + const u32 ledctl_off = E1000_LEDCTL_MODE_LED_OFF; + u16 data, i, temp; + const u16 led_mask = 0x0F; + + ret_val = hw->nvm.ops.valid_led_default(hw, &data); + if (ret_val) + return ret_val; + + mac->ledctl_default = er32(LEDCTL); + mac->ledctl_mode1 = mac->ledctl_default; + mac->ledctl_mode2 = mac->ledctl_default; + + for (i = 0; i < 4; i++) { + temp = (data >> (i << 2)) & led_mask; + switch (temp) { + case ID_LED_ON1_DEF2: + case ID_LED_ON1_ON2: + case ID_LED_ON1_OFF2: + mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode1 |= ledctl_on << (i << 3); + break; + case ID_LED_OFF1_DEF2: + case ID_LED_OFF1_ON2: + case ID_LED_OFF1_OFF2: + mac->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode1 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + switch (temp) { + case ID_LED_DEF1_ON2: + case ID_LED_ON1_ON2: + case ID_LED_OFF1_ON2: + mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode2 |= ledctl_on << (i << 3); + break; + case ID_LED_DEF1_OFF2: + case ID_LED_ON1_OFF2: + case ID_LED_OFF1_OFF2: + mac->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); + mac->ledctl_mode2 |= ledctl_off << (i << 3); + break; + default: + /* Do nothing */ + break; + } + } + + return 0; +} + +/** + * e1000e_setup_led_generic - Configures SW controllable LED + * @hw: pointer to the HW structure + * + * This prepares the SW controllable LED for use and saves the current state + * of the LED so it can be later restored. + **/ +s32 e1000e_setup_led_generic(struct e1000_hw *hw) +{ + u32 ledctl; + + if (hw->mac.ops.setup_led != e1000e_setup_led_generic) + return -E1000_ERR_CONFIG; + + if (hw->phy.media_type == e1000_media_type_fiber) { + ledctl = er32(LEDCTL); + hw->mac.ledctl_default = ledctl; + /* Turn off LED0 */ + ledctl &= ~(E1000_LEDCTL_LED0_IVRT | E1000_LEDCTL_LED0_BLINK | + E1000_LEDCTL_LED0_MODE_MASK); + ledctl |= (E1000_LEDCTL_MODE_LED_OFF << + E1000_LEDCTL_LED0_MODE_SHIFT); + ew32(LEDCTL, ledctl); + } else if (hw->phy.media_type == e1000_media_type_copper) { + ew32(LEDCTL, hw->mac.ledctl_mode1); + } + + return 0; +} + +/** + * e1000e_cleanup_led_generic - Set LED config to default operation + * @hw: pointer to the HW structure + * + * Remove the current LED configuration and set the LED configuration + * to the default value, saved from the EEPROM. + **/ +s32 e1000e_cleanup_led_generic(struct e1000_hw *hw) +{ + ew32(LEDCTL, hw->mac.ledctl_default); + return 0; +} + +/** + * e1000e_blink_led_generic - Blink LED + * @hw: pointer to the HW structure + * + * Blink the LEDs which are set to be on. + **/ +s32 e1000e_blink_led_generic(struct e1000_hw *hw) +{ + u32 ledctl_blink = 0; + u32 i; + + if (hw->phy.media_type == e1000_media_type_fiber) { + /* always blink LED0 for PCI-E fiber */ + ledctl_blink = E1000_LEDCTL_LED0_BLINK | + (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT); + } else { + /* + * set the blink bit for each LED that's "on" (0x0E) + * in ledctl_mode2 + */ + ledctl_blink = hw->mac.ledctl_mode2; + for (i = 0; i < 4; i++) + if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) == + E1000_LEDCTL_MODE_LED_ON) + ledctl_blink |= (E1000_LEDCTL_LED0_BLINK << + (i * 8)); + } + + ew32(LEDCTL, ledctl_blink); + + return 0; +} + +/** + * e1000e_led_on_generic - Turn LED on + * @hw: pointer to the HW structure + * + * Turn LED on. + **/ +s32 e1000e_led_on_generic(struct e1000_hw *hw) +{ + u32 ctrl; + + switch (hw->phy.media_type) { + case e1000_media_type_fiber: + ctrl = er32(CTRL); + ctrl &= ~E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + ew32(CTRL, ctrl); + break; + case e1000_media_type_copper: + ew32(LEDCTL, hw->mac.ledctl_mode2); + break; + default: + break; + } + + return 0; +} + +/** + * e1000e_led_off_generic - Turn LED off + * @hw: pointer to the HW structure + * + * Turn LED off. + **/ +s32 e1000e_led_off_generic(struct e1000_hw *hw) +{ + u32 ctrl; + + switch (hw->phy.media_type) { + case e1000_media_type_fiber: + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_SWDPIN0; + ctrl |= E1000_CTRL_SWDPIO0; + ew32(CTRL, ctrl); + break; + case e1000_media_type_copper: + ew32(LEDCTL, hw->mac.ledctl_mode1); + break; + default: + break; + } + + return 0; +} + +/** + * e1000e_set_pcie_no_snoop - Set PCI-express capabilities + * @hw: pointer to the HW structure + * @no_snoop: bitmap of snoop events + * + * Set the PCI-express register to snoop for events enabled in 'no_snoop'. + **/ +void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop) +{ + u32 gcr; + + if (no_snoop) { + gcr = er32(GCR); + gcr &= ~(PCIE_NO_SNOOP_ALL); + gcr |= no_snoop; + ew32(GCR, gcr); + } +} + +/** + * e1000e_disable_pcie_master - Disables PCI-express master access + * @hw: pointer to the HW structure + * + * Returns 0 if successful, else returns -10 + * (-E1000_ERR_MASTER_REQUESTS_PENDING) if master disable bit has not caused + * the master requests to be disabled. + * + * Disables PCI-Express master access and verifies there are no pending + * requests. + **/ +s32 e1000e_disable_pcie_master(struct e1000_hw *hw) +{ + u32 ctrl; + s32 timeout = MASTER_DISABLE_TIMEOUT; + + ctrl = er32(CTRL); + ctrl |= E1000_CTRL_GIO_MASTER_DISABLE; + ew32(CTRL, ctrl); + + while (timeout) { + if (!(er32(STATUS) & E1000_STATUS_GIO_MASTER_ENABLE)) + break; + udelay(100); + timeout--; + } + + if (!timeout) { + e_dbg("Master requests are pending.\n"); + return -E1000_ERR_MASTER_REQUESTS_PENDING; + } + + return 0; +} + +/** + * e1000e_reset_adaptive - Reset Adaptive Interframe Spacing + * @hw: pointer to the HW structure + * + * Reset the Adaptive Interframe Spacing throttle to default values. + **/ +void e1000e_reset_adaptive(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + + mac->current_ifs_val = 0; + mac->ifs_min_val = IFS_MIN; + mac->ifs_max_val = IFS_MAX; + mac->ifs_step_size = IFS_STEP; + mac->ifs_ratio = IFS_RATIO; + + mac->in_ifs_mode = false; + ew32(AIT, 0); +out: + return; +} + +/** + * e1000e_update_adaptive - Update Adaptive Interframe Spacing + * @hw: pointer to the HW structure + * + * Update the Adaptive Interframe Spacing Throttle value based on the + * time between transmitted packets and time between collisions. + **/ +void e1000e_update_adaptive(struct e1000_hw *hw) +{ + struct e1000_mac_info *mac = &hw->mac; + + if (!mac->adaptive_ifs) { + e_dbg("Not in Adaptive IFS mode!\n"); + goto out; + } + + if ((mac->collision_delta * mac->ifs_ratio) > mac->tx_packet_delta) { + if (mac->tx_packet_delta > MIN_NUM_XMITS) { + mac->in_ifs_mode = true; + if (mac->current_ifs_val < mac->ifs_max_val) { + if (!mac->current_ifs_val) + mac->current_ifs_val = mac->ifs_min_val; + else + mac->current_ifs_val += + mac->ifs_step_size; + ew32(AIT, mac->current_ifs_val); + } + } + } else { + if (mac->in_ifs_mode && + (mac->tx_packet_delta <= MIN_NUM_XMITS)) { + mac->current_ifs_val = 0; + mac->in_ifs_mode = false; + ew32(AIT, 0); + } + } +out: + return; +} diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c new file mode 100644 index 00000000000..3dae2655ec7 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/manage.c @@ -0,0 +1,377 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +enum e1000_mng_mode { + e1000_mng_mode_none = 0, + e1000_mng_mode_asf, + e1000_mng_mode_pt, + e1000_mng_mode_ipmi, + e1000_mng_mode_host_if_only +}; + +#define E1000_FACTPS_MNGCG 0x20000000 + +/* Intel(R) Active Management Technology signature */ +#define E1000_IAMT_SIGNATURE 0x544D4149 + +/** + * e1000_calculate_checksum - Calculate checksum for buffer + * @buffer: pointer to EEPROM + * @length: size of EEPROM to calculate a checksum for + * + * Calculates the checksum for some buffer on a specified length. The + * checksum calculated is returned. + **/ +static u8 e1000_calculate_checksum(u8 *buffer, u32 length) +{ + u32 i; + u8 sum = 0; + + if (!buffer) + return 0; + + for (i = 0; i < length; i++) + sum += buffer[i]; + + return (u8)(0 - sum); +} + +/** + * e1000_mng_enable_host_if - Checks host interface is enabled + * @hw: pointer to the HW structure + * + * Returns E1000_success upon success, else E1000_ERR_HOST_INTERFACE_COMMAND + * + * This function checks whether the HOST IF is enabled for command operation + * and also checks whether the previous command is completed. It busy waits + * in case of previous command is not completed. + **/ +static s32 e1000_mng_enable_host_if(struct e1000_hw *hw) +{ + u32 hicr; + u8 i; + + if (!(hw->mac.arc_subsystem_valid)) { + e_dbg("ARC subsystem not valid.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + + /* Check that the host interface is enabled. */ + hicr = er32(HICR); + if ((hicr & E1000_HICR_EN) == 0) { + e_dbg("E1000_HOST_EN bit disabled.\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + /* check the previous command is completed */ + for (i = 0; i < E1000_MNG_DHCP_COMMAND_TIMEOUT; i++) { + hicr = er32(HICR); + if (!(hicr & E1000_HICR_C)) + break; + mdelay(1); + } + + if (i == E1000_MNG_DHCP_COMMAND_TIMEOUT) { + e_dbg("Previous command timeout failed .\n"); + return -E1000_ERR_HOST_INTERFACE_COMMAND; + } + + return 0; +} + +/** + * e1000e_check_mng_mode_generic - check management mode + * @hw: pointer to the HW structure + * + * Reads the firmware semaphore register and returns true (>0) if + * manageability is enabled, else false (0). + **/ +bool e1000e_check_mng_mode_generic(struct e1000_hw *hw) +{ + u32 fwsm = er32(FWSM); + + return (fwsm & E1000_FWSM_MODE_MASK) == + (E1000_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT); +} + +/** + * e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx + * @hw: pointer to the HW structure + * + * Enables packet filtering on transmit packets if manageability is enabled + * and host interface is enabled. + **/ +bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw) +{ + struct e1000_host_mng_dhcp_cookie *hdr = &hw->mng_cookie; + u32 *buffer = (u32 *)&hw->mng_cookie; + u32 offset; + s32 ret_val, hdr_csum, csum; + u8 i, len; + + hw->mac.tx_pkt_filtering = true; + + /* No manageability, no filtering */ + if (!e1000e_check_mng_mode(hw)) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + + /* + * If we can't read from the host interface for whatever + * reason, disable filtering. + */ + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + + /* Read in the header. Length and offset are in dwords. */ + len = E1000_MNG_DHCP_COOKIE_LENGTH >> 2; + offset = E1000_MNG_DHCP_COOKIE_OFFSET >> 2; + for (i = 0; i < len; i++) + *(buffer + i) = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, + offset + i); + hdr_csum = hdr->checksum; + hdr->checksum = 0; + csum = e1000_calculate_checksum((u8 *)hdr, + E1000_MNG_DHCP_COOKIE_LENGTH); + /* + * If either the checksums or signature don't match, then + * the cookie area isn't considered valid, in which case we + * take the safe route of assuming Tx filtering is enabled. + */ + if ((hdr_csum != csum) || (hdr->signature != E1000_IAMT_SIGNATURE)) { + hw->mac.tx_pkt_filtering = true; + goto out; + } + + /* Cookie area is valid, make the final check for filtering. */ + if (!(hdr->status & E1000_MNG_DHCP_COOKIE_STATUS_PARSING)) { + hw->mac.tx_pkt_filtering = false; + goto out; + } + +out: + return hw->mac.tx_pkt_filtering; +} + +/** + * e1000_mng_write_cmd_header - Writes manageability command header + * @hw: pointer to the HW structure + * @hdr: pointer to the host interface command header + * + * Writes the command header after does the checksum calculation. + **/ +static s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, + struct e1000_host_mng_command_header *hdr) +{ + u16 i, length = sizeof(struct e1000_host_mng_command_header); + + /* Write the whole command header structure with new checksum. */ + + hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); + + length >>= 2; + /* Write the relevant command block into the ram area. */ + for (i = 0; i < length; i++) { + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); + e1e_flush(); + } + + return 0; +} + +/** + * e1000_mng_host_if_write - Write to the manageability host interface + * @hw: pointer to the HW structure + * @buffer: pointer to the host interface buffer + * @length: size of the buffer + * @offset: location in the buffer to write to + * @sum: sum of the data (not checksum) + * + * This function writes the buffer content at the offset given on the host if. + * It also does alignment considerations to do the writes in most efficient + * way. Also fills up the sum of the buffer in *buffer parameter. + **/ +static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer, + u16 length, u16 offset, u8 *sum) +{ + u8 *tmp; + u8 *bufptr = buffer; + u32 data = 0; + u16 remaining, i, j, prev_bytes; + + /* sum = only sum of the data and it is not checksum */ + + if (length == 0 || offset + length > E1000_HI_MAX_MNG_DATA_LENGTH) + return -E1000_ERR_PARAM; + + tmp = (u8 *)&data; + prev_bytes = offset & 0x3; + offset >>= 2; + + if (prev_bytes) { + data = E1000_READ_REG_ARRAY(hw, E1000_HOST_IF, offset); + for (j = prev_bytes; j < sizeof(u32); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset, data); + length -= j - prev_bytes; + offset++; + } + + remaining = length & 0x3; + length -= remaining; + + /* Calculate length in DWORDs */ + length >>= 2; + + /* + * The device driver writes the relevant command block into the + * ram area. + */ + for (i = 0; i < length; i++) { + for (j = 0; j < sizeof(u32); j++) { + *(tmp + j) = *bufptr++; + *sum += *(tmp + j); + } + + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); + } + if (remaining) { + for (j = 0; j < sizeof(u32); j++) { + if (j < remaining) + *(tmp + j) = *bufptr++; + else + *(tmp + j) = 0; + + *sum += *(tmp + j); + } + E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, offset + i, data); + } + + return 0; +} + +/** + * e1000e_mng_write_dhcp_info - Writes DHCP info to host interface + * @hw: pointer to the HW structure + * @buffer: pointer to the host interface + * @length: size of the buffer + * + * Writes the DHCP information to the host interface. + **/ +s32 e1000e_mng_write_dhcp_info(struct e1000_hw *hw, u8 *buffer, u16 length) +{ + struct e1000_host_mng_command_header hdr; + s32 ret_val; + u32 hicr; + + hdr.command_id = E1000_MNG_DHCP_TX_PAYLOAD_CMD; + hdr.command_length = length; + hdr.reserved1 = 0; + hdr.reserved2 = 0; + hdr.checksum = 0; + + /* Enable the host interface */ + ret_val = e1000_mng_enable_host_if(hw); + if (ret_val) + return ret_val; + + /* Populate the host interface with the contents of "buffer". */ + ret_val = e1000_mng_host_if_write(hw, buffer, length, + sizeof(hdr), &(hdr.checksum)); + if (ret_val) + return ret_val; + + /* Write the manageability command header */ + ret_val = e1000_mng_write_cmd_header(hw, &hdr); + if (ret_val) + return ret_val; + + /* Tell the ARC a new command is pending. */ + hicr = er32(HICR); + ew32(HICR, hicr | E1000_HICR_C); + + return 0; +} + +/** + * e1000e_enable_mng_pass_thru - Check if management passthrough is needed + * @hw: pointer to the HW structure + * + * Verifies the hardware needs to leave interface enabled so that frames can + * be directed to and from the management interface. + **/ +bool e1000e_enable_mng_pass_thru(struct e1000_hw *hw) +{ + u32 manc; + u32 fwsm, factps; + bool ret_val = false; + + manc = er32(MANC); + + if (!(manc & E1000_MANC_RCV_TCO_EN)) + goto out; + + if (hw->mac.has_fwsm) { + fwsm = er32(FWSM); + factps = er32(FACTPS); + + if (!(factps & E1000_FACTPS_MNGCG) && + ((fwsm & E1000_FWSM_MODE_MASK) == + (e1000_mng_mode_pt << E1000_FWSM_MODE_SHIFT))) { + ret_val = true; + goto out; + } + } else if ((hw->mac.type == e1000_82574) || + (hw->mac.type == e1000_82583)) { + u16 data; + + factps = er32(FACTPS); + e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &data); + + if (!(factps & E1000_FACTPS_MNGCG) && + ((data & E1000_NVM_INIT_CTRL2_MNGM) == + (e1000_mng_mode_pt << 13))) { + ret_val = true; + goto out; + } + } else if ((manc & E1000_MANC_SMBUS_EN) && + !(manc & E1000_MANC_ASF_EN)) { + ret_val = true; + goto out; + } + +out: + return ret_val; +} diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c new file mode 100644 index 00000000000..dbdaa0052b1 --- /dev/null +++ b/drivers/net/ethernet/intel/e1000e/nvm.c @@ -0,0 +1,647 @@ +/******************************************************************************* + + Intel PRO/1000 Linux driver + Copyright(c) 1999 - 2011 Intel Corporation. + + This program is free software; you can redistribute it and/or modify it + under the terms and conditions of the GNU General Public License, + version 2, as published by the Free Software Foundation. + + This program is distributed in the hope it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. + + The full GNU General Public License is included in this distribution in + the file called "COPYING". + + Contact Information: + Linux NICS + e1000-devel Mailing List + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include "e1000.h" + +/** + * e1000_raise_eec_clk - Raise EEPROM clock + * @hw: pointer to the HW structure + * @eecd: pointer to the EEPROM + * + * Enable/Raise the EEPROM clock bit. + **/ +static void e1000_raise_eec_clk(struct e1000_hw *hw, u32 *eecd) +{ + *eecd = *eecd | E1000_EECD_SK; + ew32(EECD, *eecd); + e1e_flush(); + udelay(hw->nvm.delay_usec); +} + +/** + * e1000_lower_eec_clk - Lower EEPROM clock + * @hw: pointer to the HW structure + * @eecd: pointer to the EEPROM + * + * Clear/Lower the EEPROM clock bit. + **/ +static void e1000_lower_eec_clk(struct e1000_hw *hw, u32 *eecd) +{ + *eecd = *eecd & ~E1000_EECD_SK; + ew32(EECD, *eecd); + e1e_flush(); + udelay(hw->nvm.delay_usec); +} + +/** + * e1000_shift_out_eec_bits - Shift data bits our to the EEPROM + * @hw: pointer to the HW structure + * @data: data to send to the EEPROM + * @count: number of bits to shift out + * + * We need to shift 'count' bits out to the EEPROM. So, the value in the + * "data" parameter will be shifted out to the EEPROM one bit at a time. + * In order to do this, "data" must be broken down into bits. + **/ +static void e1000_shift_out_eec_bits(struct e1000_hw *hw, u16 data, u16 count) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + u32 mask; + + mask = 0x01 << (count - 1); + if (nvm->type == e1000_nvm_eeprom_spi) + eecd |= E1000_EECD_DO; + + do { + eecd &= ~E1000_EECD_DI; + + if (data & mask) + eecd |= E1000_EECD_DI; + + ew32(EECD, eecd); + e1e_flush(); + + udelay(nvm->delay_usec); + + e1000_raise_eec_clk(hw, &eecd); + e1000_lower_eec_clk(hw, &eecd); + + mask >>= 1; + } while (mask); + + eecd &= ~E1000_EECD_DI; + ew32(EECD, eecd); +} + +/** + * e1000_shift_in_eec_bits - Shift data bits in from the EEPROM + * @hw: pointer to the HW structure + * @count: number of bits to shift in + * + * In order to read a register from the EEPROM, we need to shift 'count' bits + * in from the EEPROM. Bits are "shifted in" by raising the clock input to + * the EEPROM (setting the SK bit), and then reading the value of the data out + * "DO" bit. During this "shifting in" process the data in "DI" bit should + * always be clear. + **/ +static u16 e1000_shift_in_eec_bits(struct e1000_hw *hw, u16 count) +{ + u32 eecd; + u32 i; + u16 data; + + eecd = er32(EECD); + + eecd &= ~(E1000_EECD_DO | E1000_EECD_DI); + data = 0; + + for (i = 0; i < count; i++) { + data <<= 1; + e1000_raise_eec_clk(hw, &eecd); + + eecd = er32(EECD); + + eecd &= ~E1000_EECD_DI; + if (eecd & E1000_EECD_DO) + data |= 1; + + e1000_lower_eec_clk(hw, &eecd); + } + + return data; +} + +/** + * e1000e_poll_eerd_eewr_done - Poll for EEPROM read/write completion + * @hw: pointer to the HW structure + * @ee_reg: EEPROM flag for polling + * + * Polls the EEPROM status bit for either read or write completion based + * upon the value of 'ee_reg'. + **/ +s32 e1000e_poll_eerd_eewr_done(struct e1000_hw *hw, int ee_reg) +{ + u32 attempts = 100000; + u32 i, reg = 0; + + for (i = 0; i < attempts; i++) { + if (ee_reg == E1000_NVM_POLL_READ) + reg = er32(EERD); + else + reg = er32(EEWR); + + if (reg & E1000_NVM_RW_REG_DONE) + return 0; + + udelay(5); + } + + return -E1000_ERR_NVM; +} + +/** + * e1000e_acquire_nvm - Generic request for access to EEPROM + * @hw: pointer to the HW structure + * + * Set the EEPROM access request bit and wait for EEPROM access grant bit. + * Return successful if access grant bit set, else clear the request for + * EEPROM access and return -E1000_ERR_NVM (-1). + **/ +s32 e1000e_acquire_nvm(struct e1000_hw *hw) +{ + u32 eecd = er32(EECD); + s32 timeout = E1000_NVM_GRANT_ATTEMPTS; + + ew32(EECD, eecd | E1000_EECD_REQ); + eecd = er32(EECD); + + while (timeout) { + if (eecd & E1000_EECD_GNT) + break; + udelay(5); + eecd = er32(EECD); + timeout--; + } + + if (!timeout) { + eecd &= ~E1000_EECD_REQ; + ew32(EECD, eecd); + e_dbg("Could not acquire NVM grant\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000_standby_nvm - Return EEPROM to standby state + * @hw: pointer to the HW structure + * + * Return the EEPROM to a standby state. + **/ +static void e1000_standby_nvm(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + + if (nvm->type == e1000_nvm_eeprom_spi) { + /* Toggle CS to flush commands */ + eecd |= E1000_EECD_CS; + ew32(EECD, eecd); + e1e_flush(); + udelay(nvm->delay_usec); + eecd &= ~E1000_EECD_CS; + ew32(EECD, eecd); + e1e_flush(); + udelay(nvm->delay_usec); + } +} + +/** + * e1000_stop_nvm - Terminate EEPROM command + * @hw: pointer to the HW structure + * + * Terminates the current command by inverting the EEPROM's chip select pin. + **/ +static void e1000_stop_nvm(struct e1000_hw *hw) +{ + u32 eecd; + + eecd = er32(EECD); + if (hw->nvm.type == e1000_nvm_eeprom_spi) { + /* Pull CS high */ + eecd |= E1000_EECD_CS; + e1000_lower_eec_clk(hw, &eecd); + } +} + +/** + * e1000e_release_nvm - Release exclusive access to EEPROM + * @hw: pointer to the HW structure + * + * Stop any current commands to the EEPROM and clear the EEPROM request bit. + **/ +void e1000e_release_nvm(struct e1000_hw *hw) +{ + u32 eecd; + + e1000_stop_nvm(hw); + + eecd = er32(EECD); + eecd &= ~E1000_EECD_REQ; + ew32(EECD, eecd); +} + +/** + * e1000_ready_nvm_eeprom - Prepares EEPROM for read/write + * @hw: pointer to the HW structure + * + * Setups the EEPROM for reading and writing. + **/ +static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 eecd = er32(EECD); + u8 spi_stat_reg; + + if (nvm->type == e1000_nvm_eeprom_spi) { + u16 timeout = NVM_MAX_RETRY_SPI; + + /* Clear SK and CS */ + eecd &= ~(E1000_EECD_CS | E1000_EECD_SK); + ew32(EECD, eecd); + e1e_flush(); + udelay(1); + + /* + * Read "Status Register" repeatedly until the LSB is cleared. + * The EEPROM will signal that the command has been completed + * by clearing bit 0 of the internal status register. If it's + * not cleared within 'timeout', then error out. + */ + while (timeout) { + e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI, + hw->nvm.opcode_bits); + spi_stat_reg = (u8)e1000_shift_in_eec_bits(hw, 8); + if (!(spi_stat_reg & NVM_STATUS_RDY_SPI)) + break; + + udelay(5); + e1000_standby_nvm(hw); + timeout--; + } + + if (!timeout) { + e_dbg("SPI NVM Status error\n"); + return -E1000_ERR_NVM; + } + } + + return 0; +} + +/** + * e1000e_read_nvm_eerd - Reads EEPROM using EERD register + * @hw: pointer to the HW structure + * @offset: offset of word in the EEPROM to read + * @words: number of words to read + * @data: word read from the EEPROM + * + * Reads a 16 bit word from the EEPROM using the EERD register. + **/ +s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + u32 i, eerd = 0; + s32 ret_val = 0; + + /* + * A check for invalid values: offset too large, too many words, + * too many words for the offset, and not enough words. + */ + if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || + (words == 0)) { + e_dbg("nvm parameter(s) out of bounds\n"); + return -E1000_ERR_NVM; + } + + for (i = 0; i < words; i++) { + eerd = ((offset + i) << E1000_NVM_RW_ADDR_SHIFT) + + E1000_NVM_RW_REG_START; + + ew32(EERD, eerd); + ret_val = e1000e_poll_eerd_eewr_done(hw, E1000_NVM_POLL_READ); + if (ret_val) + break; + + data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA); + } + + return ret_val; +} + +/** + * e1000e_write_nvm_spi - Write to EEPROM using SPI + * @hw: pointer to the HW structure + * @offset: offset within the EEPROM to be written to + * @words: number of words to write + * @data: 16 bit word(s) to be written to the EEPROM + * + * Writes data to EEPROM at offset using SPI interface. + * + * If e1000e_update_nvm_checksum is not called after this function , the + * EEPROM will most likely contain an invalid checksum. + **/ +s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data) +{ + struct e1000_nvm_info *nvm = &hw->nvm; + s32 ret_val; + u16 widx = 0; + + /* + * A check for invalid values: offset too large, too many words, + * and not enough words. + */ + if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) || + (words == 0)) { + e_dbg("nvm parameter(s) out of bounds\n"); + return -E1000_ERR_NVM; + } + + ret_val = nvm->ops.acquire(hw); + if (ret_val) + return ret_val; + + while (widx < words) { + u8 write_opcode = NVM_WRITE_OPCODE_SPI; + + ret_val = e1000_ready_nvm_eeprom(hw); + if (ret_val) { + nvm->ops.release(hw); + return ret_val; + } + + e1000_standby_nvm(hw); + + /* Send the WRITE ENABLE command (8 bit opcode) */ + e1000_shift_out_eec_bits(hw, NVM_WREN_OPCODE_SPI, + nvm->opcode_bits); + + e1000_standby_nvm(hw); + + /* + * Some SPI eeproms use the 8th address bit embedded in the + * opcode + */ + if ((nvm->address_bits == 8) && (offset >= 128)) + write_opcode |= NVM_A8_OPCODE_SPI; + + /* Send the Write command (8-bit opcode + addr) */ + e1000_shift_out_eec_bits(hw, write_opcode, nvm->opcode_bits); + e1000_shift_out_eec_bits(hw, (u16)((offset + widx) * 2), + nvm->address_bits); + + /* Loop to allow for up to whole page write of eeprom */ + while (widx < words) { + u16 word_out = data[widx]; + word_out = (word_out >> 8) | (word_out << 8); + e1000_shift_out_eec_bits(hw, word_out, 16); + widx++; + + if ((((offset + widx) * 2) % nvm->page_size) == 0) { + e1000_standby_nvm(hw); + break; + } + } + } + + usleep_range(10000, 20000); + nvm->ops.release(hw); + return 0; +} + +/** + * e1000_read_pba_string_generic - Read device part number + * @hw: pointer to the HW structure + * @pba_num: pointer to device part number + * @pba_num_size: size of part number buffer + * + * Reads the product board assembly (PBA) number from the EEPROM and stores + * the value in pba_num. + **/ +s32 e1000_read_pba_string_generic(struct e1000_hw *hw, u8 *pba_num, + u32 pba_num_size) +{ + s32 ret_val; + u16 nvm_data; + u16 pba_ptr; + u16 offset; + u16 length; + + if (pba_num == NULL) { + e_dbg("PBA string buffer was null\n"); + ret_val = E1000_ERR_INVALID_ARGUMENT; + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_0, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + ret_val = e1000_read_nvm(hw, NVM_PBA_OFFSET_1, 1, &pba_ptr); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + /* + * if nvm_data is not ptr guard the PBA must be in legacy format which + * means pba_ptr is actually our second data word for the PBA number + * and we can decode it into an ascii string + */ + if (nvm_data != NVM_PBA_PTR_GUARD) { + e_dbg("NVM PBA number is not stored as string\n"); + + /* we will need 11 characters to store the PBA */ + if (pba_num_size < 11) { + e_dbg("PBA string buffer too small\n"); + return E1000_ERR_NO_SPACE; + } + + /* extract hex string from data and pba_ptr */ + pba_num[0] = (nvm_data >> 12) & 0xF; + pba_num[1] = (nvm_data >> 8) & 0xF; + pba_num[2] = (nvm_data >> 4) & 0xF; + pba_num[3] = nvm_data & 0xF; + pba_num[4] = (pba_ptr >> 12) & 0xF; + pba_num[5] = (pba_ptr >> 8) & 0xF; + pba_num[6] = '-'; + pba_num[7] = 0; + pba_num[8] = (pba_ptr >> 4) & 0xF; + pba_num[9] = pba_ptr & 0xF; + + /* put a null character on the end of our string */ + pba_num[10] = '\0'; + + /* switch all the data but the '-' to hex char */ + for (offset = 0; offset < 10; offset++) { + if (pba_num[offset] < 0xA) + pba_num[offset] += '0'; + else if (pba_num[offset] < 0x10) + pba_num[offset] += 'A' - 0xA; + } + + goto out; + } + + ret_val = e1000_read_nvm(hw, pba_ptr, 1, &length); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + + if (length == 0xFFFF || length == 0) { + e_dbg("NVM PBA number section invalid length\n"); + ret_val = E1000_ERR_NVM_PBA_SECTION; + goto out; + } + /* check if pba_num buffer is big enough */ + if (pba_num_size < (((u32)length * 2) - 1)) { + e_dbg("PBA string buffer too small\n"); + ret_val = E1000_ERR_NO_SPACE; + goto out; + } + + /* trim pba length from start of string */ + pba_ptr++; + length--; + + for (offset = 0; offset < length; offset++) { + ret_val = e1000_read_nvm(hw, pba_ptr + offset, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + goto out; + } + pba_num[offset * 2] = (u8)(nvm_data >> 8); + pba_num[(offset * 2) + 1] = (u8)(nvm_data & 0xFF); + } + pba_num[offset * 2] = '\0'; + +out: + return ret_val; +} + +/** + * e1000_read_mac_addr_generic - Read device MAC address + * @hw: pointer to the HW structure + * + * Reads the device MAC address from the EEPROM and stores the value. + * Since devices with two ports use the same EEPROM, we increment the + * last bit in the MAC address for the second port. + **/ +s32 e1000_read_mac_addr_generic(struct e1000_hw *hw) +{ + u32 rar_high; + u32 rar_low; + u16 i; + + rar_high = er32(RAH(0)); + rar_low = er32(RAL(0)); + + for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i] = (u8)(rar_low >> (i * 8)); + + for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++) + hw->mac.perm_addr[i + 4] = (u8)(rar_high >> (i * 8)); + + for (i = 0; i < ETH_ALEN; i++) + hw->mac.addr[i] = hw->mac.perm_addr[i]; + + return 0; +} + +/** + * e1000e_validate_nvm_checksum_generic - Validate EEPROM checksum + * @hw: pointer to the HW structure + * + * Calculates the EEPROM checksum by reading/adding each word of the EEPROM + * and then verifies that the sum of the EEPROM is equal to 0xBABA. + **/ +s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) { + ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error\n"); + return ret_val; + } + checksum += nvm_data; + } + + if (checksum != (u16)NVM_SUM) { + e_dbg("NVM Checksum Invalid\n"); + return -E1000_ERR_NVM; + } + + return 0; +} + +/** + * e1000e_update_nvm_checksum_generic - Update EEPROM checksum + * @hw: pointer to the HW structure + * + * Updates the EEPROM checksum by reading/adding each word of the EEPROM + * up to the checksum. Then calculates the EEPROM checksum and writes the + * value to the EEPROM. + **/ +s32 e1000e_update_nvm_checksum_generic(struct e1000_hw *hw) +{ + s32 ret_val; + u16 checksum = 0; + u16 i, nvm_data; + + for (i = 0; i < NVM_CHECKSUM_REG; i++) { + ret_val = e1000_read_nvm(hw, i, 1, &nvm_data); + if (ret_val) { + e_dbg("NVM Read Error while updating checksum.\n"); + return ret_val; + } + checksum += nvm_data; + } + checksum = (u16)NVM_SUM - checksum; + ret_val = e1000_write_nvm(hw, NVM_CHECKSUM_REG, 1, &checksum); + if (ret_val) + e_dbg("NVM Write Error while updating checksum.\n"); + + return ret_val; +} + +/** + * e1000e_reload_nvm - Reloads EEPROM + * @hw: pointer to the HW structure + * + * Reloads the EEPROM by setting the "Reinitialize from EEPROM" bit in the + * extended control register. + **/ +void e1000e_reload_nvm(struct e1000_hw *hw) +{ + u32 ctrl_ext; + + udelay(10); + ctrl_ext = er32(CTRL_EXT); + ctrl_ext |= E1000_CTRL_EXT_EE_RST; + ew32(CTRL_EXT, ctrl_ext); + e1e_flush(); +} -- cgit v1.2.3-70-g09d2 From f5e261e626eb3fe07adf484aaad2ecfc757feba3 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Sun, 1 Jan 2012 16:00:03 +0000 Subject: e1000e: update copyright year Signed-off-by: Bruce Allan Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/80003es2lan.c | 2 +- drivers/net/ethernet/intel/e1000e/82571.c | 2 +- drivers/net/ethernet/intel/e1000e/Makefile | 2 +- drivers/net/ethernet/intel/e1000e/defines.h | 2 +- drivers/net/ethernet/intel/e1000e/e1000.h | 2 +- drivers/net/ethernet/intel/e1000e/ethtool.c | 2 +- drivers/net/ethernet/intel/e1000e/hw.h | 2 +- drivers/net/ethernet/intel/e1000e/ich8lan.c | 2 +- drivers/net/ethernet/intel/e1000e/mac.c | 2 +- drivers/net/ethernet/intel/e1000e/manage.c | 2 +- drivers/net/ethernet/intel/e1000e/netdev.c | 4 ++-- drivers/net/ethernet/intel/e1000e/nvm.c | 2 +- drivers/net/ethernet/intel/e1000e/param.c | 2 +- drivers/net/ethernet/intel/e1000e/phy.c | 2 +- 14 files changed, 15 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/80003es2lan.c b/drivers/net/ethernet/intel/e1000e/80003es2lan.c index f323ce507f5..82a5d87c90c 100644 --- a/drivers/net/ethernet/intel/e1000e/80003es2lan.c +++ b/drivers/net/ethernet/intel/e1000e/80003es2lan.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 0609ac69bb3..844907da8aa 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/Makefile b/drivers/net/ethernet/intel/e1000e/Makefile index 8b888e5f6a0..591b7132450 100644 --- a/drivers/net/ethernet/intel/e1000e/Makefile +++ b/drivers/net/ethernet/intel/e1000e/Makefile @@ -1,7 +1,7 @@ ################################################################################ # # Intel PRO/1000 Linux driver -# Copyright(c) 1999 - 2011 Intel Corporation. +# Copyright(c) 1999 - 2012 Intel Corporation. # # This program is free software; you can redistribute it and/or modify it # under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/defines.h b/drivers/net/ethernet/intel/e1000e/defines.h index c73795f4653..1af30b967a4 100644 --- a/drivers/net/ethernet/intel/e1000e/defines.h +++ b/drivers/net/ethernet/intel/e1000e/defines.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index 70bc9e90273..45e5ae8a9fb 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 1ea317f1adc..92d5b627895 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h index a15da4712f8..197059bb9ab 100644 --- a/drivers/net/ethernet/intel/e1000e/hw.h +++ b/drivers/net/ethernet/intel/e1000e/hw.h @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 070a90f78aa..907b17b2e66 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c index 64b6f439338..e1cf1072f31 100644 --- a/drivers/net/ethernet/intel/e1000e/mac.c +++ b/drivers/net/ethernet/intel/e1000e/mac.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/manage.c b/drivers/net/ethernet/intel/e1000e/manage.c index 3dae2655ec7..6594dbf248b 100644 --- a/drivers/net/ethernet/intel/e1000e/manage.c +++ b/drivers/net/ethernet/intel/e1000e/manage.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 210d27ddd8c..1a8dd2f0e60 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, @@ -6538,7 +6538,7 @@ static int __init e1000_init_module(void) int ret; pr_info("Intel(R) PRO/1000 Network Driver - %s\n", e1000e_driver_version); - pr_info("Copyright(c) 1999 - 2011 Intel Corporation.\n"); + pr_info("Copyright(c) 1999 - 2012 Intel Corporation.\n"); ret = pci_register_driver(&e1000_driver); return ret; diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c index dbdaa0052b1..f6fb7a768ba 100644 --- a/drivers/net/ethernet/intel/e1000e/nvm.c +++ b/drivers/net/ethernet/intel/e1000e/nvm.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c index 40664f5bfbd..9c6a56d804a 100644 --- a/drivers/net/ethernet/intel/e1000e/param.c +++ b/drivers/net/ethernet/intel/e1000e/param.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c index ed70d08db5b..8dd2ff03f1f 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.c +++ b/drivers/net/ethernet/intel/e1000e/phy.c @@ -1,7 +1,7 @@ /******************************************************************************* Intel PRO/1000 Linux driver - Copyright(c) 1999 - 2011 Intel Corporation. + Copyright(c) 1999 - 2012 Intel Corporation. This program is free software; you can redistribute it and/or modify it under the terms and conditions of the GNU General Public License, -- cgit v1.2.3-70-g09d2 From 36f21f1ce419a552227b32d445e40c2d99286275 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Jan 2012 10:55:15 +0100 Subject: clocksource: cyclone: Add missing iounmap Add missing iounmap in error handling code, in a case where the function already preforms iounmap on some other execution path. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; statement S,S1; int ret; @@ e = \(ioremap\|ioremap_nocache\)(...) ... when != iounmap(e) if (<+...e...+>) S ... when any when != iounmap(e) *if (...) { ... when != iounmap(e) return ...; } ... when any iounmap(e); // Signed-off-by: Julia Lawall [fixed up subject -jstultz] Signed-off-by: John Stultz --- drivers/clocksource/cyclone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clocksource/cyclone.c b/drivers/clocksource/cyclone.c index 72f811f73e9..9e0998f2288 100644 --- a/drivers/clocksource/cyclone.c +++ b/drivers/clocksource/cyclone.c @@ -55,11 +55,11 @@ static int __init init_cyclone_clocksource(void) } /* even on 64bit systems, this is only 32bits: */ base = readl(reg); + iounmap(reg); if (!base) { printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n"); return -ENODEV; } - iounmap(reg); /* setup PMCC: */ offset = base + CYCLONE_PMCC_OFFSET; -- cgit v1.2.3-70-g09d2 From bd729d72b428261f2975360e0c117d7d7a2cd6e8 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 5 Jan 2012 15:21:19 -0800 Subject: rtc: Avoid setting alarm to a time in the past In some cases at boot up, the RTC alarm may be set in the past, but still have the enabled flag on. This was causing problems, because we would then enqueue the alarm into the timerqueue, but it would never fire. This would clog up the timerqueue and keep other alarms from working. The fix is to check the alarm against the current rtc time at boot and avoid enqueueing the alarm if it is in the past. Reported-by: NeilBrown Tested-by: NeilBrown Tested-by: Sander Eikelenboom Signed-off-by: John Stultz --- drivers/rtc/interface.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 8a1c031391d..c55a16041b6 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -380,18 +380,27 @@ EXPORT_SYMBOL_GPL(rtc_set_alarm); int rtc_initialize_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; + struct rtc_time now; err = rtc_valid_tm(&alarm->time); if (err != 0) return err; + err = rtc_read_time(rtc, &now); + if (err) + return err; + err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.period = ktime_set(0, 0); - if (alarm->enabled) { + + /* Alarm has to be enabled & in the futrure for us to enqueue it */ + if (alarm->enabled && (rtc_tm_to_ktime(now).tv64 < + rtc->aie_timer.node.expires.tv64)) { + rtc->aie_timer.enabled = 1; timerqueue_add(&rtc->timerqueue, &rtc->aie_timer.node); } -- cgit v1.2.3-70-g09d2 From 5f9679d29c7959445d4af1eb85ee55e4ebad4a93 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 9 Dec 2011 09:39:15 +1100 Subject: rtc: Expire alarms after the time is set. (v2) If the alarm time programming in the rtc is ever in the past, it won't fire, and any other alarm will be queued after it so they won't fire either. So any time that the alarm might be in the past, we need to trigger the irq handler to ensure the old alarm is cleared and the timer queue is fully in the future. This is done whenever the RTC clock is set. This is the second revision of this patch, which was earlier reverted. This version avoids the initialization problem, which is handled by a different patch. Tested-by: Sander Eikelenboom Signed-off-by: NeilBrown [Remove problematic initialization change, update commit log, also catch set_mmss case -jstultz] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index c55a16041b6..167e68a9ffd 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -73,6 +73,8 @@ int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } EXPORT_SYMBOL_GPL(rtc_set_time); @@ -112,6 +114,8 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) err = -EINVAL; mutex_unlock(&rtc->ops_lock); + /* A timer might have just expired */ + schedule_work(&rtc->irqwork); return err; } -- cgit v1.2.3-70-g09d2 From 41c7f7424259ff11009449f87c95656f69f9b186 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Tue, 22 Nov 2011 11:03:14 +0100 Subject: rtc: Disable the alarm in the hardware (v2) Currently, the RTC code does not disable the alarm in the hardware. This means that after a sequence such as the one below (the files are in the RTC sysfs), the box will boot up after 2 minutes even though we've asked for the alarm to be turned off. # echo $((`cat since_epoch`)+120) > wakealarm # echo 0 > wakealarm # poweroff Fix this by disabling the alarm when there are no timers to run. The original version of this patch was reverted. This version disables the irq directly instead of setting a disabled timer in the future. Cc: stable@kernel.org Cc: John Stultz Signed-off-by: Rabin Vincent [Merged in the second revision from Rabin] Signed-off-by: John Stultz --- drivers/rtc/interface.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index 167e68a9ffd..dc87eda6581 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -776,6 +776,14 @@ static int rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) return 0; } +static void rtc_alarm_disable(struct rtc_device *rtc) +{ + if (!rtc->ops || !rtc->ops->alarm_irq_enable) + return; + + rtc->ops->alarm_irq_enable(rtc->dev.parent, false); +} + /** * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * @rtc rtc device @@ -797,8 +805,10 @@ static void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) struct rtc_wkalrm alarm; int err; next = timerqueue_getnext(&rtc->timerqueue); - if (!next) + if (!next) { + rtc_alarm_disable(rtc); return; + } alarm.time = rtc_ktime_to_tm(next->expires); alarm.enabled = 1; err = __rtc_set_alarm(rtc, &alarm); @@ -860,7 +870,8 @@ again: err = __rtc_set_alarm(rtc, &alarm); if (err == -ETIME) goto again; - } + } else + rtc_alarm_disable(rtc); mutex_unlock(&rtc->ops_lock); } -- cgit v1.2.3-70-g09d2 From c8aa130b74cc5b112cb2b119d3b477abaaf6e5b2 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 27 Jan 2012 15:22:07 +0900 Subject: PM / Domains: Add OF support A device node pointer is added to generic pm domain structure to associate the domain with a node in the device tree. The platform code parses the device tree to find available nodes representing the generic power domain, instantiates the available domains and initializes them by calling pm_genpd_init(). Nodes representing the devices include a phandle of the power domain to which it belongs. As these devices get instantiated, the driver code checkes for availability of a power domain phandle, converts the phandle to a device node and uses the new pm_genpd_of_add_device() api to associate the device with a power domain. pm_genpd_of_add_device() runs through its list of registered power domains and matches the OF node of the domain with the one specified as the parameter. If a match is found, the device is associated with the matched domain. Cc: Rob Herring Cc: Grant Likely Signed-off-by: Thomas Abraham Acked-by: Rafael J. Wysocki Signed-off-by: Kukjin Kim --- drivers/base/power/domain.c | 32 ++++++++++++++++++++++++++++++++ include/linux/pm_domain.h | 12 ++++++++++++ 2 files changed, 44 insertions(+) (limited to 'drivers') diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 978bbf7ac6a..939109b75c9 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -1170,6 +1170,38 @@ int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, return ret; } +/** + * __pm_genpd_of_add_device - Add a device to an I/O PM domain. + * @genpd_node: Device tree node pointer representing a PM domain to which the + * the device is added to. + * @dev: Device to be added. + * @td: Set of PM QoS timing parameters to attach to the device. + */ +int __pm_genpd_of_add_device(struct device_node *genpd_node, struct device *dev, + struct gpd_timing_data *td) +{ + struct generic_pm_domain *genpd = NULL, *gpd; + + dev_dbg(dev, "%s()\n", __func__); + + if (IS_ERR_OR_NULL(genpd_node) || IS_ERR_OR_NULL(dev)) + return -EINVAL; + + mutex_lock(&gpd_list_lock); + list_for_each_entry(gpd, &gpd_list, gpd_list_node) { + if (gpd->of_node == genpd_node) { + genpd = gpd; + break; + } + } + mutex_unlock(&gpd_list_lock); + + if (!genpd) + return -EINVAL; + + return __pm_genpd_add_device(genpd, dev, td); +} + /** * pm_genpd_remove_device - Remove a device from an I/O PM domain. * @genpd: PM domain to remove the device from. diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index a03a0ad998b..e3ff87550ee 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h @@ -11,6 +11,7 @@ #include #include +#include enum gpd_status { GPD_STATE_ACTIVE = 0, /* PM domain is active */ @@ -70,6 +71,7 @@ struct generic_pm_domain { s64 break_even_ns; /* Power break even for the entire domain. */ s64 max_off_time_ns; /* Maximum allowed "suspended" time. */ ktime_t power_off_time; + struct device_node *of_node; /* Node in device tree */ }; static inline struct generic_pm_domain *pd_to_genpd(struct dev_pm_domain *pd) @@ -117,12 +119,22 @@ extern int __pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev, struct gpd_timing_data *td); +extern int __pm_genpd_of_add_device(struct device_node *genpd_node, + struct device *dev, + struct gpd_timing_data *td); + static inline int pm_genpd_add_device(struct generic_pm_domain *genpd, struct device *dev) { return __pm_genpd_add_device(genpd, dev, NULL); } +static inline int pm_genpd_of_add_device(struct device_node *genpd_node, + struct device *dev) +{ + return __pm_genpd_of_add_device(genpd_node, dev, NULL); +} + extern int pm_genpd_remove_device(struct generic_pm_domain *genpd, struct device *dev); extern int pm_genpd_add_subdomain(struct generic_pm_domain *genpd, -- cgit v1.2.3-70-g09d2 From 4512ff9f361a2786a18cb805d1f64b8d8719f121 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 22 Dec 2011 18:59:37 +0100 Subject: r8169: remove hardcoded PCIe registers accesses. Signed-off-by: Francois Romieu --- drivers/net/ethernet/realtek/r8169.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7a0c800b50a..ca86e67a33a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3824,23 +3824,21 @@ static void r8168dp_hw_jumbo_disable(struct rtl8169_private *tp) static void r8168e_hw_jumbo_enable(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; RTL_W8(MaxTxPacketSize, 0x3f); RTL_W8(Config3, RTL_R8(Config3) | Jumbo_En0); RTL_W8(Config4, RTL_R8(Config4) | 0x01); - pci_write_config_byte(pdev, 0x79, 0x20); + rtl_tx_performance_tweak(tp->pci_dev, 0x2 << MAX_READ_REQUEST_SHIFT); } static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - struct pci_dev *pdev = tp->pci_dev; RTL_W8(MaxTxPacketSize, 0x0c); RTL_W8(Config3, RTL_R8(Config3) & ~Jumbo_En0); RTL_W8(Config4, RTL_R8(Config4) & ~0x01); - pci_write_config_byte(pdev, 0x79, 0x50); + rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); } static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp) -- cgit v1.2.3-70-g09d2 From 209e5ac83b4d038ffb52cabc793f75031602a031 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 09:59:50 +0100 Subject: r8169: remove rtl8169_reinit_task. I see no good reason to keep both rtl8169_reinit_task and rtl8169_reset_task: - rtl8169_reinit_task adds a software failure point which does relate to any hardware state - they handle hardware the same. Remember that rtl8169_reinit_task was introduced in the 8169 only era to handle PCI errors way before the 8168 asked for pll and firmware ops and compare : rtl8169_reinit_task | rtl8169_reset_task ----------------------------+-------------------------- rtl8169_wait_for_quiescence | rtl8169_hw_reset rtl8169_update_counters | rtl8169_wait_for_quiescence rtl8169_hw_reset | rtl_hw_start rtl8169_rx_missed | rtl8169_check_link_status rtl_pll_power_down | rtl_request_firmware | rtl8169_init_phy | rtl_pll_power_up | rtl_hw_start | rtl8169_check_link_status | Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 34 +++------------------------------- 1 file changed, 3 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index ca86e67a33a..4f0856b8fab 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5353,34 +5353,6 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) napi_enable(&tp->napi); } -static void rtl8169_reinit_task(struct work_struct *work) -{ - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); - struct net_device *dev = tp->dev; - int ret; - - rtnl_lock(); - - if (!netif_running(dev)) - goto out_unlock; - - rtl8169_wait_for_quiescence(dev); - rtl8169_close(dev); - - ret = rtl8169_open(dev); - if (unlikely(ret < 0)) { - if (net_ratelimit()) - netif_err(tp, drv, dev, - "reinit failure (status = %d). Rescheduling\n", - ret); - rtl8169_schedule_work(dev, rtl8169_reinit_task); - } - -out_unlock: - rtnl_unlock(); -} - static void rtl8169_reset_task(struct work_struct *work) { struct rtl8169_private *tp = @@ -5616,7 +5588,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev, rtl8169_reinit_task); + rtl8169_schedule_work(dev, rtl8169_reset_task); } static void rtl8169_tx_interrupt(struct net_device *dev, @@ -5923,8 +5895,8 @@ static void rtl8169_down(struct net_device *dev) rtl8169_hw_reset(tp); /* * At this point device interrupts can not be enabled in any function, - * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task, - * rtl8169_reinit_task) and napi is disabled (rtl8169_poll). + * as netif_running is not true (rtl8169_interrupt, rtl8169_reset_task) + * and napi is disabled (rtl8169_poll). */ rtl8169_rx_missed(dev, ioaddr); -- cgit v1.2.3-70-g09d2 From 4422bcd4907d1bbb9f63e049e3c3819132c047a1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 11:23:32 +0100 Subject: r8169: stop delaying workqueue. Though motivated by the move of the driver to a single work queue of sequential events and removal of hard irq processing, it looks safe as a standalone change. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 4f0856b8fab..6d74931049f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -714,7 +714,11 @@ struct rtl8169_private { unsigned int (*phy_reset_pending)(struct rtl8169_private *tp); unsigned int (*link_ok)(void __iomem *); int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); - struct delayed_work task; + + struct { + struct work_struct work; + } wk; + unsigned features; struct mii_if_info mii; @@ -4194,7 +4198,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) rtl8168_driver_stop(tp); } - cancel_delayed_work_sync(&tp->task); + cancel_work_sync(&tp->wk.work); unregister_netdev(dev); @@ -4255,6 +4259,8 @@ static void rtl_request_firmware(struct rtl8169_private *tp) rtl_request_uncached_firmware(tp); } +static void rtl_task(struct work_struct *); + static int rtl8169_open(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -4282,7 +4288,7 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_free_rx_1; - INIT_DELAYED_WORK(&tp->task, NULL); + INIT_WORK(&tp->wk.work, rtl_task); smp_mb(); @@ -5328,12 +5334,11 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->cur_tx = tp->dirty_tx = 0; } -static void rtl8169_schedule_work(struct net_device *dev, work_func_t task) +static void rtl8169_schedule_work(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - PREPARE_DELAYED_WORK(&tp->task, task); - schedule_delayed_work(&tp->task, 4); + schedule_work(&tp->wk.work); } static void rtl8169_wait_for_quiescence(struct net_device *dev) @@ -5353,10 +5358,8 @@ static void rtl8169_wait_for_quiescence(struct net_device *dev) napi_enable(&tp->napi); } -static void rtl8169_reset_task(struct work_struct *work) +static void rtl_reset_work(struct rtl8169_private *tp) { - struct rtl8169_private *tp = - container_of(work, struct rtl8169_private, task.work); struct net_device *dev = tp->dev; int i; @@ -5385,7 +5388,7 @@ out_unlock: static void rtl8169_tx_timeout(struct net_device *dev) { - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, @@ -5588,7 +5591,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static void rtl8169_tx_interrupt(struct net_device *dev, @@ -5707,7 +5710,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (status & RxCRC) dev->stats.rx_crc_errors++; if (status & RxFOVF) { - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); dev->stats.rx_fifo_errors++; } rtl8169_mark_to_asic(desc, rx_buf_sz); @@ -5840,6 +5843,14 @@ done: return IRQ_RETVAL(handled); } +static void rtl_task(struct work_struct *work) +{ + struct rtl8169_private *tp = + container_of(work, struct rtl8169_private, wk.work); + + rtl_reset_work(tp); +} + static int rtl8169_poll(struct napi_struct *napi, int budget) { struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); @@ -6046,7 +6057,7 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - rtl8169_schedule_work(dev, rtl8169_reset_task); + rtl8169_schedule_work(dev); } static int rtl8169_resume(struct device *device) -- cgit v1.2.3-70-g09d2 From 3e990ff5f119c2f9b142f3e2548dc90ca9b7dfa1 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 12:50:01 +0100 Subject: r8169: factor out IntrMask writes. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 6d74931049f..9f9abb5d01a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1184,6 +1184,13 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } +static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrMask, bits); +} + static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -4383,6 +4390,8 @@ static void rtl_hw_start(struct net_device *dev) tp->hw_start(dev); + rtl_irq_enable(tp, tp->intr_event); + netif_start_queue(dev); } @@ -4510,9 +4519,6 @@ static void rtl_hw_start_8169(struct net_device *dev) /* no early-rx interrupts */ RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - - /* Enable all known interrupts by setting the interrupt mask. */ - RTL_W16(IntrMask, tp->intr_event); } static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits) @@ -4981,8 +4987,6 @@ static void rtl_hw_start_8168(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); - - RTL_W16(IntrMask, tp->intr_event); } #define R810X_CPCMD_QUIRK_MASK (\ @@ -5140,8 +5144,6 @@ static void rtl_hw_start_8101(struct net_device *dev) rtl_set_rx_mode(dev); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); - - RTL_W16(IntrMask, tp->intr_event); } static int rtl8169_change_mtu(struct net_device *dev, int new_mtu) -- cgit v1.2.3-70-g09d2 From 9085cdfa2f9f04d8678465748e2cced6e3f02e26 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 12:59:08 +0100 Subject: r8169: irq mask helpers. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 37 +++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 9f9abb5d01a..610f4b3655c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1184,6 +1184,29 @@ static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) return value; } +static u16 rtl_get_events(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R16(IntrStatus); +} + +static void rtl_ack_events(struct rtl8169_private *tp, u16 bits) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrStatus, bits); + mmiowb(); +} + +static void rtl_irq_disable(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + RTL_W16(IntrMask, 0); + mmiowb(); +} + static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) { void __iomem *ioaddr = tp->mmio_addr; @@ -1195,8 +1218,8 @@ static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - RTL_W16(IntrMask, 0x0000); - RTL_W16(IntrStatus, tp->intr_event); + rtl_irq_disable(tp); + rtl_ack_events(tp, tp->intr_event); RTL_R8(ChipCmd); } @@ -4057,11 +4080,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_init_rxcfg(tp); - RTL_W16(IntrMask, 0x0000); + rtl_irq_disable(tp); rtl_hw_reset(tp); - RTL_W16(IntrStatus, 0xffff); + rtl_ack_events(tp, 0xffff); pci_set_master(pdev); @@ -5775,12 +5798,12 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; int handled = 0; - int status; + u16 status; /* loop handling interrupts until we have no new ones or * we hit a invalid/hotplug case. */ - status = RTL_R16(IntrStatus); + status = rtl_get_events(tp); while (status && status != 0xffff) { status &= tp->intr_event; if (!status) @@ -5839,7 +5862,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) */ RTL_W16(IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status); - status = RTL_R16(IntrStatus); + status = rtl_get_events(tp); } done: return IRQ_RETVAL(handled); -- cgit v1.2.3-70-g09d2 From 9aa507505cdcd10b7390398790f013374ee74a26 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 27 Jan 2012 16:10:22 +0100 Subject: regmap: Add support for 2/6 register formating Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 2d71aeae310..b4475d87f4a 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -76,6 +76,14 @@ static bool regmap_volatile_range(struct regmap *map, unsigned int reg, return true; } +static void regmap_format_2_6_write(struct regmap *map, + unsigned int reg, unsigned int val) +{ + u8 *out = map->work_buf; + + *out = (reg << 6) | val; +} + static void regmap_format_4_12_write(struct regmap *map, unsigned int reg, unsigned int val) { @@ -180,6 +188,16 @@ struct regmap *regmap_init(struct device *dev, } switch (config->reg_bits) { + case 2: + switch (config->val_bits) { + case 6: + map->format.format_write = regmap_format_2_6_write; + break; + default: + goto err_map; + } + break; + case 4: switch (config->val_bits) { case 12: -- cgit v1.2.3-70-g09d2 From 1e874e041fc7c222cbd85b20c4406070be1f687a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Fri, 27 Jan 2012 15:05:38 +0100 Subject: r8169: missing barriers. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 610f4b3655c..8dd13f5a920 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5552,7 +5552,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); - smp_rmb(); + smp_mb(); if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); } @@ -5653,7 +5653,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev, if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; - smp_wmb(); + smp_mb(); if (netif_queue_stopped(dev) && (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { netif_wake_queue(dev); @@ -5664,7 +5664,6 @@ static void rtl8169_tx_interrupt(struct net_device *dev, * of start_xmit activity is detected (if it is not detected, * it is slow enough). -- FR */ - smp_rmb(); if (tp->cur_tx != dirty_tx) RTL_W8(TxPoll, NPQ); } -- cgit v1.2.3-70-g09d2 From c1288b1278d00169e12495eb53ad128e09560b69 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Jan 2012 09:29:57 +0100 Subject: mac80211: make beacon filtering per virtual interface Due to firmware limitations, we may not be able to support beacon filtering on all virtual interfaces. To allow this in mac80211, introduce per-interface driver capability flags that the driver sets when an interface is added. Signed-off-by: Johannes Berg Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/p54/main.c | 3 ++- drivers/net/wireless/rtlwifi/base.c | 1 - drivers/net/wireless/rtlwifi/core.c | 2 ++ drivers/net/wireless/wl1251/main.c | 3 ++- drivers/net/wireless/wl12xx/main.c | 3 ++- include/net/mac80211.h | 29 ++++++++++++++++++++--------- net/mac80211/debugfs.c | 2 -- net/mac80211/mlme.c | 2 +- 8 files changed, 29 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c index af2ca1a9c7d..40f4eb7da7b 100644 --- a/drivers/net/wireless/p54/main.c +++ b/drivers/net/wireless/p54/main.c @@ -228,6 +228,8 @@ static int p54_add_interface(struct ieee80211_hw *dev, { struct p54_common *priv = dev->priv; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + mutex_lock(&priv->conf_mutex); if (priv->mode != NL80211_IFTYPE_MONITOR) { mutex_unlock(&priv->conf_mutex); @@ -734,7 +736,6 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len) IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_REPORTS_TX_ACK_STATUS; dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 6f80142580f..ff3e393bc10 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -309,7 +309,6 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw) /* <5> set hw caps */ hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_RX_INCLUDES_FCS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_AMPDU_AGGREGATION | IEEE80211_HW_CONNECTION_MONITOR | /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */ diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index d6e37e6a1d5..0ee01ab2e4f 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -112,6 +112,8 @@ static int rtl_op_add_interface(struct ieee80211_hw *hw, struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); int err = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + if (mac->vif) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "vif has been set!! mac->vif = 0x%p\n", mac->vif); diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index ba3268ea81f..86540db6f1a 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -514,6 +514,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, struct wl1251 *wl = hw->priv; int ret = 0; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); @@ -1338,7 +1340,6 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_SUPPORTS_CQM_RSSI; diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index d5f55a149de..afc5381f287 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2060,6 +2060,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, u8 role_type; bool booted = false; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", ieee80211_vif_type_p2p(vif), vif->addr); @@ -4898,7 +4900,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) wl->hw->max_listen_interval = wl->conf.conn.max_listen_interval; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | - IEEE80211_HW_BEACON_FILTER | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d49928ba5d0..ae8db247bde 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -851,6 +851,16 @@ struct ieee80211_channel_switch { u8 count; }; +/** + * enum ieee80211_vif_flags - virtual interface flags + * + * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering + * on this virtual interface to avoid unnecessary CPU wakeups + */ +enum ieee80211_vif_flags { + IEEE80211_VIF_BEACON_FILTER = BIT(0), +}; + /** * struct ieee80211_vif - per-interface data * @@ -863,6 +873,10 @@ struct ieee80211_channel_switch { * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively + * @driver_flags: flags/capabilities the driver has for this interface, + * these need to be set (or cleared) when the interface is added + * or, if supported by the driver, the interface type is changed + * at runtime, mac80211 will never touch this field * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). */ @@ -871,6 +885,7 @@ struct ieee80211_vif { struct ieee80211_bss_conf bss_conf; u8 addr[ETH_ALEN]; bool p2p; + u32 driver_flags; /* must be last */ u8 drv_priv[0] __attribute__((__aligned__(sizeof(void *)))); }; @@ -1079,10 +1094,6 @@ enum sta_notify_cmd { * @IEEE80211_HW_MFP_CAPABLE: * Hardware supports management frame protection (MFP, IEEE 802.11w). * - * @IEEE80211_HW_BEACON_FILTER: - * Hardware supports dropping of irrelevant beacon frames to - * avoid waking up cpu. - * * @IEEE80211_HW_SUPPORTS_STATIC_SMPS: * Hardware supports static spatial multiplexing powersave, * ie. can turn off all but one chain even on HT connections @@ -1150,7 +1161,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_PS_NULLFUNC_STACK = 1<<11, IEEE80211_HW_SUPPORTS_DYNAMIC_PS = 1<<12, IEEE80211_HW_MFP_CAPABLE = 1<<13, - IEEE80211_HW_BEACON_FILTER = 1<<14, + /* reuse bit 14 */ IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, @@ -1446,8 +1457,8 @@ void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); * way the host will only receive beacons where some relevant information * (for example ERP protection or WMM settings) have changed. * - * Beacon filter support is advertised with the %IEEE80211_HW_BEACON_FILTER - * hardware capability. The driver needs to enable beacon filter support + * Beacon filter support is advertised with the %IEEE80211_VIF_BEACON_FILTER + * interface capability. The driver needs to enable beacon filter support * whenever power save is enabled, that is %IEEE80211_CONF_PS is set. When * power save is enabled, the stack will not check for beacon loss and the * driver needs to notify about loss of beacons with ieee80211_beacon_loss(). @@ -3316,7 +3327,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER and + * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER and * %IEEE80211_CONF_PS is set, the driver needs to inform whenever the * hardware is not receiving beacons with this function. */ @@ -3327,7 +3338,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif); * * @vif: &struct ieee80211_vif pointer from the add_interface callback. * - * When beacon filtering is enabled with %IEEE80211_HW_BEACON_FILTER, and + * When beacon filtering is enabled with %IEEE80211_VIF_BEACON_FILTER, and * %IEEE80211_CONF_PS and %IEEE80211_HW_CONNECTION_MONITOR are set, the driver * needs to inform if the connection to the AP has been lost. * diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 90baea53e7c..e8868dae1c0 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -247,8 +247,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_DYNAMIC_PS\n"); if (local->hw.flags & IEEE80211_HW_MFP_CAPABLE) sf += snprintf(buf + sf, mxln - sf, "MFP_CAPABLE\n"); - if (local->hw.flags & IEEE80211_HW_BEACON_FILTER) - sf += snprintf(buf + sf, mxln - sf, "BEACON_FILTER\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_STATIC_SMPS) sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_STATIC_SMPS\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 95d3964fc08..b51eb49d852 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -127,7 +127,7 @@ static void run_again(struct ieee80211_if_managed *ifmgd, void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) { - if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER) + if (sdata->vif.driver_flags & IEEE80211_VIF_BEACON_FILTER) return; mod_timer(&sdata->u.mgd.bcn_mon_timer, -- cgit v1.2.3-70-g09d2 From ea086359a63bd0dd85c1d784d0425340649613fa Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 19 Jan 2012 09:29:58 +0100 Subject: mac80211: make CQM RSSI support per virtual interface Similar to the previous beacon filtering patch, make CQM RSSI support depend on the flags that the driver set for virtual interfaces. Signed-off-by: Johannes Berg Acked-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl1251/main.c | 6 +++--- drivers/net/wireless/wl12xx/main.c | 4 ++-- include/net/mac80211.h | 14 +++++++------- net/mac80211/cfg.c | 10 ++-------- net/mac80211/debugfs.c | 2 -- net/mac80211/mlme.c | 4 ++-- 6 files changed, 16 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/wl1251/main.c b/drivers/net/wireless/wl1251/main.c index 86540db6f1a..41302c7b1ad 100644 --- a/drivers/net/wireless/wl1251/main.c +++ b/drivers/net/wireless/wl1251/main.c @@ -514,7 +514,8 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw, struct wl1251 *wl = hw->priv; int ret = 0; - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", vif->type, vif->addr); @@ -1340,8 +1341,7 @@ int wl1251_init_ieee80211(struct wl1251 *wl) wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | - IEEE80211_HW_SUPPORTS_UAPSD | - IEEE80211_HW_SUPPORTS_CQM_RSSI; + IEEE80211_HW_SUPPORTS_UAPSD; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC); diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c index afc5381f287..f8748cedbae 100644 --- a/drivers/net/wireless/wl12xx/main.c +++ b/drivers/net/wireless/wl12xx/main.c @@ -2060,7 +2060,8 @@ static int wl1271_op_add_interface(struct ieee80211_hw *hw, u8 role_type; bool booted = false; - vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER; + vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER | + IEEE80211_VIF_SUPPORTS_CQM_RSSI; wl1271_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM", ieee80211_vif_type_p2p(vif), vif->addr); @@ -4904,7 +4905,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl) IEEE80211_HW_SUPPORTS_UAPSD | IEEE80211_HW_HAS_RATE_CONTROL | IEEE80211_HW_CONNECTION_MONITOR | - IEEE80211_HW_SUPPORTS_CQM_RSSI | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SPECTRUM_MGMT | IEEE80211_HW_AP_LINK_PS | diff --git a/include/net/mac80211.h b/include/net/mac80211.h index ae8db247bde..65018587684 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -856,9 +856,14 @@ struct ieee80211_channel_switch { * * @IEEE80211_VIF_BEACON_FILTER: the device performs beacon filtering * on this virtual interface to avoid unnecessary CPU wakeups + * @IEEE80211_VIF_SUPPORTS_CQM_RSSI: the device can do connection quality + * monitoring on this virtual interface -- i.e. it can monitor + * connection quality related parameters, such as the RSSI level and + * provide notifications if configured trigger levels are reached. */ enum ieee80211_vif_flags { IEEE80211_VIF_BEACON_FILTER = BIT(0), + IEEE80211_VIF_SUPPORTS_CQM_RSSI = BIT(1), }; /** @@ -1119,11 +1124,6 @@ enum sta_notify_cmd { * When this flag is set, signaling beacon-loss will cause an immediate * change to disassociated state. * - * @IEEE80211_HW_SUPPORTS_CQM_RSSI: - * Hardware can do connection quality monitoring - i.e. it can monitor - * connection quality related parameters, such as the RSSI level and - * provide notifications if configured trigger levels are reached. - * * @IEEE80211_HW_NEED_DTIM_PERIOD: * This device needs to know the DTIM period for the BSS before * associating. @@ -1167,7 +1167,7 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_UAPSD = 1<<17, IEEE80211_HW_REPORTS_TX_ACK_STATUS = 1<<18, IEEE80211_HW_CONNECTION_MONITOR = 1<<19, - IEEE80211_HW_SUPPORTS_CQM_RSSI = 1<<20, + /* reuse bit 20 */ IEEE80211_HW_SUPPORTS_PER_STA_GTK = 1<<21, IEEE80211_HW_AP_LINK_PS = 1<<22, IEEE80211_HW_TX_AMPDU_SETUP_IN_HW = 1<<23, @@ -3408,7 +3408,7 @@ void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif); * @rssi_event: the RSSI trigger event type * @gfp: context flags * - * When the %IEEE80211_HW_SUPPORTS_CQM_RSSI is set, and a connection quality + * When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality * monitoring is configured with an rssi threshold, the driver will inform * whenever the rssi level reaches the threshold. */ diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index d86730fe75c..74c9301681e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1873,7 +1873,6 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, s32 rssi_thold, u32 rssi_hyst) { struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_vif *vif = &sdata->vif; struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; @@ -1884,14 +1883,9 @@ static int ieee80211_set_cqm_rssi_config(struct wiphy *wiphy, bss_conf->cqm_rssi_thold = rssi_thold; bss_conf->cqm_rssi_hyst = rssi_hyst; - if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { - if (sdata->vif.type != NL80211_IFTYPE_STATION) - return -EOPNOTSUPP; - return 0; - } - /* tell the driver upon association, unless already associated */ - if (sdata->u.mgd.associated) + if (sdata->u.mgd.associated && + sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI) ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_CQM); return 0; diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index e8868dae1c0..affe64be909 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c @@ -257,8 +257,6 @@ static ssize_t hwflags_read(struct file *file, char __user *user_buf, sf += snprintf(buf + sf, mxln - sf, "REPORTS_TX_ACK_STATUS\n"); if (local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) sf += snprintf(buf + sf, mxln - sf, "CONNECTION_MONITOR\n"); - if (local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) - sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_CQM_RSSI\n"); if (local->hw.flags & IEEE80211_HW_SUPPORTS_PER_STA_GTK) sf += snprintf(buf + sf, mxln - sf, "SUPPORTS_PER_STA_GTK\n"); if (local->hw.flags & IEEE80211_HW_AP_LINK_PS) diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index b51eb49d852..de3268c7be1 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1043,7 +1043,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, bss_info_changed |= BSS_CHANGED_BSSID; /* Tell the driver to monitor connection quality (if supported) */ - if ((local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI) && + if (sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI && bss_conf->cqm_rssi_thold) bss_info_changed |= BSS_CHANGED_CQM; @@ -1882,7 +1882,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, if (bss_conf->cqm_rssi_thold && ifmgd->count_beacon_signal >= IEEE80211_SIGNAL_AVE_MIN_COUNT && - !(local->hw.flags & IEEE80211_HW_SUPPORTS_CQM_RSSI)) { + !(sdata->vif.driver_flags & IEEE80211_VIF_SUPPORTS_CQM_RSSI)) { int sig = ifmgd->ave_beacon_signal / 16; int last_event = ifmgd->last_cqm_event_signal; int thold = bss_conf->cqm_rssi_thold; -- cgit v1.2.3-70-g09d2 From 67e43de6dbc9caf52fa7bcf4c813fd088ba6fbfc Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 21 Jan 2012 16:59:10 +0100 Subject: carl9170: allow users to lower output power level This patch implements a simple way of reducing the output power of the device by a configurable upper limit. Requested-by: Harshal Chhaya Signed-off-by: Christian Lamparter Signed-off-by: John W. Linville --- drivers/net/wireless/ath/carl9170/carl9170.h | 1 + drivers/net/wireless/ath/carl9170/mac.c | 35 +++++++++++++++++++++++++++ drivers/net/wireless/ath/carl9170/main.c | 11 +++++---- drivers/net/wireless/ath/carl9170/phy.c | 36 +++++----------------------- drivers/net/wireless/ath/carl9170/tx.c | 2 ++ 5 files changed, 50 insertions(+), 35 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index f0f44c30b2f..0cea20e3e25 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -559,6 +559,7 @@ int carl9170_set_hwretry_limit(struct ar9170 *ar, const u32 max_retry); int carl9170_upload_key(struct ar9170 *ar, const u8 id, const u8 *mac, const u8 ktype, const u8 keyidx, const u8 *keydata, const int keylen); int carl9170_disable_key(struct ar9170 *ar, const u8 id); +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel); /* RX */ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len); diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index dfda9197099..53415bfd8be 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -485,3 +485,38 @@ int carl9170_disable_key(struct ar9170 *ar, const u8 id) return carl9170_exec_cmd(ar, CARL9170_CMD_DKEY, sizeof(key), (u8 *)&key, 0, NULL); } + +int carl9170_set_mac_tpc(struct ar9170 *ar, struct ieee80211_channel *channel) +{ + unsigned int power, chains; + + if (ar->eeprom.tx_mask != 1) + chains = AR9170_TX_PHY_TXCHAIN_2; + else + chains = AR9170_TX_PHY_TXCHAIN_1; + + switch (channel->band) { + case IEEE80211_BAND_2GHZ: + power = ar->power_2G_ofdm[0] & 0x3f; + break; + case IEEE80211_BAND_5GHZ: + power = ar->power_5G_leg[0] & 0x3f; + break; + default: + BUG_ON(1); + } + + power = min_t(unsigned int, power, ar->hw->conf.power_level * 2); + + carl9170_regwrite_begin(ar); + carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, + 0x3c1e | power << 20 | chains << 26); + carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, + power << 5 | chains << 11 | + power << 21 | chains << 27); + carl9170_regwrite_finish(); + return carl9170_regwrite_result(); +} diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 6ee7c55f75a..8d2523b3f72 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -853,11 +853,6 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } - if (changed & IEEE80211_CONF_CHANGE_POWER) { - /* TODO */ - err = 0; - } - if (changed & IEEE80211_CONF_CHANGE_SMPS) { /* TODO */ err = 0; @@ -891,6 +886,12 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed) goto out; } + if (changed & IEEE80211_CONF_CHANGE_POWER) { + err = carl9170_set_mac_tpc(ar, ar->hw->conf.channel); + if (err) + goto out; + } + out: mutex_unlock(&ar->mutex); return err; diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c index 472efc7e340..b72c09cf43a 100644 --- a/drivers/net/wireless/ath/carl9170/phy.c +++ b/drivers/net/wireless/ath/carl9170/phy.c @@ -1426,15 +1426,15 @@ static void carl9170_calc_ctl(struct ar9170 *ar, u32 freq, enum carl9170_bw bw) #undef EDGES } -static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, - enum carl9170_bw bw) +static void carl9170_set_power_cal(struct ar9170 *ar, u32 freq, + enum carl9170_bw bw) { struct ar9170_calibration_target_power_legacy *ctpl; struct ar9170_calibration_target_power_ht *ctph; u8 *ctpres; int ntargets; int idx, i, n; - u8 ackpower, ackchains, f; + u8 f; u8 pwr_freqs[AR5416_MAX_NUM_TGT_PWRS]; if (freq < 3000) @@ -1523,32 +1523,6 @@ static int carl9170_set_power_cal(struct ar9170 *ar, u32 freq, /* calc. conformance test limits and apply to ar->power*[] */ carl9170_calc_ctl(ar, freq, bw); - - /* set ACK/CTS TX power */ - carl9170_regwrite_begin(ar); - - if (ar->eeprom.tx_mask != 1) - ackchains = AR9170_TX_PHY_TXCHAIN_2; - else - ackchains = AR9170_TX_PHY_TXCHAIN_1; - - if (freq < 3000) - ackpower = ar->power_2G_ofdm[0] & 0x3f; - else - ackpower = ar->power_5G_leg[0] & 0x3f; - - carl9170_regwrite(AR9170_MAC_REG_ACK_TPC, - 0x3c1e | ackpower << 20 | ackchains << 26); - carl9170_regwrite(AR9170_MAC_REG_RTS_CTS_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite(AR9170_MAC_REG_CFEND_QOSNULL_TPC, - ackpower << 5 | ackchains << 11 | - ackpower << 21 | ackchains << 27); - - carl9170_regwrite_finish(); - return carl9170_regwrite_result(); } int carl9170_get_noisefloor(struct ar9170 *ar) @@ -1712,7 +1686,9 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, if (err) return err; - err = carl9170_set_power_cal(ar, channel->center_freq, bw); + carl9170_set_power_cal(ar, channel->center_freq, bw); + + err = carl9170_set_mac_tpc(ar, channel); if (err) return err; diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index d19a9ee9d05..771e1a9294c 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c @@ -719,6 +719,8 @@ static void carl9170_tx_rate_tpc_chains(struct ar9170 *ar, else *chains = AR9170_TX_PHY_TXCHAIN_2; } + + *tpc = min_t(unsigned int, *tpc, ar->hw->conf.power_level * 2); } static __le32 carl9170_tx_physet(struct ar9170 *ar, -- cgit v1.2.3-70-g09d2 From 0c17cf962d716ea7557d18679cc98b3a43efb46d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:06 +0100 Subject: rt2800usb: initialize H2M_INT_SRC register Ralink USB driver initialize H2M_INT_SRC to 0 after firmware load, and never touch this register later. It is not touched at all by Ralink PCI driver. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 22a1a8fc6e0..3e194b7e9bb 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -448,6 +448,8 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, */ rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0); rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0); + if (rt2x00_is_usb(rt2x00dev)) + rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0); msleep(1); return 0; -- cgit v1.2.3-70-g09d2 From 4ed1dd2a7ec880b301beb61cbc1e08811ec340e4 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:07 +0100 Subject: rt2800: disable DMA after firmware load We can receive frames just after firmware load with current code, so disable DMA just after firmware is loaded, not before. Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800lib.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c index 3e194b7e9bb..165535cc507 100644 --- a/drivers/net/wireless/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/rt2x00/rt2800lib.c @@ -411,18 +411,6 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, rt2800_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000002); } - /* - * Disable DMA, will be reenabled later when enabling - * the radio. - */ - rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_RX_DMA_BUSY, 0); - rt2x00_set_field32(®, WPDMA_GLO_CFG_TX_WRITEBACK_DONE, 1); - rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); - /* * Write firmware to the device. */ @@ -443,6 +431,15 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev, return -EBUSY; } + /* + * Disable DMA, will be reenabled later when enabling + * the radio. + */ + rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, ®); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_TX_DMA, 0); + rt2x00_set_field32(®, WPDMA_GLO_CFG_ENABLE_RX_DMA, 0); + rt2800_register_write(rt2x00dev, WPDMA_GLO_CFG, reg); + /* * Initialize firmware. */ -- cgit v1.2.3-70-g09d2 From 2a48e8ae113be506a7169d50c0b8fcb3ab0c462a Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:08 +0100 Subject: rt2800: zero MAC_SYS_CTRL bits during BBP and MAC reset Zero all other bits than RESET_CSR and RESET_BBP when want to do the reset, that the vendor driver behaviour. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800pci.c | 2 +- drivers/net/wireless/rt2x00/rt2800usb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index dc88baefa72..4e985026985 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -489,7 +489,7 @@ static int rt2800pci_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00pci_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2x00pci_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00pci_register_write(rt2x00dev, MAC_SYS_CTRL, reg); diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 262ee9eefb6..425267af610 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -228,7 +228,7 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - rt2x00usb_register_read(rt2x00dev, MAC_SYS_CTRL, ®); + reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); rt2x00usb_register_write(rt2x00dev, MAC_SYS_CTRL, reg); -- cgit v1.2.3-70-g09d2 From 10ef6a8f1567739192c29f11375556ce0d53ec74 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Tue, 24 Jan 2012 14:09:09 +0100 Subject: rt2800usb: remove PWR_PIN_CFG=0x3 during init This seems to be only needed as workaround for hardware problem on PCI devices. Acked-by: Helmut Schaa Acked-by: Ivo van Doorn Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2800usb.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c index 425267af610..f0074bcee7c 100644 --- a/drivers/net/wireless/rt2x00/rt2800usb.c +++ b/drivers/net/wireless/rt2x00/rt2800usb.c @@ -226,8 +226,6 @@ static int rt2800usb_init_registers(struct rt2x00_dev *rt2x00dev) rt2x00usb_register_read(rt2x00dev, PBF_SYS_CTRL, ®); rt2x00usb_register_write(rt2x00dev, PBF_SYS_CTRL, reg & ~0x00002000); - rt2x00usb_register_write(rt2x00dev, PWR_PIN_CFG, 0x00000003); - reg = 0; rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_CSR, 1); rt2x00_set_field32(®, MAC_SYS_CTRL_RESET_BBP, 1); -- cgit v1.2.3-70-g09d2 From 2690e1bb35e97a3b15f0064e9176cd2ec61c2511 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Tue, 24 Jan 2012 20:50:24 -0800 Subject: mwifiex: pass priv pointer instead of adapter Pass mwifiex_private pointer directly to wmm_add_buf_txqueue() instead of passing adapter and then deriving priv again in mwifiex_get_priv_by_id(). This reduces a 'for' loop in TX path. Signed-off-by: Avinash Patil Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/main.c | 2 +- drivers/net/wireless/mwifiex/wmm.c | 6 ++---- drivers/net/wireless/mwifiex/wmm.h | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c index 1a0775d19ad..80e44566bf6 100644 --- a/drivers/net/wireless/mwifiex/main.c +++ b/drivers/net/wireless/mwifiex/main.c @@ -462,7 +462,7 @@ mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) tx_info->bss_type = priv->bss_type; mwifiex_fill_buffer(skb); - mwifiex_wmm_add_buf_txqueue(priv->adapter, skb); + mwifiex_wmm_add_buf_txqueue(priv, skb); atomic_inc(&priv->adapter->tx_pending); if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) { diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c index e6a2cb127d2..75f79ef9f6c 100644 --- a/drivers/net/wireless/mwifiex/wmm.c +++ b/drivers/net/wireless/mwifiex/wmm.c @@ -599,12 +599,10 @@ mwifiex_is_ralist_valid(struct mwifiex_private *priv, * is queued at the list tail. */ void -mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, +mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, struct sk_buff *skb) { - struct mwifiex_txinfo *tx_info = MWIFIEX_SKB_TXCB(skb); - struct mwifiex_private *priv = mwifiex_get_priv_by_id(adapter, - tx_info->bss_num, tx_info->bss_type); + struct mwifiex_adapter *adapter = priv->adapter; u32 tid; struct mwifiex_ra_list_tbl *ra_list; u8 ra[ETH_ALEN], tid_down; diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h index fcea1f68792..ec839952d2e 100644 --- a/drivers/net/wireless/mwifiex/wmm.h +++ b/drivers/net/wireless/mwifiex/wmm.h @@ -80,8 +80,8 @@ mwifiex_wmm_is_ra_list_empty(struct list_head *ra_list_hhead) return true; } -void mwifiex_wmm_add_buf_txqueue(struct mwifiex_adapter *adapter, - struct sk_buff *skb); +void mwifiex_wmm_add_buf_txqueue(struct mwifiex_private *priv, + struct sk_buff *skb); void mwifiex_ralist_add(struct mwifiex_private *priv, u8 *ra); int mwifiex_wmm_lists_empty(struct mwifiex_adapter *adapter); -- cgit v1.2.3-70-g09d2 From c4f3b9725ed476adbcaf1c49d882ab541bc4214c Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Tue, 24 Jan 2012 20:50:25 -0800 Subject: mwifiex: update BSS parameters in dump_station_info() This enables user to check beacon interval, DTIM period, short slot time and short preamble information using "iw dev mlan0 link" command when station is in connected state. Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cfg80211.c | 17 +++++++++++++++++ drivers/net/wireless/mwifiex/main.h | 1 + drivers/net/wireless/mwifiex/scan.c | 6 ++++++ 3 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c index 00f10059ecb..6fef4925d13 100644 --- a/drivers/net/wireless/mwifiex/cfg80211.c +++ b/drivers/net/wireless/mwifiex/cfg80211.c @@ -557,6 +557,23 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, /* bit rate is in 500 kb/s units. Convert it to 100kb/s units */ sinfo->txrate.legacy = rate.rate * 5; + if (priv->bss_mode == NL80211_IFTYPE_STATION) { + sinfo->filled |= STATION_INFO_BSS_PARAM; + sinfo->bss_param.flags = 0; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_PREAMBLE) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_PREAMBLE; + if (priv->curr_bss_params.bss_descriptor.cap_info_bitmap & + WLAN_CAPABILITY_SHORT_SLOT_TIME) + sinfo->bss_param.flags |= + BSS_PARAM_FLAGS_SHORT_SLOT_TIME; + sinfo->bss_param.dtim_period = + priv->curr_bss_params.bss_descriptor.dtim_period; + sinfo->bss_param.beacon_interval = + priv->curr_bss_params.bss_descriptor.beacon_period; + } + return ret; } diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 6712ea89ef7..3dc0f721c1d 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -249,6 +249,7 @@ struct mwifiex_bssdescriptor { u32 channel; u32 freq; u16 beacon_period; + u8 dtim_period; u8 erp_flags; u32 bss_mode; u8 supported_rates[MWIFIEX_SUPPORTED_RATES]; diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 98f1ca9cd6d..135208596af 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1086,6 +1086,7 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, struct ieee_types_vendor_specific *vendor_ie; const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 }; const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 }; + struct ieee80211_tim_ie *tim_ie; found_data_rate_ie = false; rate_size = 0; @@ -1258,6 +1259,11 @@ mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, sizeof(struct ieee_types_header) - bss_entry->beacon_buf); break; + case WLAN_EID_TIM: + tim_ie = (void *) (current_ptr + + sizeof(struct ieee_types_header)); + bss_entry->dtim_period = tim_ie->dtim_period; + break; default: break; } -- cgit v1.2.3-70-g09d2 From ff7e9f99f7effb385a9be2f7198743c1ad2bb126 Mon Sep 17 00:00:00 2001 From: Yogesh Ashok Powar Date: Fri, 27 Jan 2012 16:08:27 +0530 Subject: mwl8k: Configuring correct MAC address in broadcast key While configuring the broadcast key in the hardware, in multi-BSS environment, BSSes other than first were incorrectly configured with the MAC address of first BSS. Fixing it with correct MAC addresses. Signed-off-by: Yogesh Ashok Powar Signed-off-by: John W. Linville --- drivers/net/wireless/mwl8k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c index dd5aeaff44b..fd125473be7 100644 --- a/drivers/net/wireless/mwl8k.c +++ b/drivers/net/wireless/mwl8k.c @@ -4093,7 +4093,7 @@ static int mwl8k_set_key(struct ieee80211_hw *hw, return -EOPNOTSUPP; if (sta == NULL) - addr = hw->wiphy->perm_addr; + addr = vif->addr; else addr = sta->addr; -- cgit v1.2.3-70-g09d2 From da78dbff2e05630921c551dbbc70a4b7981a8fff Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Thu, 26 Jan 2012 14:18:23 +0100 Subject: r8169: remove work from irq handler. The irq handler was a mess. See 7ab87ff4c770eed71e3777936299292739fcd0fe ("via-rhine: move work from irq handler to softirq and beyond") for similar changes. One can notice: - all non-napi tasks are explicitely scheduled trough a single work queue. - hiding software tx queue start behind the rtl_hw_start method is mildly natural. Move it in the caller where needed. - as can be seen from the heavy use of bh disabling locks, the driver is not safe for irq context messages with netconsole. It is still quite usable for general messaging though. Tested ok with concurrent registers dump (ethtool -d) + background traffic + "echo t > /proc/sysrq-trigger". Tested with old PCI chipset, PCIe 8168 and 810x: - XID 0c900800 RTL8168evl/8111evl - XID 18000000 RTL8168b/8111b - XID 98000000 RTL8169sc/8110sc - XID 083000c0 RTL8168d/8111d - XID 081000c0 RTL8168d/8111d - XID 00b00000 RTL8105e - XID 04a00000 RTL8102e As a side note, the comments in f11a377b3f4e897d11f0e8d1fc688667e2f19708 ("r8169: avoid losing MSI interrupts") does not seem completely clear: if I hack the driver further to stop acking the irq link event bit, MSI interrupts keep being delivered (RTL8168b/8111b, XID 18000000). Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 449 ++++++++++++++++++----------------- 1 file changed, 231 insertions(+), 218 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 8dd13f5a920..d039d39963a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -667,6 +667,13 @@ struct rtl8169_counters { __le16 tx_underun; }; +enum rtl_flag { + RTL_FLAG_TASK_SLOW_PENDING, + RTL_FLAG_TASK_RESET_PENDING, + RTL_FLAG_TASK_PHY_PENDING, + RTL_FLAG_MAX +}; + struct rtl8169_private { void __iomem *mmio_addr; /* memory map physical address */ struct pci_dev *pci_dev; @@ -688,9 +695,8 @@ struct rtl8169_private { struct ring_info tx_skb[NUM_TX_DESC]; /* Tx data buffers */ struct timer_list timer; u16 cp_cmd; - u16 intr_event; - u16 napi_event; - u16 intr_mask; + + u16 event_slow; struct mdio_ops { void (*write)(void __iomem *, int, int); @@ -716,7 +722,10 @@ struct rtl8169_private { int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd); struct { + DECLARE_BITMAP(flags, RTL_FLAG_MAX); + struct mutex mutex; struct work_struct work; + bool enabled; } wk; unsigned features; @@ -768,13 +777,20 @@ static int rtl8169_close(struct net_device *dev); static void rtl_set_rx_mode(struct net_device *dev); static void rtl8169_tx_timeout(struct net_device *dev); static struct net_device_stats *rtl8169_get_stats(struct net_device *dev); -static int rtl8169_rx_interrupt(struct net_device *, struct rtl8169_private *, - void __iomem *, u32 budget); static int rtl8169_change_mtu(struct net_device *dev, int new_mtu); -static void rtl8169_down(struct net_device *dev); static void rtl8169_rx_clear(struct rtl8169_private *tp); static int rtl8169_poll(struct napi_struct *napi, int budget); +static void rtl_lock_work(struct rtl8169_private *tp) +{ + mutex_lock(&tp->wk.mutex); +} + +static void rtl_unlock_work(struct rtl8169_private *tp) +{ + mutex_unlock(&tp->wk.mutex); +} + static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) { int cap = pci_pcie_cap(pdev); @@ -1214,12 +1230,21 @@ static void rtl_irq_enable(struct rtl8169_private *tp, u16 bits) RTL_W16(IntrMask, bits); } +#define RTL_EVENT_NAPI_RX (RxOK | RxErr) +#define RTL_EVENT_NAPI_TX (TxOK | TxErr) +#define RTL_EVENT_NAPI (RTL_EVENT_NAPI_RX | RTL_EVENT_NAPI_TX) + +static void rtl_irq_enable_all(struct rtl8169_private *tp) +{ + rtl_irq_enable(tp, RTL_EVENT_NAPI | tp->event_slow); +} + static void rtl8169_irq_mask_and_ack(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; rtl_irq_disable(tp); - rtl_ack_events(tp, tp->intr_event); + rtl_ack_events(tp, RTL_EVENT_NAPI | tp->event_slow); RTL_R8(ChipCmd); } @@ -1310,9 +1335,6 @@ static void __rtl8169_check_link_status(struct net_device *dev, struct rtl8169_private *tp, void __iomem *ioaddr, bool pm) { - unsigned long flags; - - spin_lock_irqsave(&tp->lock, flags); if (tp->link_ok(ioaddr)) { rtl_link_chg_patch(tp); /* This is to cancel a scheduled suspend if there's one. */ @@ -1327,7 +1349,6 @@ static void __rtl8169_check_link_status(struct net_device *dev, if (pm) pm_schedule_suspend(&tp->pci_dev->dev, 5000); } - spin_unlock_irqrestore(&tp->lock, flags); } static void rtl8169_check_link_status(struct net_device *dev, @@ -1370,12 +1391,12 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); wol->supported = WAKE_ANY; wol->wolopts = __rtl8169_get_wol(tp); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); } static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) @@ -1412,14 +1433,15 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) { struct rtl8169_private *tp = netdev_priv(dev); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); if (wol->wolopts) tp->features |= RTL_FEATURE_WOL; else tp->features &= ~RTL_FEATURE_WOL; __rtl8169_set_wol(tp, wol->wolopts); - spin_unlock_irq(&tp->lock); + + rtl_unlock_work(tp); device_set_wakeup_enable(&tp->pci_dev->dev, wol->wolopts); @@ -1574,15 +1596,14 @@ out: static int rtl8169_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; int ret; del_timer_sync(&tp->timer); - spin_lock_irqsave(&tp->lock, flags); + rtl_lock_work(tp); ret = rtl8169_set_speed(dev, cmd->autoneg, ethtool_cmd_speed(cmd), cmd->duplex, cmd->advertising); - spin_unlock_irqrestore(&tp->lock, flags); + rtl_unlock_work(tp); return ret; } @@ -1602,14 +1623,12 @@ static netdev_features_t rtl8169_fix_features(struct net_device *dev, return features; } -static int rtl8169_set_features(struct net_device *dev, - netdev_features_t features) +static void __rtl8169_set_features(struct net_device *dev, + netdev_features_t features) { struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - spin_lock_irqsave(&tp->lock, flags); + void __iomem *ioaddr = tp->mmio_addr; if (features & NETIF_F_RXCSUM) tp->cp_cmd |= RxChkSum; @@ -1623,12 +1642,21 @@ static int rtl8169_set_features(struct net_device *dev, RTL_W16(CPlusCmd, tp->cp_cmd); RTL_R16(CPlusCmd); +} - spin_unlock_irqrestore(&tp->lock, flags); +static int rtl8169_set_features(struct net_device *dev, + netdev_features_t features) +{ + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_lock_work(tp); + __rtl8169_set_features(dev, features); + rtl_unlock_work(tp); return 0; } + static inline u32 rtl8169_tx_vlan_tag(struct rtl8169_private *tp, struct sk_buff *skb) { @@ -1677,14 +1705,12 @@ static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd) static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; int rc; - spin_lock_irqsave(&tp->lock, flags); - + rtl_lock_work(tp); rc = tp->get_settings(dev, cmd); + rtl_unlock_work(tp); - spin_unlock_irqrestore(&tp->lock, flags); return rc; } @@ -1692,14 +1718,15 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct rtl8169_private *tp = netdev_priv(dev); - unsigned long flags; if (regs->len > R8169_REGS_SIZE) regs->len = R8169_REGS_SIZE; - spin_lock_irqsave(&tp->lock, flags); + rtl_lock_work(tp); + spin_lock_bh(&tp->lock); memcpy_fromio(p, tp->mmio_addr, regs->len); - spin_unlock_irqrestore(&tp->lock, flags); + spin_unlock_bh(&tp->lock); + rtl_unlock_work(tp); } static u32 rtl8169_get_msglevel(struct net_device *dev) @@ -3216,18 +3243,14 @@ static void rtl_hw_phy_config(struct net_device *dev) } } -static void rtl8169_phy_timer(unsigned long __opaque) +static void rtl_phy_work(struct rtl8169_private *tp) { - struct net_device *dev = (struct net_device *)__opaque; - struct rtl8169_private *tp = netdev_priv(dev); struct timer_list *timer = &tp->timer; void __iomem *ioaddr = tp->mmio_addr; unsigned long timeout = RTL8169_PHY_TIMEOUT; assert(tp->mac_version > RTL_GIGA_MAC_VER_01); - spin_lock_irq(&tp->lock); - if (tp->phy_reset_pending(tp)) { /* * A busy loop could burn quite a few cycles on nowadays CPU. @@ -3238,32 +3261,45 @@ static void rtl8169_phy_timer(unsigned long __opaque) } if (tp->link_ok(ioaddr)) - goto out_unlock; + return; - netif_warn(tp, link, dev, "PHY reset until link up\n"); + netif_warn(tp, link, tp->dev, "PHY reset until link up\n"); tp->phy_reset_enable(tp); out_mod_timer: mod_timer(timer, jiffies + timeout); -out_unlock: - spin_unlock_irq(&tp->lock); +} + +static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) +{ + spin_lock(&tp->lock); + if (!test_and_set_bit(flag, tp->wk.flags)) + schedule_work(&tp->wk.work); + spin_unlock(&tp->lock); +} + +static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag) +{ + local_bh_disable(); + rtl_schedule_task(tp, flag); + local_bh_enable(); +} + +static void rtl8169_phy_timer(unsigned long __opaque) +{ + struct net_device *dev = (struct net_device *)__opaque; + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); } #ifdef CONFIG_NET_POLL_CONTROLLER -/* - * Polling 'interrupt' - used by things like netconsole to send skbs - * without having to re-enable interrupts. It's not called while - * the interrupt routine is executing. - */ static void rtl8169_netpoll(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); - struct pci_dev *pdev = tp->pci_dev; - disable_irq(pdev->irq); - rtl8169_interrupt(pdev->irq, dev); - enable_irq(pdev->irq); + rtl8169_interrupt(tp->pci_dev->irq, dev); } #endif @@ -3344,7 +3380,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) low = addr[0] | (addr[1] << 8) | (addr[2] << 16) | (addr[3] << 24); high = addr[4] | (addr[5] << 8); - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); RTL_W8(Cfg9346, Cfg9346_Unlock); @@ -3368,7 +3404,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) RTL_W8(Cfg9346, Cfg9346_Lock); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); } static int rtl_set_mac_address(struct net_device *dev, void *p) @@ -3422,8 +3458,7 @@ static const struct rtl_cfg_info { void (*hw_start)(struct net_device *); unsigned int region; unsigned int align; - u16 intr_event; - u16 napi_event; + u16 event_slow; unsigned features; u8 default_ver; } rtl_cfg_infos [] = { @@ -3431,9 +3466,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8169, .region = 1, .align = 0, - .intr_event = SYSErr | LinkChg | RxOverflow | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver, .features = RTL_FEATURE_GMII, .default_ver = RTL_GIGA_MAC_VER_01, }, @@ -3441,9 +3474,7 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8168, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | - TxErr | TxOK | RxOK | RxErr, - .napi_event = TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow, .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI, .default_ver = RTL_GIGA_MAC_VER_11, }, @@ -3451,9 +3482,8 @@ static const struct rtl_cfg_info { .hw_start = rtl_hw_start_8101, .region = 2, .align = 8, - .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout | - RxFIFOOver | TxErr | TxOK | RxOK | RxErr, - .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow, + .event_slow = SYSErr | LinkChg | RxOverflow | RxFIFOOver | + PCSTimeout, .features = RTL_FEATURE_MSI, .default_ver = RTL_GIGA_MAC_VER_13, } @@ -4131,6 +4161,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) } spin_lock_init(&tp->lock); + mutex_init(&tp->wk.mutex); /* Get MAC address */ for (i = 0; i < ETH_ALEN; i++) @@ -4158,10 +4189,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* 8110SCd requires hardware Rx VLAN - disallow toggling */ dev->hw_features &= ~NETIF_F_HW_VLAN_RX; - tp->intr_mask = 0xffff; tp->hw_start = cfg->hw_start; - tp->intr_event = cfg->intr_event; - tp->napi_event = cfg->napi_event; + tp->event_slow = cfg->event_slow; tp->opts1_mask = (tp->mac_version != RTL_GIGA_MAC_VER_01) ? ~(RxBOVF | RxFOVF) : ~0; @@ -4330,16 +4359,24 @@ static int rtl8169_open(struct net_device *dev) if (retval < 0) goto err_release_fw_2; + rtl_lock_work(tp); + + tp->wk.enabled = true; + napi_enable(&tp->napi); rtl8169_init_phy(dev, tp); - rtl8169_set_features(dev, dev->features); + __rtl8169_set_features(dev, dev->features); rtl_pll_power_up(tp); rtl_hw_start(dev); + netif_start_queue(dev); + + rtl_unlock_work(tp); + tp->saved_wolopts = 0; pm_runtime_put_noidle(&pdev->dev); @@ -4413,9 +4450,7 @@ static void rtl_hw_start(struct net_device *dev) tp->hw_start(dev); - rtl_irq_enable(tp, tp->intr_event); - - netif_start_queue(dev); + rtl_irq_enable_all(tp); } static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp, @@ -4921,8 +4956,8 @@ static void rtl_hw_start_8168(struct net_device *dev) /* Work around for RxFIFO overflow. */ if (tp->mac_version == RTL_GIGA_MAC_VER_11) { - tp->intr_event |= RxFIFOOver | PCSTimeout; - tp->intr_event &= ~RxOverflow; + tp->event_slow |= RxFIFOOver | PCSTimeout; + tp->event_slow &= ~RxOverflow; } rtl_set_rx_tx_desc_registers(tp, ioaddr); @@ -5108,10 +5143,8 @@ static void rtl_hw_start_8101(struct net_device *dev) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - if (tp->mac_version >= RTL_GIGA_MAC_VER_30) { - tp->intr_event &= ~RxFIFOOver; - tp->napi_event &= ~RxFIFOOver; - } + if (tp->mac_version >= RTL_GIGA_MAC_VER_30) + tp->event_slow &= ~RxFIFOOver; if (tp->mac_version == RTL_GIGA_MAC_VER_13 || tp->mac_version == RTL_GIGA_MAC_VER_16) { @@ -5359,61 +5392,34 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp) tp->cur_tx = tp->dirty_tx = 0; } -static void rtl8169_schedule_work(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - - schedule_work(&tp->wk.work); -} - -static void rtl8169_wait_for_quiescence(struct net_device *dev) -{ - struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; - - synchronize_irq(dev->irq); - - /* Wait for any pending NAPI task to complete */ - napi_disable(&tp->napi); - - rtl8169_irq_mask_and_ack(tp); - - tp->intr_mask = 0xffff; - RTL_W16(IntrMask, tp->intr_event); - napi_enable(&tp->napi); -} - static void rtl_reset_work(struct rtl8169_private *tp) { struct net_device *dev = tp->dev; int i; - rtnl_lock(); - - if (!netif_running(dev)) - goto out_unlock; + napi_disable(&tp->napi); + netif_stop_queue(dev); + synchronize_sched(); rtl8169_hw_reset(tp); - rtl8169_wait_for_quiescence(dev); - for (i = 0; i < NUM_RX_DESC; i++) rtl8169_mark_to_asic(tp->RxDescArray + i, rx_buf_sz); rtl8169_tx_clear(tp); rtl8169_init_ring_indexes(tp); + napi_enable(&tp->napi); rtl_hw_start(dev); netif_wake_queue(dev); rtl8169_check_link_status(dev, tp, tp->mmio_addr); - -out_unlock: - rtnl_unlock(); } static void rtl8169_tx_timeout(struct net_device *dev) { - rtl8169_schedule_work(dev); + struct rtl8169_private *tp = netdev_priv(dev); + + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, @@ -5550,6 +5556,8 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, RTL_W8(TxPoll, NPQ); + mmiowb(); + if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { netif_stop_queue(dev); smp_mb(); @@ -5616,12 +5624,10 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl8169_schedule_work(dev); + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); } -static void rtl8169_tx_interrupt(struct net_device *dev, - struct rtl8169_private *tp, - void __iomem *ioaddr) +static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) { unsigned int dirty_tx, tx_left; @@ -5664,8 +5670,11 @@ static void rtl8169_tx_interrupt(struct net_device *dev, * of start_xmit activity is detected (if it is not detected, * it is slow enough). -- FR */ - if (tp->cur_tx != dirty_tx) + if (tp->cur_tx != dirty_tx) { + void __iomem *ioaddr = tp->mmio_addr; + RTL_W8(TxPoll, NPQ); + } } } @@ -5704,9 +5713,7 @@ static struct sk_buff *rtl8169_try_rx_copy(void *data, return skb; } -static int rtl8169_rx_interrupt(struct net_device *dev, - struct rtl8169_private *tp, - void __iomem *ioaddr, u32 budget) +static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) { unsigned int cur_rx, rx_left; unsigned int count; @@ -5734,7 +5741,7 @@ static int rtl8169_rx_interrupt(struct net_device *dev, if (status & RxCRC) dev->stats.rx_crc_errors++; if (status & RxFOVF) { - rtl8169_schedule_work(dev); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); dev->stats.rx_fifo_errors++; } rtl8169_mark_to_asic(desc, rx_buf_sz); @@ -5795,109 +5802,120 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) { struct net_device *dev = dev_instance; struct rtl8169_private *tp = netdev_priv(dev); - void __iomem *ioaddr = tp->mmio_addr; int handled = 0; u16 status; - /* loop handling interrupts until we have no new ones or - * we hit a invalid/hotplug case. - */ status = rtl_get_events(tp); - while (status && status != 0xffff) { - status &= tp->intr_event; - if (!status) - break; - - handled = 1; + if (status && status != 0xffff) { + status &= RTL_EVENT_NAPI | tp->event_slow; + if (status) { + handled = 1; - /* Handle all of the error cases first. These will reset - * the chip, so just exit the loop. - */ - if (unlikely(!netif_running(dev))) { - rtl8169_hw_reset(tp); - break; + rtl_irq_disable(tp); + napi_schedule(&tp->napi); } + } + return IRQ_RETVAL(handled); +} - if (unlikely(status & RxFIFOOver)) { - switch (tp->mac_version) { - /* Work around for rx fifo overflow */ - case RTL_GIGA_MAC_VER_11: - netif_stop_queue(dev); - rtl8169_tx_timeout(dev); - goto done; - default: - break; - } - } +/* + * Workqueue context. + */ +static void rtl_slow_event_work(struct rtl8169_private *tp) +{ + struct net_device *dev = tp->dev; + u16 status; + + status = rtl_get_events(tp) & tp->event_slow; + rtl_ack_events(tp, status); - if (unlikely(status & SYSErr)) { - rtl8169_pcierr_interrupt(dev); + if (unlikely(status & RxFIFOOver)) { + switch (tp->mac_version) { + /* Work around for rx fifo overflow */ + case RTL_GIGA_MAC_VER_11: + netif_stop_queue(dev); + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + default: break; } + } - if (status & LinkChg) - __rtl8169_check_link_status(dev, tp, ioaddr, true); + if (unlikely(status & SYSErr)) + rtl8169_pcierr_interrupt(dev); - /* We need to see the lastest version of tp->intr_mask to - * avoid ignoring an MSI interrupt and having to wait for - * another event which may never come. - */ - smp_rmb(); - if (status & tp->intr_mask & tp->napi_event) { - RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event); - tp->intr_mask = ~tp->napi_event; - - if (likely(napi_schedule_prep(&tp->napi))) - __napi_schedule(&tp->napi); - else - netif_info(tp, intr, dev, - "interrupt %04x in poll\n", status); - } + if (status & LinkChg) + __rtl8169_check_link_status(dev, tp, tp->mmio_addr, true); - /* We only get a new MSI interrupt when all active irq - * sources on the chip have been acknowledged. So, ack - * everything we've seen and check if new sources have become - * active to avoid blocking all interrupts from the chip. - */ - RTL_W16(IntrStatus, - (status & RxFIFOOver) ? (status | RxOverflow) : status); - status = rtl_get_events(tp); - } -done: - return IRQ_RETVAL(handled); + napi_disable(&tp->napi); + rtl_irq_disable(tp); + + napi_enable(&tp->napi); + napi_schedule(&tp->napi); } static void rtl_task(struct work_struct *work) { + static const struct { + int bitnr; + void (*action)(struct rtl8169_private *); + } rtl_work[] = { + { RTL_FLAG_TASK_SLOW_PENDING, rtl_slow_event_work }, + { RTL_FLAG_TASK_RESET_PENDING, rtl_reset_work }, + { RTL_FLAG_TASK_PHY_PENDING, rtl_phy_work } + }; struct rtl8169_private *tp = container_of(work, struct rtl8169_private, wk.work); + struct net_device *dev = tp->dev; + int i; + + rtl_lock_work(tp); + + if (!netif_running(dev) || !tp->wk.enabled) + goto out_unlock; + + for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { + bool pending; + + spin_lock_bh(&tp->lock); + pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); + spin_unlock_bh(&tp->lock); + + if (pending) + rtl_work[i].action(tp); + } - rtl_reset_work(tp); +out_unlock: + rtl_unlock_work(tp); } static int rtl8169_poll(struct napi_struct *napi, int budget) { struct rtl8169_private *tp = container_of(napi, struct rtl8169_private, napi); struct net_device *dev = tp->dev; - void __iomem *ioaddr = tp->mmio_addr; - int work_done; + u16 enable_mask = RTL_EVENT_NAPI | tp->event_slow; + int work_done= 0; + u16 status; + + status = rtl_get_events(tp); + rtl_ack_events(tp, status & ~tp->event_slow); + + if (status & RTL_EVENT_NAPI_RX) + work_done = rtl_rx(dev, tp, (u32) budget); + + if (status & RTL_EVENT_NAPI_TX) + rtl_tx(dev, tp); - work_done = rtl8169_rx_interrupt(dev, tp, ioaddr, (u32) budget); - rtl8169_tx_interrupt(dev, tp, ioaddr); + if (status & tp->event_slow) { + enable_mask &= ~tp->event_slow; + + rtl_schedule_task(tp, RTL_FLAG_TASK_SLOW_PENDING); + } if (work_done < budget) { napi_complete(napi); - /* We need for force the visibility of tp->intr_mask - * for other CPUs, as we can loose an MSI interrupt - * and potentially wait for a retransmit timeout if we don't. - * The posted write to IntrMask is safe, as it will - * eventually make it to the chip and we won't loose anything - * until it does. - */ - tp->intr_mask = 0xffff; - wmb(); - RTL_W16(IntrMask, tp->intr_event); + rtl_irq_enable(tp, enable_mask); + mmiowb(); } return work_done; @@ -5921,11 +5939,8 @@ static void rtl8169_down(struct net_device *dev) del_timer_sync(&tp->timer); - netif_stop_queue(dev); - napi_disable(&tp->napi); - - spin_lock_irq(&tp->lock); + netif_stop_queue(dev); rtl8169_hw_reset(tp); /* @@ -5935,12 +5950,8 @@ static void rtl8169_down(struct net_device *dev) */ rtl8169_rx_missed(dev, ioaddr); - spin_unlock_irq(&tp->lock); - - synchronize_irq(dev->irq); - /* Give a racing hard_start_xmit a few cycles to complete. */ - synchronize_sched(); /* FIXME: should this be synchronize_irq()? */ + synchronize_sched(); rtl8169_tx_clear(tp); @@ -5959,7 +5970,11 @@ static int rtl8169_close(struct net_device *dev) /* Update counters before going down */ rtl8169_update_counters(dev); + rtl_lock_work(tp); + tp->wk.enabled = false; + rtl8169_down(dev); + rtl_unlock_work(tp); free_irq(dev->irq, dev); @@ -5979,7 +5994,6 @@ static void rtl_set_rx_mode(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; u32 mc_filter[2]; /* Multicast hash filter */ int rx_mode; u32 tmp = 0; @@ -6008,7 +6022,7 @@ static void rtl_set_rx_mode(struct net_device *dev) } } - spin_lock_irqsave(&tp->lock, flags); + spin_lock_bh(&tp->lock); tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; @@ -6024,7 +6038,7 @@ static void rtl_set_rx_mode(struct net_device *dev) RTL_W32(RxConfig, tmp); - spin_unlock_irqrestore(&tp->lock, flags); + spin_unlock_bh(&tp->lock); } /** @@ -6037,13 +6051,9 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); void __iomem *ioaddr = tp->mmio_addr; - unsigned long flags; - if (netif_running(dev)) { - spin_lock_irqsave(&tp->lock, flags); + if (netif_running(dev)) rtl8169_rx_missed(dev, ioaddr); - spin_unlock_irqrestore(&tp->lock, flags); - } return &dev->stats; } @@ -6055,10 +6065,15 @@ static void rtl8169_net_suspend(struct net_device *dev) if (!netif_running(dev)) return; - rtl_pll_power_down(tp); - netif_device_detach(dev); netif_stop_queue(dev); + + rtl_lock_work(tp); + napi_disable(&tp->napi); + tp->wk.enabled = false; + rtl_unlock_work(tp); + + rtl_pll_power_down(tp); } #ifdef CONFIG_PM @@ -6081,7 +6096,9 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - rtl8169_schedule_work(dev); + tp->wk.enabled = true; + + rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_resume(struct device *device) @@ -6107,10 +6124,10 @@ static int rtl8169_runtime_suspend(struct device *device) if (!tp->TxDescArray) return 0; - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); tp->saved_wolopts = __rtl8169_get_wol(tp); __rtl8169_set_wol(tp, WAKE_ANY); - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); rtl8169_net_suspend(dev); @@ -6126,10 +6143,10 @@ static int rtl8169_runtime_resume(struct device *device) if (!tp->TxDescArray) return 0; - spin_lock_irq(&tp->lock); + rtl_lock_work(tp); __rtl8169_set_wol(tp, tp->saved_wolopts); tp->saved_wolopts = 0; - spin_unlock_irq(&tp->lock); + rtl_unlock_work(tp); rtl8169_init_phy(dev, tp); @@ -6197,12 +6214,8 @@ static void rtl_shutdown(struct pci_dev *pdev) /* Restore original MAC address */ rtl_rar_set(tp, dev->perm_addr); - spin_lock_irq(&tp->lock); - rtl8169_hw_reset(tp); - spin_unlock_irq(&tp->lock); - if (system_state == SYSTEM_POWER_OFF) { if (__rtl8169_get_wol(tp) & WAKE_ANY) { rtl_wol_suspend_quirk(tp); -- cgit v1.2.3-70-g09d2 From 07d251460bbf9752c6532af8c1a68328c199dd70 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 27 Jan 2012 10:24:40 -0500 Subject: PCI/XEN: Fix bug introduced by a recent change This patch (as1516) fixes a bug introduced during the removal of put_driver() and get_driver() from drivers/pci/xen-pcifront.c. Reported-by: Stephen Rothwell Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/pci/xen-pcifront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 6f819988a8d..98387caf59b 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -593,7 +593,7 @@ static pci_ers_result_t pcifront_common_process(int cmd, } pdrv = pcidev->driver; - if (pdrv->driver) { + if (pdrv) { if (pdrv->err_handler && pdrv->err_handler->error_detected) { dev_dbg(&pcidev->dev, "trying to call AER service\n"); -- cgit v1.2.3-70-g09d2 From 7aff0fe33033fc75b61446ba29d38b1b1354af9f Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Mon, 12 Dec 2011 09:25:58 -0700 Subject: of: Add of_property_match_string() to find index into a string list Add a helper function for finding the index of a string in a string list property. This helper is useful for bindings that use a separate *-name property for attaching names to tuples in another property such as 'reg' or 'gpios'. Signed-off-by: Grant Likely --- arch/arm/boot/dts/testcases/tests-phandle.dtsi | 2 ++ drivers/of/base.c | 36 ++++++++++++++++++++++++++ drivers/of/selftest.c | 29 +++++++++++++++++++++ include/linux/of.h | 3 +++ 4 files changed, 70 insertions(+) (limited to 'drivers') diff --git a/arch/arm/boot/dts/testcases/tests-phandle.dtsi b/arch/arm/boot/dts/testcases/tests-phandle.dtsi index ec0c4e6212c..0007d3cd7dc 100644 --- a/arch/arm/boot/dts/testcases/tests-phandle.dtsi +++ b/arch/arm/boot/dts/testcases/tests-phandle.dtsi @@ -31,6 +31,8 @@ phandle-list-bad-phandle = <12345678 0 0>; phandle-list-bad-args = <&provider2 1 0>, <&provider3 0>; + empty-property; + unterminated-string = [40 41 42 43]; }; }; }; diff --git a/drivers/of/base.c b/drivers/of/base.c index 133908a6fd8..13ba72875e2 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c @@ -761,6 +761,42 @@ int of_property_read_string_index(struct device_node *np, const char *propname, } EXPORT_SYMBOL_GPL(of_property_read_string_index); +/** + * of_property_match_string() - Find string in a list and return index + * @np: pointer to node containing string list property + * @propname: string list property name + * @string: pointer to string to search for in string list + * + * This function searches a string list property and returns the index + * of a specific string value. + */ +int of_property_match_string(struct device_node *np, const char *propname, + const char *string) +{ + struct property *prop = of_find_property(np, propname, NULL); + size_t l; + int i; + const char *p, *end; + + if (!prop) + return -EINVAL; + if (!prop->value) + return -ENODATA; + + p = prop->value; + end = p + prop->length; + + for (i = 0; p < end; i++, p += l) { + l = strlen(p) + 1; + if (p + l > end) + return -EILSEQ; + pr_debug("comparing %s with %s\n", string, p); + if (strcmp(string, p) == 0) + return i; /* Found it; return index */ + } + return -ENODATA; +} +EXPORT_SYMBOL_GPL(of_property_match_string); /** * of_property_count_strings - Find and return the number of strings from a diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 9d2b4803a9d..f24ffd7088d 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c @@ -120,6 +120,34 @@ static void __init of_selftest_parse_phandle_with_args(void) pr_info("end - %s\n", passed_all ? "PASS" : "FAIL"); } +static void __init of_selftest_property_match_string(void) +{ + struct device_node *np; + int rc; + + pr_info("start\n"); + np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); + if (!np) { + pr_err("No testcase data in device tree\n"); + return; + } + + rc = of_property_match_string(np, "phandle-list-names", "first"); + selftest(rc == 0, "first expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "second"); + selftest(rc == 1, "second expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "third"); + selftest(rc == 2, "third expected:0 got:%i\n", rc); + rc = of_property_match_string(np, "phandle-list-names", "fourth"); + selftest(rc == -ENODATA, "unmatched string; rc=%i", rc); + rc = of_property_match_string(np, "missing-property", "blah"); + selftest(rc == -EINVAL, "missing property; rc=%i", rc); + rc = of_property_match_string(np, "empty-property", "blah"); + selftest(rc == -ENODATA, "empty property; rc=%i", rc); + rc = of_property_match_string(np, "unterminated-string", "blah"); + selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); +} + static int __init of_selftest(void) { struct device_node *np; @@ -133,6 +161,7 @@ static int __init of_selftest(void) pr_info("start of selftest - you will see error messages\n"); of_selftest_parse_phandle_with_args(); + of_selftest_property_match_string(); pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); return 0; } diff --git a/include/linux/of.h b/include/linux/of.h index a75a831e205..5a4a3adb17e 100644 --- a/include/linux/of.h +++ b/include/linux/of.h @@ -217,6 +217,9 @@ extern int of_property_read_string(struct device_node *np, extern int of_property_read_string_index(struct device_node *np, const char *propname, int index, const char **output); +extern int of_property_match_string(struct device_node *np, + const char *propname, + const char *string); extern int of_property_count_strings(struct device_node *np, const char *propname); extern int of_device_is_compatible(const struct device_node *device, -- cgit v1.2.3-70-g09d2 From 787f9fd23283d7103c65371f7b108ecf1020cddf Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Thu, 13 Oct 2011 16:52:50 +0200 Subject: atmel_lcdfb: support 16bit BGR:565 mode, remove unsupported 15bit modes Allow framebuffer to be configured in 16bit mode when panel is wired in (the default) BGR configuration, and don't claim to support 15bit input modes, which the LCD controller cannot handle. Signed-off-by: Peter Korsgaard Acked-by: Nicolas Ferre Signed-off-by: Florian Tobias Schandinat --- drivers/video/atmel_lcdfb.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index e40c00f2c2b..d99505b1637 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -421,24 +421,18 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, var->red.length = var->green.length = var->blue.length = var->bits_per_pixel; break; - case 15: case 16: if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { /* RGB:565 mode */ var->red.offset = 11; var->blue.offset = 0; - var->green.length = 6; - } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) { - var->red.offset = 10; - var->blue.offset = 0; - var->green.length = 5; } else { - /* BGR:555 mode */ + /* BGR:565 mode */ var->red.offset = 0; - var->blue.offset = 10; - var->green.length = 5; + var->blue.offset = 11; } var->green.offset = 5; + var->green.length = 6; var->red.length = var->blue.length = 5; break; case 32: -- cgit v1.2.3-70-g09d2 From f820917abae4a019b0357d3fe72b22c22a11b775 Mon Sep 17 00:00:00 2001 From: "Manjunathappa, Prakash" Date: Tue, 3 Jan 2012 18:10:51 +0530 Subject: video: da8xx-fb: reset LCDC only if functional clock changes with DVFS LCDC functional clock may or may not be derived from CPU/MPU DPLL, For example, AM335x => Separate independent DPLL for LCDC Davinci => Same DPLL as MPU So, on platforms where LCDC functional clock is not derived from CPU/MPU PLL it is not required to reset LCDC module as its functional clock does not change with DVFS. This patch adds check to do reset only if functional clock changes between pre and post notifier callbacks with DVFS. Signed-off-by: Manjunathappa, Prakash Signed-off-by: Florian Tobias Schandinat --- drivers/video/da8xx-fb.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 29577bf1f55..9ecc30744c6 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -161,6 +161,7 @@ struct da8xx_fb_par { int vsync_timeout; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; + unsigned int lcd_fck_rate; #endif void (*panel_power_ctrl)(int); }; @@ -840,11 +841,13 @@ static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, struct da8xx_fb_par *par; par = container_of(nb, struct da8xx_fb_par, freq_transition); - if (val == CPUFREQ_PRECHANGE) { - lcd_disable_raster(); - } else if (val == CPUFREQ_POSTCHANGE) { - lcd_calc_clk_divider(par); - lcd_enable_raster(); + if (val == CPUFREQ_POSTCHANGE) { + if (par->lcd_fck_rate != clk_get_rate(par->lcdc_clk)) { + par->lcd_fck_rate = clk_get_rate(par->lcdc_clk); + lcd_disable_raster(); + lcd_calc_clk_divider(par); + lcd_enable_raster(); + } } return 0; @@ -1137,6 +1140,9 @@ static int __devinit fb_probe(struct platform_device *device) par = da8xx_fb_info->par; par->lcdc_clk = fb_clk; +#ifdef CONFIG_CPU_FREQ + par->lcd_fck_rate = clk_get_rate(fb_clk); +#endif par->pxl_clk = lcdc_info->pxl_clk; if (fb_pdata->panel_power_ctrl) { par->panel_power_ctrl = fb_pdata->panel_power_ctrl; -- cgit v1.2.3-70-g09d2 From 857a8df9467a6dfe5d3aa309d9bdef31dc817647 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 21 Jan 2012 13:11:49 +0000 Subject: video: s3c-fb: Convert to devm style allocation Saves some code, especially useful as the code saved is mostly in the infrequently tested error paths. Signed-off-by: Mark Brown Acked-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 32 +++++--------------------------- 1 file changed, 5 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 0c63b69b634..7c5158dda0b 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -186,7 +186,6 @@ struct s3c_fb_vsync { * struct s3c_fb - overall hardware state of the hardware * @slock: The spinlock protection for this data sturcture. * @dev: The device that we bound to, for printing, etc. - * @regs_res: The resource we claimed for the IO registers. * @bus_clk: The clk (hclk) feeding our interface and possibly pixclk. * @lcd_clk: The clk (sclk) feeding pixclk. * @regs: The mapped hardware registers. @@ -202,7 +201,6 @@ struct s3c_fb_vsync { struct s3c_fb { spinlock_t slock; struct device *dev; - struct resource *regs_res; struct clk *bus_clk; struct clk *lcd_clk; void __iomem *regs; @@ -1361,7 +1359,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) return -EINVAL; } - sfb = kzalloc(sizeof(struct s3c_fb), GFP_KERNEL); + sfb = devm_kzalloc(dev, sizeof(struct s3c_fb), GFP_KERNEL); if (!sfb) { dev_err(dev, "no memory for framebuffers\n"); return -ENOMEM; @@ -1404,33 +1402,25 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) goto err_lcd_clk; } - sfb->regs_res = request_mem_region(res->start, resource_size(res), - dev_name(dev)); - if (!sfb->regs_res) { - dev_err(dev, "failed to claim register region\n"); - ret = -ENOENT; - goto err_lcd_clk; - } - - sfb->regs = ioremap(res->start, resource_size(res)); + sfb->regs = devm_request_and_ioremap(dev, res); if (!sfb->regs) { dev_err(dev, "failed to map registers\n"); ret = -ENXIO; - goto err_req_region; + goto err_lcd_clk; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { dev_err(dev, "failed to acquire irq resource\n"); ret = -ENOENT; - goto err_ioremap; + goto err_lcd_clk; } sfb->irq_no = res->start; ret = request_irq(sfb->irq_no, s3c_fb_irq, 0, "s3c_fb", sfb); if (ret) { dev_err(dev, "irq request failed\n"); - goto err_ioremap; + goto err_lcd_clk; } dev_dbg(dev, "got resources (regs %p), probing windows\n", sfb->regs); @@ -1486,12 +1476,6 @@ err_pm_runtime: pm_runtime_put_sync(sfb->dev); free_irq(sfb->irq_no, sfb); -err_ioremap: - iounmap(sfb->regs); - -err_req_region: - release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); - err_lcd_clk: pm_runtime_disable(sfb->dev); @@ -1505,7 +1489,6 @@ err_bus_clk: clk_put(sfb->bus_clk); err_sfb: - kfree(sfb); return ret; } @@ -1529,8 +1512,6 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) free_irq(sfb->irq_no, sfb); - iounmap(sfb->regs); - if (!sfb->variant.has_clksel) { clk_disable(sfb->lcd_clk); clk_put(sfb->lcd_clk); @@ -1539,12 +1520,9 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev) clk_disable(sfb->bus_clk); clk_put(sfb->bus_clk); - release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res)); - pm_runtime_put_sync(sfb->dev); pm_runtime_disable(sfb->dev); - kfree(sfb); return 0; } -- cgit v1.2.3-70-g09d2 From 92a9c19a89af2ca219fbb040a0059f414a4b7223 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Sat, 28 Jan 2012 19:57:46 +0000 Subject: udlfb: remove sysfs framebuffer device with USB .disconnect() The USB graphics card driver delays the unregistering of the framebuffer device to a workqueue, which breaks the userspace visible remove uevent sequence. Recent userspace tools started to support USB graphics card hotplug out-of-the-box and rely on proper events sent by the kernel. The framebuffer device is a direct child of the USB interface which is removed immediately after the USB .disconnect() callback. But the fb device in /sys stays around until its final cleanup, at a time where all the parent devices have been removed already. To work around that, we remove the sysfs fb device directly in the USB .disconnect() callback and leave only the cleanup of the internal fb data to the delayed work. Before: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb0 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) remove /2-1.2:1.0/graphics/fb0 (graphics) After: add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/graphics/fb1 (graphics) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0 (usb) remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2 (usb) Cc: stable@vger.kernel.org Tested-by: Bernie Thompson Acked-by: Bernie Thompson Signed-off-by: Kay Sievers Signed-off-by: Florian Tobias Schandinat --- drivers/video/fbmem.c | 18 +++++++++++++++++- drivers/video/udlfb.c | 2 +- include/linux/fb.h | 1 + 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index ac9141b8535..c6ce416ab58 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1665,6 +1665,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) if (ret) return -EINVAL; + unlink_framebuffer(fb_info); if (fb_info->pixmap.addr && (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT)) kfree(fb_info->pixmap.addr); @@ -1672,7 +1673,6 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) registered_fb[i] = NULL; num_registered_fb--; fb_cleanup_device(fb_info); - device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); @@ -1681,6 +1681,22 @@ static int do_unregister_framebuffer(struct fb_info *fb_info) return 0; } +int unlink_framebuffer(struct fb_info *fb_info) +{ + int i; + + i = fb_info->node; + if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info) + return -EINVAL; + + if (fb_info->dev) { + device_destroy(fb_class, MKDEV(FB_MAJOR, i)); + fb_info->dev = NULL; + } + return 0; +} +EXPORT_SYMBOL(unlink_framebuffer); + void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary) { diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c index a19773149bd..a40c05ebbdc 100644 --- a/drivers/video/udlfb.c +++ b/drivers/video/udlfb.c @@ -1739,7 +1739,7 @@ static void dlfb_usb_disconnect(struct usb_interface *interface) for (i = 0; i < ARRAY_SIZE(fb_device_attrs); i++) device_remove_file(info->dev, &fb_device_attrs[i]); device_remove_bin_file(info->dev, &edid_attr); - + unlink_framebuffer(info); usb_set_intfdata(interface, NULL); /* if clients still have us open, will be freed on last close */ diff --git a/include/linux/fb.h b/include/linux/fb.h index c18122f4054..a395b8c7699 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -1003,6 +1003,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf, /* drivers/video/fbmem.c */ extern int register_framebuffer(struct fb_info *fb_info); extern int unregister_framebuffer(struct fb_info *fb_info); +extern int unlink_framebuffer(struct fb_info *fb_info); extern void remove_conflicting_framebuffers(struct apertures_struct *a, const char *name, bool primary); extern int fb_prepare_logo(struct fb_info *fb_info, int rotate); -- cgit v1.2.3-70-g09d2 From 1c16697bf9d5b206cb0d2b905a54de5e077296be Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Jan 2012 16:01:58 +0100 Subject: drivers/video/au*fb.c: use devm_ functions The various devm_ functions allocate memory that is released when a driver detaches. This patch uses these functions for data that is allocated in the probe function of a platform device and is only freed in the remove function. In au1100fb.c, the probe function now returns -ENODEV on failure. Signed-off-by: Julia Lawall Acked-by: Manuel Lauss Signed-off-by: Florian Tobias Schandinat --- drivers/video/au1100fb.c | 32 ++++++++++++-------------------- drivers/video/au1200fb.c | 9 +-------- 2 files changed, 13 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index de9da6774fd..befcbd8ef01 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -477,7 +477,8 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) u32 sys_clksrc; /* Allocate new device private */ - fbdev = kzalloc(sizeof(struct au1100fb_device), GFP_KERNEL); + fbdev = devm_kzalloc(&dev->dev, sizeof(struct au1100fb_device), + GFP_KERNEL); if (!fbdev) { print_err("fail to allocate device private record"); return -ENOMEM; @@ -498,8 +499,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) au1100fb_fix.mmio_start = regs_res->start; au1100fb_fix.mmio_len = resource_size(regs_res); - if (!request_mem_region(au1100fb_fix.mmio_start, au1100fb_fix.mmio_len, - DRIVER_NAME)) { + if (!devm_request_mem_region(au1100fb_fix.mmio_start, + au1100fb_fix.mmio_len, + DRIVER_NAME)) { print_err("fail to lock memory region at 0x%08lx", au1100fb_fix.mmio_start); return -EBUSY; @@ -514,8 +516,9 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->fb_len = fbdev->panel->xres * fbdev->panel->yres * (fbdev->panel->bpp >> 3) * AU1100FB_NBR_VIDEO_BUFFERS; - fbdev->fb_mem = dma_alloc_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), - &fbdev->fb_phys, GFP_KERNEL); + fbdev->fb_mem = dmam_alloc_coherent(&dev->dev, &dev->dev, + PAGE_ALIGN(fbdev->fb_len), + &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { print_err("fail to allocate frambuffer (size: %dK))", fbdev->fb_len / 1024); @@ -557,14 +560,14 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) fbdev->info.fbops = &au1100fb_ops; fbdev->info.fix = au1100fb_fix; - if (!(fbdev->info.pseudo_palette = kzalloc(sizeof(u32) * 16, GFP_KERNEL))) { + fbdev->info.pseudo_palette = + devm_kzalloc(&dev->dev, sizeof(u32) * 16, GFP_KERNEL); + if (!fbdev->info.pseudo_palette) return -ENOMEM; - } if (fb_alloc_cmap(&fbdev->info.cmap, AU1100_LCD_NBR_PALETTE_ENTRIES, 0) < 0) { print_err("Fail to allocate colormap (%d entries)", AU1100_LCD_NBR_PALETTE_ENTRIES); - kfree(fbdev->info.pseudo_palette); return -EFAULT; } @@ -582,9 +585,6 @@ static int __devinit au1100fb_drv_probe(struct platform_device *dev) return 0; failed: - if (fbdev->regs) { - release_mem_region(fbdev->regs_phys, fbdev->regs_len); - } if (fbdev->fb_mem) { dma_free_noncoherent(&dev->dev, fbdev->fb_len, fbdev->fb_mem, fbdev->fb_phys); @@ -592,10 +592,9 @@ failed: if (fbdev->info.cmap.len != 0) { fb_dealloc_cmap(&fbdev->info.cmap); } - kfree(fbdev); platform_set_drvdata(dev, NULL); - return 0; + return -ENODEV; } int au1100fb_drv_remove(struct platform_device *dev) @@ -615,14 +614,7 @@ int au1100fb_drv_remove(struct platform_device *dev) /* Clean up all probe data */ unregister_framebuffer(&fbdev->info); - release_mem_region(fbdev->regs_phys, fbdev->regs_len); - - dma_free_coherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), fbdev->fb_mem, - fbdev->fb_phys); - fb_dealloc_cmap(&fbdev->info.cmap); - kfree(fbdev->info.pseudo_palette); - kfree((void*)fbdev); return 0; } diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c index 04e4479d5af..3e9a773db09 100644 --- a/drivers/video/au1200fb.c +++ b/drivers/video/au1200fb.c @@ -1724,7 +1724,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) /* Allocate the framebuffer to the maximum screen size */ fbdev->fb_len = (win->w[plane].xres * win->w[plane].yres * bpp) / 8; - fbdev->fb_mem = dma_alloc_noncoherent(&dev->dev, + fbdev->fb_mem = dmam_alloc_noncoherent(&dev->dev, &dev->dev, PAGE_ALIGN(fbdev->fb_len), &fbdev->fb_phys, GFP_KERNEL); if (!fbdev->fb_mem) { @@ -1788,9 +1788,6 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev) failed: /* NOTE: This only does the current plane/window that failed; others are still active */ - if (fbdev->fb_mem) - dma_free_noncoherent(&dev->dev, PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); if (fbi) { if (fbi->cmap.len != 0) fb_dealloc_cmap(&fbi->cmap); @@ -1817,10 +1814,6 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev) /* Clean up all probe data */ unregister_framebuffer(fbi); - if (fbdev->fb_mem) - dma_free_noncoherent(&dev->dev, - PAGE_ALIGN(fbdev->fb_len), - fbdev->fb_mem, fbdev->fb_phys); if (fbi->cmap.len != 0) fb_dealloc_cmap(&fbi->cmap); kfree(fbi->pseudo_palette); -- cgit v1.2.3-70-g09d2 From f8bd493456c3da372ae81ed8f6b903f6207b9d98 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 26 Jan 2012 19:32:34 +0900 Subject: video: use gpio_request_one Using gpio_request_one can make the code simpler because it can set the direction and initial value in one shot. Signed-off-by: Jingoo Han Acked-by: Tomi Valkeinen Cc: Michael Hennerich Cc: Pavel Machek Signed-off-by: Florian Tobias Schandinat --- drivers/video/bf537-lq035.c | 12 +++--------- drivers/video/bf54x-lq043fb.c | 4 +--- drivers/video/bfin-lq035q1-fb.c | 8 ++++---- drivers/video/bfin_adv7393fb.c | 5 +++-- drivers/video/msm/mddi_client_nt35399.c | 7 +------ drivers/video/msm/mddi_client_toshiba.c | 7 +------ drivers/video/omap/lcd_inn1610.c | 10 ++++------ drivers/video/omap2/displays/panel-taal.c | 4 +--- drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 11 ++--------- 9 files changed, 20 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bf537-lq035.c b/drivers/video/bf537-lq035.c index bea53c1a495..befbc80d11f 100644 --- a/drivers/video/bf537-lq035.c +++ b/drivers/video/bf537-lq035.c @@ -383,23 +383,19 @@ static int __devinit request_ports(void) } #if (defined(UD) && defined(LBR)) - if (gpio_request(UD, KBUILD_MODNAME)) { + if (gpio_request_one(UD, GPIOF_OUT_INIT_LOW, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", UD); return -EBUSY; } - if (gpio_request(LBR, KBUILD_MODNAME)) { + if (gpio_request_one(LBR, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", LBR); gpio_free(UD); return -EBUSY; } - - gpio_direction_output(UD, 0); - gpio_direction_output(LBR, 1); - #endif - if (gpio_request(MOD, KBUILD_MODNAME)) { + if (gpio_request_one(MOD, GPIOF_OUT_INIT_HIGH, KBUILD_MODNAME)) { pr_err("requesting GPIO %d failed\n", MOD); #if (defined(UD) && defined(LBR)) gpio_free(LBR); @@ -408,8 +404,6 @@ static int __devinit request_ports(void) return -EBUSY; } - gpio_direction_output(MOD, 1); - SSYNC(); return 0; } diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index 46b03f53985..dc2f0047769 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c @@ -240,7 +240,7 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) u16 eppi_req_18[] = EPPI0_18; u16 disp = fbi->mach_info->disp; - if (gpio_request(disp, DRIVER_NAME)) { + if (gpio_request_one(disp, GPIOF_OUT_INIT_HIGH, DRIVER_NAME)) { printk(KERN_ERR "Requesting GPIO %d failed\n", disp); return -EFAULT; } @@ -263,8 +263,6 @@ static int request_ports(struct bfin_bf54xfb_info *fbi) } } - gpio_direction_output(disp, 1); - return 0; } diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c index c633068372c..86922ac8441 100644 --- a/drivers/video/bfin-lq035q1-fb.c +++ b/drivers/video/bfin-lq035q1-fb.c @@ -365,10 +365,10 @@ static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev, * Drive PPI_FS3 Low */ if (ANOMALY_05000400) { - int ret = gpio_request(P_IDENT(P_PPI0_FS3), "PPI_FS3"); + int ret = gpio_request_one(P_IDENT(P_PPI0_FS3), + GPIOF_OUT_INIT_LOW, "PPI_FS3"); if (ret) return ret; - gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); } if (ppi16) @@ -716,14 +716,14 @@ static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) } if (info->disp_info->use_bl) { - ret = gpio_request(info->disp_info->gpio_bl, "LQ035 Backlight"); + ret = gpio_request_one(info->disp_info->gpio_bl, + GPIOF_OUT_INIT_LOW, "LQ035 Backlight"); if (ret) { dev_err(&pdev->dev, "failed to request GPIO %d\n", info->disp_info->gpio_bl); goto out9; } - gpio_direction_output(info->disp_info->gpio_bl, 0); } ret = register_framebuffer(fbinfo); diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/bfin_adv7393fb.c index 811dd7f6aa4..c9928142921 100644 --- a/drivers/video/bfin_adv7393fb.c +++ b/drivers/video/bfin_adv7393fb.c @@ -411,12 +411,13 @@ static int __devinit bfin_adv7393_fb_probe(struct i2c_client *client, /* Workaround "PPI Does Not Start Properly In Specific Mode" */ if (ANOMALY_05000400) { - if (gpio_request(P_IDENT(P_PPI0_FS3), "PPI0_FS3")) { + ret = gpio_request_one(P_IDENT(P_PPI0_FS3), GPIOF_OUT_INIT_LOW, + "PPI0_FS3") + if (ret) { dev_err(&client->dev, "PPI0_FS3 GPIO request failed\n"); ret = -EBUSY; goto out_8; } - gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); } if (peripheral_request_list(ppi_pins, DRIVER_NAME)) { diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/msm/mddi_client_nt35399.c index f239f4a25e0..7fcd67e132b 100644 --- a/drivers/video/msm/mddi_client_nt35399.c +++ b/drivers/video/msm/mddi_client_nt35399.c @@ -155,14 +155,10 @@ static int setup_vsync(struct panel_info *panel, int init) ret = 0; goto uninit; } - ret = gpio_request(gpio, "vsync"); + ret = gpio_request_one(gpio, GPIOF_IN, "vsync"); if (ret) goto err_request_gpio_failed; - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(gpio); if (ret < 0) goto err_get_irq_num_failed; @@ -180,7 +176,6 @@ uninit: free_irq(gpio_to_irq(gpio), panel->client_data); err_request_irq_failed: err_get_irq_num_failed: -err_gpio_direction_input_failed: gpio_free(gpio); err_request_gpio_failed: return ret; diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/msm/mddi_client_toshiba.c index f9bc932ac46..053eb687733 100644 --- a/drivers/video/msm/mddi_client_toshiba.c +++ b/drivers/video/msm/mddi_client_toshiba.c @@ -186,14 +186,10 @@ static int setup_vsync(struct panel_info *panel, ret = 0; goto uninit; } - ret = gpio_request(gpio, "vsync"); + ret = gpio_request_one(gpio, GPIOF_IN, "vsync"); if (ret) goto err_request_gpio_failed; - ret = gpio_direction_input(gpio); - if (ret) - goto err_gpio_direction_input_failed; - ret = irq = gpio_to_irq(gpio); if (ret < 0) goto err_get_irq_num_failed; @@ -210,7 +206,6 @@ uninit: free_irq(gpio_to_irq(gpio), panel); err_request_irq_failed: err_get_irq_num_failed: -err_gpio_direction_input_failed: gpio_free(gpio); err_request_gpio_failed: return ret; diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c index 7e8bd8e08a9..e3d3d135aa4 100644 --- a/drivers/video/omap/lcd_inn1610.c +++ b/drivers/video/omap/lcd_inn1610.c @@ -22,7 +22,7 @@ #include #include -#include +#include #include "omapfb.h" #define MODULE_NAME "omapfb-lcd_h3" @@ -32,20 +32,18 @@ static int innovator1610_panel_init(struct lcd_panel *panel, { int r = 0; - if (gpio_request(14, "lcd_en0")) { + /* configure GPIO(14, 15) as outputs */ + if (gpio_request_one(14, GPIOF_OUT_INIT_LOW, "lcd_en0")) { pr_err(MODULE_NAME ": can't request GPIO 14\n"); r = -1; goto exit; } - if (gpio_request(15, "lcd_en1")) { + if (gpio_request_one(15, GPIOF_OUT_INIT_LOW, "lcd_en1")) { pr_err(MODULE_NAME ": can't request GPIO 15\n"); gpio_free(14); r = -1; goto exit; } - /* configure GPIO(14, 15) as outputs */ - gpio_direction_output(14, 0); - gpio_direction_output(15, 0); exit: return r; } diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index 00c5c615585..0f21fa5a16a 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -1019,14 +1019,12 @@ static int taal_probe(struct omap_dss_device *dssdev) if (panel_data->use_ext_te) { int gpio = panel_data->ext_te_gpio; - r = gpio_request(gpio, "taal irq"); + r = gpio_request_one(gpio, GPIOF_IN, "taal irq"); if (r) { dev_err(&dssdev->dev, "GPIO request failed\n"); goto err_gpio; } - gpio_direction_input(gpio); - r = request_irq(gpio_to_irq(gpio), taal_te_isr, IRQF_TRIGGER_RISING, "taal vsync", dssdev); diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index e6649aa8959..880c313d6bc 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -408,17 +408,12 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev) } if (gpio_is_valid(nreset_gpio)) { - ret = gpio_request(nreset_gpio, "lcd reset"); + ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW, + "lcd reset"); if (ret < 0) { dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); goto fail_gpio_req; } - - ret = gpio_direction_output(nreset_gpio, 0); - if (ret < 0) { - dev_err(&dssdev->dev, "couldn't set GPIO direction\n"); - goto fail_gpio_direction; - } } ret = sysfs_create_group(&dssdev->dev.kobj, &tpo_td043_attr_group); @@ -427,8 +422,6 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev) return 0; -fail_gpio_direction: - gpio_free(nreset_gpio); fail_gpio_req: regulator_put(tpo_td043->vcc_reg); fail_regulator: -- cgit v1.2.3-70-g09d2 From 05e52b4bfba0d1fa4195abbc4ac29c24033c8e96 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Thu, 26 Jan 2012 19:38:45 +0900 Subject: video: s3c-fb: fix checkpatch error This patch fixes the checkpatch error listed below: ERROR: trailing statements should be on next line Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- drivers/video/s3c-fb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 7c5158dda0b..389189a9e77 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -48,7 +48,8 @@ #undef writel #define writel(v, r) do { \ printk(KERN_DEBUG "%s: %08x => %p\n", __func__, (unsigned int)v, r); \ - __raw_writel(v, r); } while (0) + __raw_writel(v, r); \ +} while (0) #endif /* FB_S3C_DEBUG_REGWRITE */ /* irq_flags bits */ -- cgit v1.2.3-70-g09d2 From f7f31e505aa79d91b979a38789b1608744361bdc Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 27 Jan 2012 14:47:22 +0900 Subject: video: s3c-fb: add alpha value width setting This patch adds alpha value width setting according to transparency value of each window format, using BLENDCON register. When alpha value is 8 bits, BLENDCON will set alpha value width as 8 bits. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- arch/arm/plat-samsung/include/plat/regs-fb.h | 6 ++++++ drivers/video/s3c-fb.c | 18 ++++++++++++++++++ 2 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h index 8f39aa5b26e..6bf68ed0196 100644 --- a/arch/arm/plat-samsung/include/plat/regs-fb.h +++ b/arch/arm/plat-samsung/include/plat/regs-fb.h @@ -384,3 +384,9 @@ #define WPALCON_W0PAL_16BPP_A555 (0x5 << 0) #define WPALCON_W0PAL_16BPP_565 (0x6 << 0) +/* Blending equation control */ +#define BLENDCON (0x260) +#define BLENDCON_NEW_MASK (1 << 0) +#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0) +#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0) + diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 389189a9e77..9af6c1849c2 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -82,6 +82,7 @@ struct s3c_fb; * @palette: Address of palette memory, or 0 if none. * @has_prtcon: Set if has PRTCON register. * @has_shadowcon: Set if has SHADOWCON register. + * @has_blendcon: Set if has BLENDCON register. * @has_clksel: Set if VIDCON0 register has CLKSEL bit. */ struct s3c_fb_variant { @@ -100,6 +101,7 @@ struct s3c_fb_variant { unsigned int has_prtcon:1; unsigned int has_shadowcon:1; + unsigned int has_blendcon:1; unsigned int has_clksel:1; }; @@ -691,6 +693,17 @@ static int s3c_fb_set_par(struct fb_info *info) writel(data, regs + sfb->variant.wincon + (win_no * 4)); writel(0x0, regs + sfb->variant.winmap + (win_no * 4)); + /* Set alpha value width */ + if (sfb->variant.has_blendcon) { + data = readl(sfb->regs + BLENDCON); + data &= ~BLENDCON_NEW_MASK; + if (var->transp.length > 4) + data |= BLENDCON_NEW_8BIT_ALPHA_VALUE; + else + data |= BLENDCON_NEW_4BIT_ALPHA_VALUE; + writel(data, sfb->regs + BLENDCON); + } + shadow_protect_win(win, 0); pm_runtime_put_sync(sfb->dev); @@ -1798,6 +1811,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pc100 = { }, .has_prtcon = 1, + .has_blendcon = 1, .has_clksel = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], @@ -1829,6 +1843,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { }, .has_shadowcon = 1, + .has_blendcon = 1, .has_clksel = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], @@ -1860,6 +1875,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = { }, .has_shadowcon = 1, + .has_blendcon = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1923,6 +1939,8 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { [1] = 0x2800, [2] = 0x2c00, }, + + .has_blendcon = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], -- cgit v1.2.3-70-g09d2 From d8b97db4c8e40e49985fa5802be914292add64f6 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Fri, 27 Jan 2012 14:47:55 +0900 Subject: video: s3c-fb: add video clock running at data under-flow This patch adds video clock running at data under-flow. It means that the pixel clock is continuously provided to lcd module, even when under-run occurs. Signed-off-by: Jingoo Han Signed-off-by: Florian Tobias Schandinat --- arch/arm/plat-samsung/include/plat/regs-fb.h | 3 +++ drivers/video/s3c-fb.c | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/arch/arm/plat-samsung/include/plat/regs-fb.h b/arch/arm/plat-samsung/include/plat/regs-fb.h index 6bf68ed0196..bbb16e0aa1f 100644 --- a/arch/arm/plat-samsung/include/plat/regs-fb.h +++ b/arch/arm/plat-samsung/include/plat/regs-fb.h @@ -91,6 +91,9 @@ #define VIDCON1_VSTATUS_BACKPORCH (0x1 << 13) #define VIDCON1_VSTATUS_ACTIVE (0x2 << 13) #define VIDCON1_VSTATUS_FRONTPORCH (0x0 << 13) +#define VIDCON1_VCLK_MASK (0x3 << 9) +#define VIDCON1_VCLK_HOLD (0x0 << 9) +#define VIDCON1_VCLK_RUN (0x1 << 9) #define VIDCON1_INV_VCLK (1 << 7) #define VIDCON1_INV_HSYNC (1 << 6) diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index 9af6c1849c2..e22bf9ddf28 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -84,6 +84,7 @@ struct s3c_fb; * @has_shadowcon: Set if has SHADOWCON register. * @has_blendcon: Set if has BLENDCON register. * @has_clksel: Set if VIDCON0 register has CLKSEL bit. + * @has_fixvclk: Set if VIDCON1 register has FIXVCLK bits. */ struct s3c_fb_variant { unsigned int is_2443:1; @@ -103,6 +104,7 @@ struct s3c_fb_variant { unsigned int has_shadowcon:1; unsigned int has_blendcon:1; unsigned int has_clksel:1; + unsigned int has_fixvclk:1; }; /** @@ -1358,6 +1360,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) struct resource *res; int win; int ret = 0; + u32 reg; platid = platform_get_device_id(pdev); fbdrv = (struct s3c_fb_driverdata *)platid->driver_data; @@ -1448,6 +1451,14 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev) writel(pd->vidcon1, sfb->regs + VIDCON1); + /* set video clock running at under-run */ + if (sfb->variant.has_fixvclk) { + reg = readl(sfb->regs + VIDCON1); + reg &= ~VIDCON1_VCLK_MASK; + reg |= VIDCON1_VCLK_RUN; + writel(reg, sfb->regs + VIDCON1); + } + /* zero all windows before we do anything */ for (win = 0; win < fbdrv->variant.nr_windows; win++) @@ -1571,6 +1582,7 @@ static int s3c_fb_resume(struct device *dev) struct s3c_fb_platdata *pd = sfb->pdata; struct s3c_fb_win *win; int win_no; + u32 reg; clk_enable(sfb->bus_clk); @@ -1581,6 +1593,14 @@ static int s3c_fb_resume(struct device *dev) pd->setup_gpio(); writel(pd->vidcon1, sfb->regs + VIDCON1); + /* set video clock running at under-run */ + if (sfb->variant.has_fixvclk) { + reg = readl(sfb->regs + VIDCON1); + reg &= ~VIDCON1_VCLK_MASK; + reg |= VIDCON1_VCLK_RUN; + writel(reg, sfb->regs + VIDCON1); + } + /* zero all windows before we do anything */ for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++) s3c_fb_clear_win(sfb, win_no); @@ -1845,6 +1865,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5pv210 = { .has_shadowcon = 1, .has_blendcon = 1, .has_clksel = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1876,6 +1897,7 @@ static struct s3c_fb_driverdata s3c_fb_data_exynos4 = { .has_shadowcon = 1, .has_blendcon = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], @@ -1941,6 +1963,7 @@ static struct s3c_fb_driverdata s3c_fb_data_s5p64x0 = { }, .has_blendcon = 1, + .has_fixvclk = 1, }, .win[0] = &s3c_fb_data_s5p_wins[0], .win[1] = &s3c_fb_data_s5p_wins[1], -- cgit v1.2.3-70-g09d2 From c6d242aa64d27ebd258a12aa0a5da068e25e01f5 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 27 Jan 2012 16:02:54 +0800 Subject: video: convert drivers/video/* to use module_spi_driver() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch converts the drivers in drivers/video/* to use the module_spi_driver() macro which makes the code smaller and a bit simpler. Signed-off-by: Axel Lin Cc: Imre Deak Cc: Roger Quadros Cc: Steve Sakoman Cc: Erik Gilling Cc: Gražvydas Ignotas Signed-off-by: Florian Tobias Schandinat --- drivers/video/omap/lcd_mipid.c | 14 +------------- drivers/video/omap2/displays/panel-acx565akm.c | 13 +------------ drivers/video/omap2/displays/panel-lgphilips-lb035q02.c | 12 +----------- drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c | 12 +----------- drivers/video/omap2/displays/panel-tpo-td043mtea1.c | 13 +------------ 5 files changed, 5 insertions(+), 59 deletions(-) (limited to 'drivers') diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c index 8d546dd55e8..e3880c4a0bb 100644 --- a/drivers/video/omap/lcd_mipid.c +++ b/drivers/video/omap/lcd_mipid.c @@ -609,19 +609,7 @@ static struct spi_driver mipid_spi_driver = { .remove = __devexit_p(mipid_spi_remove), }; -static int __init mipid_drv_init(void) -{ - spi_register_driver(&mipid_spi_driver); - - return 0; -} -module_init(mipid_drv_init); - -static void __exit mipid_drv_cleanup(void) -{ - spi_unregister_driver(&mipid_spi_driver); -} -module_exit(mipid_drv_cleanup); +module_spi_driver(mipid_spi_driver); MODULE_DESCRIPTION("MIPI display driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c index 51a87e149e2..d26f37ac69d 100644 --- a/drivers/video/omap2/displays/panel-acx565akm.c +++ b/drivers/video/omap2/displays/panel-acx565akm.c @@ -809,18 +809,7 @@ static struct spi_driver acx565akm_spi_driver = { .remove = __devexit_p(acx565akm_spi_remove), }; -static int __init acx565akm_init(void) -{ - return spi_register_driver(&acx565akm_spi_driver); -} - -static void __exit acx565akm_exit(void) -{ - spi_unregister_driver(&acx565akm_spi_driver); -} - -module_init(acx565akm_init); -module_exit(acx565akm_exit); +module_spi_driver(acx565akm_spi_driver); MODULE_AUTHOR("Nokia Corporation"); MODULE_DESCRIPTION("acx565akm LCD Driver"); diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c index e0eb35be303..0841cc2b3f7 100644 --- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c +++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c @@ -264,16 +264,6 @@ static struct spi_driver lb035q02_spi_driver = { .remove = __devexit_p(lb035q02_panel_spi_remove), }; -static int __init lb035q02_panel_drv_init(void) -{ - return spi_register_driver(&lb035q02_spi_driver); -} - -static void __exit lb035q02_panel_drv_exit(void) -{ - spi_unregister_driver(&lb035q02_spi_driver); -} +module_spi_driver(lb035q02_spi_driver); -module_init(lb035q02_panel_drv_init); -module_exit(lb035q02_panel_drv_exit); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c index 0eb31caddca..8b38b39213f 100644 --- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c +++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c @@ -350,18 +350,8 @@ static struct spi_driver nec_8048_spi_driver = { }, }; -static int __init nec_8048_lcd_init(void) -{ - return spi_register_driver(&nec_8048_spi_driver); -} - -static void __exit nec_8048_lcd_exit(void) -{ - return spi_unregister_driver(&nec_8048_spi_driver); -} +module_spi_driver(nec_8048_spi_driver); -module_init(nec_8048_lcd_init); -module_exit(nec_8048_lcd_exit); MODULE_AUTHOR("Erik Gilling "); MODULE_DESCRIPTION("NEC-nl8048hl11-01b Driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c index 880c313d6bc..0ca9644f9ea 100644 --- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c +++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c @@ -511,18 +511,7 @@ static struct spi_driver tpo_td043_spi_driver = { .remove = __devexit_p(tpo_td043_spi_remove), }; -static int __init tpo_td043_init(void) -{ - return spi_register_driver(&tpo_td043_spi_driver); -} - -static void __exit tpo_td043_exit(void) -{ - spi_unregister_driver(&tpo_td043_spi_driver); -} - -module_init(tpo_td043_init); -module_exit(tpo_td043_exit); +module_spi_driver(tpo_td043_spi_driver); MODULE_AUTHOR("Gražvydas Ignotas "); MODULE_DESCRIPTION("TPO TD043MTEA1 LCD Driver"); -- cgit v1.2.3-70-g09d2 From b6daa025b1e1aebf276508eb2a5a9f730391aa84 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Fri, 6 Jan 2012 14:41:31 -0600 Subject: drm/i915: set AUD_CONFIG N_value_index for DisplayPort It should be programmed to "0" for HDMI or "1" for DisplayPort. This enables DisplayPort audio for - HP EliteBook 8460p (whose BIOS does not set the N_value_index bit for us) - DisplayPort monitor hot plugged after boot (otherwise most BIOS will fill the N_value_index bit for us) Tested-by: Robert Lemaire Reviewed-by: Keith Packard Signed-off-by: Wu Fengguang Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 12 ++++++++++++ drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index bbad7885348..f4daa6e60b6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3742,4 +3742,16 @@ */ #define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4) +#define IBX_AUD_CONFIG_A 0xe2000 +#define CPT_AUD_CONFIG_A 0xe5000 +#define AUD_CONFIG_N_VALUE_INDEX (1 << 29) +#define AUD_CONFIG_N_PROG_ENABLE (1 << 28) +#define AUD_CONFIG_UPPER_N_SHIFT 20 +#define AUD_CONFIG_UPPER_N_VALUE (0xff << 20) +#define AUD_CONFIG_LOWER_N_SHIFT 4 +#define AUD_CONFIG_LOWER_N_VALUE (0xfff << 4) +#define AUD_CONFIG_PIXEL_CLOCK_HDMI_SHIFT 16 +#define AUD_CONFIG_PIXEL_CLOCK_HDMI (0xf << 16) +#define AUD_CONFIG_DISABLE_NCTS (1 << 3) + #endif /* _I915_REG_H_ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ebb34524490..0770671fa8a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6141,15 +6141,18 @@ static void ironlake_write_eld(struct drm_connector *connector, uint32_t i; int len; int hdmiw_hdmiedid; + int aud_config; int aud_cntl_st; int aud_cntrl_st2; if (HAS_PCH_IBX(connector->dev)) { hdmiw_hdmiedid = IBX_HDMIW_HDMIEDID_A; + aud_config = IBX_AUD_CONFIG_A; aud_cntl_st = IBX_AUD_CNTL_ST_A; aud_cntrl_st2 = IBX_AUD_CNTL_ST2; } else { hdmiw_hdmiedid = CPT_HDMIW_HDMIEDID_A; + aud_config = CPT_AUD_CONFIG_A; aud_cntl_st = CPT_AUD_CNTL_ST_A; aud_cntrl_st2 = CPT_AUD_CNTRL_ST2; } @@ -6157,6 +6160,7 @@ static void ironlake_write_eld(struct drm_connector *connector, i = to_intel_crtc(crtc)->pipe; hdmiw_hdmiedid += i * 0x100; aud_cntl_st += i * 0x100; + aud_config += i * 0x100; DRM_DEBUG_DRIVER("ELD on pipe %c\n", pipe_name(i)); @@ -6176,7 +6180,9 @@ static void ironlake_write_eld(struct drm_connector *connector, if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { DRM_DEBUG_DRIVER("ELD: DisplayPort detected\n"); eld[5] |= (1 << 2); /* Conn_Type, 0x1 = DisplayPort */ - } + I915_WRITE(aud_config, AUD_CONFIG_N_VALUE_INDEX); /* 0x1 = DP */ + } else + I915_WRITE(aud_config, 0); if (intel_eld_uptodate(connector, aud_cntrl_st2, eldv, -- cgit v1.2.3-70-g09d2 From 96154f2faba540281073243d61108d1705d19c6d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:00 +0100 Subject: drm/i915: switch ring->id to be a real id ... and add a helpr function for the places where we want a flag. This way we can use ring->id to index into arrays. v2: Resurrect the missing beautification-space Chris Wilson noted. I'm moving this space around because I'll reuse ring_str in the next patch. Reviewed-by: Chris Wilson Reviewed-by: Ben Widawsky Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 9 +++++---- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 4 ++-- drivers/gpu/drm/i915/i915_irq.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 14 +++++++------- drivers/gpu/drm/i915/intel_ringbuffer.h | 20 ++++++++++---------- 5 files changed, 25 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 6c3be86274e..9c5db4edd68 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -669,9 +669,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) static const char *ring_str(int ring) { switch (ring) { - case RING_RENDER: return " render"; - case RING_BSD: return " bsd"; - case RING_BLT: return " blt"; + case RCS: return "render"; + case VCS: return "bsd"; + case BCS: return "blt"; default: return ""; } } @@ -714,7 +714,7 @@ static void print_error_buffers(struct seq_file *m, seq_printf(m, "%s [%d]:\n", name, count); while (count--) { - seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s", + seq_printf(m, " %08x %8u %04x %04x %08x%s%s%s%s%s%s%s", err->gtt_offset, err->size, err->read_domains, @@ -724,6 +724,7 @@ static void print_error_buffers(struct seq_file *m, tiling_flag(err->tiling), dirty_flag(err->dirty), purgeable_flag(err->purgeable), + err->ring != -1 ? " " : "", ring_str(err->ring), cache_level_str(err->cache_level)); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index c649e0f255b..49b3ebc0e7a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -203,9 +203,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, cd->invalidate_domains |= invalidate_domains; cd->flush_domains |= flush_domains; if (flush_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= obj->ring->id; + cd->flush_rings |= intel_ring_flag(obj->ring); if (invalidate_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= ring->id; + cd->flush_rings |= intel_ring_flag(ring); } struct eb_objects { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 275ab6fecbd..ab53edb9f29 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -804,7 +804,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, err->tiling = obj->tiling_mode; err->dirty = obj->dirty; err->purgeable = obj->madv != I915_MADV_WILLNEED; - err->ring = obj->ring ? obj->ring->id : 0; + err->ring = obj->ring ? obj->ring->id : -1; err->cache_level = obj->cache_level; if (++i == count) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b3da17af899..48042f3b0ea 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -729,13 +729,13 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) */ if (IS_GEN7(dev)) { switch (ring->id) { - case RING_RENDER: + case RCS: mmio = RENDER_HWS_PGA_GEN7; break; - case RING_BLT: + case BCS: mmio = BLT_HWS_PGA_GEN7; break; - case RING_BSD: + case VCS: mmio = BSD_HWS_PGA_GEN7; break; } @@ -1199,7 +1199,7 @@ void intel_ring_advance(struct intel_ring_buffer *ring) static const struct intel_ring_buffer render_ring = { .name = "render ring", - .id = RING_RENDER, + .id = RCS, .mmio_base = RENDER_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_render_ring, @@ -1222,7 +1222,7 @@ static const struct intel_ring_buffer render_ring = { static const struct intel_ring_buffer bsd_ring = { .name = "bsd ring", - .id = RING_BSD, + .id = VCS, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_ring_common, @@ -1332,7 +1332,7 @@ gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) /* ring buffer for Video Codec for Gen6+ */ static const struct intel_ring_buffer gen6_bsd_ring = { .name = "gen6 bsd ring", - .id = RING_BSD, + .id = VCS, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, .init = init_ring_common, @@ -1467,7 +1467,7 @@ static void blt_ring_cleanup(struct intel_ring_buffer *ring) static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", - .id = RING_BLT, + .id = BCS, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, .init = blt_ring_init, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 68281c96c55..c8b9cc0cd0d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -1,13 +1,6 @@ #ifndef _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_ -enum { - RCS = 0x0, - VCS, - BCS, - I915_NUM_RINGS, -}; - struct intel_hw_status_page { u32 __iomem *page_addr; unsigned int gfx_addr; @@ -36,10 +29,11 @@ struct intel_hw_status_page { struct intel_ring_buffer { const char *name; enum intel_ring_id { - RING_RENDER = 0x1, - RING_BSD = 0x2, - RING_BLT = 0x4, + RCS = 0x0, + VCS, + BCS, } id; +#define I915_NUM_RINGS 3 u32 mmio_base; void __iomem *virtual_start; struct drm_device *dev; @@ -119,6 +113,12 @@ struct intel_ring_buffer { void *private; }; +static inline unsigned +intel_ring_flag(struct intel_ring_buffer *ring) +{ + return 1 << ring->id; +} + static inline u32 intel_ring_sync_index(struct intel_ring_buffer *ring, struct intel_ring_buffer *other) -- cgit v1.2.3-70-g09d2 From d27b1e0ec2a0a04770b2ebf70a2e01281ef93562 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:01 +0100 Subject: drm/i915: refactor ring error state capture to use arrays The code already got unwieldy and we want to dump more per-ring registers. Only functional change is that we now also capture the video ring registers on ilk. v2: fixup a refactor fumble spotted by Chris Wilson. Reviewed-by: Eugeni Dodonov Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 55 +++++++++++++++-------------- drivers/gpu/drm/i915/i915_drv.h | 20 +++-------- drivers/gpu/drm/i915/i915_irq.c | 70 +++++++++++++++++++------------------ drivers/gpu/drm/i915/i915_reg.h | 11 ++---- 4 files changed, 73 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9c5db4edd68..4002846d56a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -738,6 +738,26 @@ static void print_error_buffers(struct seq_file *m, } } +static void i915_ring_error_state(struct seq_file *m, + struct drm_device *dev, + struct drm_i915_error_state *error, + unsigned ring) +{ + seq_printf(m, "%s command stream:\n", ring_str(ring)); + seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); + seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); + seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); + seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); + if (ring == RCS) { + if (INTEL_INFO(dev)->gen >= 4) { + seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); + seq_printf(m, " INSTPS: 0x%08x\n", error->instps); + } + seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + } + seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); +} + static int i915_error_state(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -760,36 +780,19 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); seq_printf(m, "EIR: 0x%08x\n", error->eir); seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); - if (INTEL_INFO(dev)->gen >= 6) { - seq_printf(m, "ERROR: 0x%08x\n", error->error); - seq_printf(m, "Blitter command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); - seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); - seq_printf(m, "Video (BSD) command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); - seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); - } - seq_printf(m, "Render command stream:\n"); - seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); - seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); - seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); - seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); - if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); - seq_printf(m, " INSTPS: 0x%08x\n", error->instps); - } - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); - seq_printf(m, " seqno: 0x%08x\n", error->seqno); for (i = 0; i < dev_priv->num_fence_regs; i++) seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); + if (INTEL_INFO(dev)->gen >= 6) + seq_printf(m, "ERROR: 0x%08x\n", error->error); + + i915_ring_error_state(m, dev, error, RCS); + if (HAS_BLT(dev)) + i915_ring_error_state(m, dev, error, BCS); + if (HAS_BSD(dev)) + i915_ring_error_state(m, dev, error, VCS); + if (error->active_bo) print_error_buffers(m, "Active", error->active_bo, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1d10b8c26c9..766ef1c10ce 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,25 +152,15 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; - u32 ipeir; - u32 ipehr; - u32 instdone; - u32 acthd; + u32 ipeir[I915_NUM_RINGS]; + u32 ipehr[I915_NUM_RINGS]; + u32 instdone[I915_NUM_RINGS]; + u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 bcs_acthd; /* gen6+ blt engine */ - u32 bcs_ipehr; - u32 bcs_ipeir; - u32 bcs_instdone; - u32 bcs_seqno; - u32 vcs_acthd; /* gen6+ bsd engine */ - u32 vcs_ipehr; - u32 vcs_ipeir; - u32 vcs_instdone; - u32 vcs_seqno; u32 instpm; u32 instps; u32 instdone1; - u32 seqno; + u32 seqno[I915_NUM_RINGS]; u64 bbaddr; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ab53edb9f29..dffeef870b3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -876,6 +876,32 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv, return NULL; } +static void i915_record_ring_state(struct drm_device *dev, + struct drm_i915_error_state *error, + struct intel_ring_buffer *ring) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (INTEL_INFO(dev)->gen >= 4) { + error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); + error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); + error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); + if (ring->id == RCS) { + error->instps = I915_READ(INSTPS); + error->instdone1 = I915_READ(INSTDONE1); + error->bbaddr = I915_READ64(BB_ADDR); + } + } else { + error->ipeir[ring->id] = I915_READ(IPEIR); + error->ipehr[ring->id] = I915_READ(IPEHR); + error->instdone[ring->id] = I915_READ(INSTDONE); + error->bbaddr = 0; + } + + error->seqno[ring->id] = ring->get_seqno(ring); + error->acthd[ring->id] = intel_ring_get_active_head(ring); +} + /** * i915_capture_error_state - capture an error record for later analysis * @dev: drm device @@ -909,47 +935,23 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_INFO("capturing error event; look for more information in /debug/dri/%d/i915_error_state\n", dev->primary->index); - error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); error->instpm = I915_READ(INSTPM); - error->error = 0; - if (INTEL_INFO(dev)->gen >= 6) { + + if (INTEL_INFO(dev)->gen >= 6) error->error = I915_READ(ERROR_GEN6); + else + error->error = 0; + + i915_record_ring_state(dev, error, &dev_priv->ring[RCS]); + if (HAS_BLT(dev)) + i915_record_ring_state(dev, error, &dev_priv->ring[BCS]); + if (HAS_BSD(dev)) + i915_record_ring_state(dev, error, &dev_priv->ring[VCS]); - error->bcs_acthd = I915_READ(BCS_ACTHD); - error->bcs_ipehr = I915_READ(BCS_IPEHR); - error->bcs_ipeir = I915_READ(BCS_IPEIR); - error->bcs_instdone = I915_READ(BCS_INSTDONE); - error->bcs_seqno = 0; - if (dev_priv->ring[BCS].get_seqno) - error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]); - - error->vcs_acthd = I915_READ(VCS_ACTHD); - error->vcs_ipehr = I915_READ(VCS_IPEHR); - error->vcs_ipeir = I915_READ(VCS_IPEIR); - error->vcs_instdone = I915_READ(VCS_INSTDONE); - error->vcs_seqno = 0; - if (dev_priv->ring[VCS].get_seqno) - error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]); - } - if (INTEL_INFO(dev)->gen >= 4) { - error->ipeir = I915_READ(IPEIR_I965); - error->ipehr = I915_READ(IPEHR_I965); - error->instdone = I915_READ(INSTDONE_I965); - error->instps = I915_READ(INSTPS); - error->instdone1 = I915_READ(INSTDONE1); - error->acthd = I915_READ(ACTHD_I965); - error->bbaddr = I915_READ64(BB_ADDR); - } else { - error->ipeir = I915_READ(IPEIR); - error->ipehr = I915_READ(IPEHR); - error->instdone = I915_READ(INSTDONE); - error->acthd = I915_READ(ACTHD); - error->bbaddr = 0; - } i915_gem_record_fences(dev, error); /* Record the active batch and ring buffers */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index f4daa6e60b6..80febc55a0c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -352,6 +352,9 @@ #define IPEIR_I965 0x02064 #define IPEHR_I965 0x02068 #define INSTDONE_I965 0x0206c +#define RING_IPEIR(base) ((base)+0x64) +#define RING_IPEHR(base) ((base)+0x68) +#define RING_INSTDONE(base) ((base)+0x6c) #define INSTPS 0x02070 /* 965+ only */ #define INSTDONE1 0x0207c /* 965+ only */ #define ACTHD_I965 0x02074 @@ -365,14 +368,6 @@ #define INSTDONE 0x02090 #define NOPID 0x02094 #define HWSTAM 0x02098 -#define VCS_INSTDONE 0x1206C -#define VCS_IPEIR 0x12064 -#define VCS_IPEHR 0x12068 -#define VCS_ACTHD 0x12074 -#define BCS_INSTDONE 0x2206C -#define BCS_IPEIR 0x22064 -#define BCS_IPEHR 0x22068 -#define BCS_ACTHD 0x22074 #define ERROR_GEN6 0x040a0 -- cgit v1.2.3-70-g09d2 From c1cd90ed7957d1dd8aa6138468d71003fbc095ce Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:02 +0100 Subject: drm/i915: collect more per ring error state Based on a patch by Ben Widawsky, but with different colors for the bikeshed. In contrast to Ben's patch this one doesn't add the fault regs. Afaics they're for the optional page fault support which - we're not enabling - and which seems to be unsupported by the hw team. Recent bspec lacks tons of information about this that the public docs released half a year back still contain. Also dump ring HEAD/TAIL registers - I've recently seen a few error_state where just guessing these is not good enough. v2: Also dump INSTPM for every ring. v3: Fix a few really silly goof-ups spotted by Chris Wilson. Reviewed-by: Eugeni Dodonov Reviewed-by: Chris Wilson Signed-off-by: Ben Widawsky Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 16 ++++++++++------ drivers/gpu/drm/i915/i915_drv.h | 7 +++++-- drivers/gpu/drm/i915/i915_irq.c | 9 +++++++-- drivers/gpu/drm/i915/i915_reg.h | 3 +++ 4 files changed, 25 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4002846d56a..5aa256861df 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -744,17 +744,21 @@ static void i915_ring_error_state(struct seq_file *m, unsigned ring) { seq_printf(m, "%s command stream:\n", ring_str(ring)); + seq_printf(m, " HEAD: 0x%08x\n", error->head[ring]); + seq_printf(m, " TAIL: 0x%08x\n", error->tail[ring]); seq_printf(m, " ACTHD: 0x%08x\n", error->acthd[ring]); seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir[ring]); seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr[ring]); seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone[ring]); - if (ring == RCS) { - if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); - seq_printf(m, " INSTPS: 0x%08x\n", error->instps); - } - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + if (ring == RCS && INTEL_INFO(dev)->gen >= 4) { + seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); + seq_printf(m, " BBADDR: 0x%08llx\n", error->bbaddr); } + if (INTEL_INFO(dev)->gen >= 4) + seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); + seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); + if (INTEL_INFO(dev)->gen >= 6) + seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 766ef1c10ce..733f5f57bab 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -152,16 +152,19 @@ struct drm_i915_error_state { u32 eir; u32 pgtbl_er; u32 pipestat[I915_MAX_PIPES]; + u32 tail[I915_NUM_RINGS]; + u32 head[I915_NUM_RINGS]; u32 ipeir[I915_NUM_RINGS]; u32 ipehr[I915_NUM_RINGS]; u32 instdone[I915_NUM_RINGS]; u32 acthd[I915_NUM_RINGS]; u32 error; /* gen6+ */ - u32 instpm; - u32 instps; + u32 instpm[I915_NUM_RINGS]; + u32 instps[I915_NUM_RINGS]; u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; struct drm_i915_error_object { diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index dffeef870b3..1e75c44af56 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -882,12 +882,15 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; + if (INTEL_INFO(dev)->gen >= 6) + error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); + if (INTEL_INFO(dev)->gen >= 4) { error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); error->ipehr[ring->id] = I915_READ(RING_IPEHR(ring->mmio_base)); error->instdone[ring->id] = I915_READ(RING_INSTDONE(ring->mmio_base)); + error->instps[ring->id] = I915_READ(RING_INSTPS(ring->mmio_base)); if (ring->id == RCS) { - error->instps = I915_READ(INSTPS); error->instdone1 = I915_READ(INSTDONE1); error->bbaddr = I915_READ64(BB_ADDR); } @@ -898,8 +901,11 @@ static void i915_record_ring_state(struct drm_device *dev, error->bbaddr = 0; } + error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); error->seqno[ring->id] = ring->get_seqno(ring); error->acthd[ring->id] = intel_ring_get_active_head(ring); + error->head[ring->id] = I915_READ_HEAD(ring); + error->tail[ring->id] = I915_READ_TAIL(ring); } /** @@ -939,7 +945,6 @@ static void i915_capture_error_state(struct drm_device *dev) error->pgtbl_er = I915_READ(PGTBL_ER); for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - error->instpm = I915_READ(INSTPM); if (INTEL_INFO(dev)->gen >= 6) error->error = I915_READ(ERROR_GEN6); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 80febc55a0c..d107a1d756a 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -355,6 +355,9 @@ #define RING_IPEIR(base) ((base)+0x64) #define RING_IPEHR(base) ((base)+0x68) #define RING_INSTDONE(base) ((base)+0x6c) +#define RING_INSTPS(base) ((base)+0x70) +#define RING_DMA_FADD(base) ((base)+0x78) +#define RING_INSTPM(base) ((base)+0xc0) #define INSTPS 0x02070 /* 965+ only */ #define INSTDONE1 0x0207c /* 965+ only */ #define ACTHD_I965 0x02074 -- cgit v1.2.3-70-g09d2 From 6a233c78878d8795517d716544d045d5675b3061 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:07 +0100 Subject: drm/i915/ringbuffer: kill snb blt workaround This was just to facilitate product enablement with pre-production hw. Allows us to kill quite a bit of cruft. Signed-off-by: Kenneth Graunke Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ringbuffer.c | 81 +-------------------------------- 1 file changed, 2 insertions(+), 79 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 48042f3b0ea..6e80f836835 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1368,79 +1368,13 @@ blt_ring_put_irq(struct intel_ring_buffer *ring) GEN6_BLITTER_USER_INTERRUPT); } - -/* Workaround for some stepping of SNB, - * each time when BLT engine ring tail moved, - * the first command in the ring to be parsed - * should be MI_BATCH_BUFFER_START - */ -#define NEED_BLT_WORKAROUND(dev) \ - (IS_GEN6(dev) && (dev->pdev->revision < 8)) - -static inline struct drm_i915_gem_object * -to_blt_workaround(struct intel_ring_buffer *ring) -{ - return ring->private; -} - -static int blt_ring_init(struct intel_ring_buffer *ring) -{ - if (NEED_BLT_WORKAROUND(ring->dev)) { - struct drm_i915_gem_object *obj; - u32 *ptr; - int ret; - - obj = i915_gem_alloc_object(ring->dev, 4096); - if (obj == NULL) - return -ENOMEM; - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) { - drm_gem_object_unreference(&obj->base); - return ret; - } - - ptr = kmap(obj->pages[0]); - *ptr++ = MI_BATCH_BUFFER_END; - *ptr++ = MI_NOOP; - kunmap(obj->pages[0]); - - ret = i915_gem_object_set_to_gtt_domain(obj, false); - if (ret) { - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - return ret; - } - - ring->private = obj; - } - - return init_ring_common(ring); -} - -static int blt_ring_begin(struct intel_ring_buffer *ring, - int num_dwords) -{ - if (ring->private) { - int ret = intel_ring_begin(ring, num_dwords+2); - if (ret) - return ret; - - intel_ring_emit(ring, MI_BATCH_BUFFER_START); - intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset); - - return 0; - } else - return intel_ring_begin(ring, 4); -} - static int blt_ring_flush(struct intel_ring_buffer *ring, u32 invalidate, u32 flush) { uint32_t cmd; int ret; - ret = blt_ring_begin(ring, 4); + ret = intel_ring_begin(ring, 4); if (ret) return ret; @@ -1455,22 +1389,12 @@ static int blt_ring_flush(struct intel_ring_buffer *ring, return 0; } -static void blt_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - i915_gem_object_unpin(ring->private); - drm_gem_object_unreference(ring->private); - ring->private = NULL; -} - static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = BCS, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = blt_ring_init, + .init = init_ring_common, .write_tail = ring_write_tail, .flush = blt_ring_flush, .add_request = gen6_add_request, @@ -1478,7 +1402,6 @@ static const struct intel_ring_buffer gen6_blt_ring = { .irq_get = blt_ring_get_irq, .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, - .cleanup = blt_ring_cleanup, .sync_to = gen6_blt_ring_sync_to, .semaphore_register = {MI_SEMAPHORE_SYNC_BR, MI_SEMAPHORE_SYNC_BV, -- cgit v1.2.3-70-g09d2 From 1690e1eb7a9021826853e181baa48dd77090da28 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 14 Dec 2011 13:57:08 +0100 Subject: drm/i915: Separate fence pin counting from normal bind pin counting In order to correctly account for reserving space in the GTT and fences for a batch buffer, we need to independently track whether the fence is pinned due to a fenced GPU access in the batch or whether the buffer is pinned in the aperture. Currently we count the fenced as pinned if the buffer has already been seen in the execbuffer. This leads to a false accounting of available fence registers, causing frequent mass evictions. Worse, if coupled with the change to make i915_gem_object_get_fence() report EDADLK upon fence starvation, the batchbuffer can fail with only one fence required... Fixes intel-gpu-tools/tests/gem_fenced_exec_thrash Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38735 Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Tested-by: Paul Neumann [danvet: Resolve the functional conflict with Jesse Barnes sprite patches, acked by Chris Wilson on irc.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 19 ++++ drivers/gpu/drm/i915/i915_gem.c | 7 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 139 +++++++++++++++++++---------- drivers/gpu/drm/i915/intel_display.c | 16 +++- drivers/gpu/drm/i915/intel_drv.h | 1 + drivers/gpu/drm/i915/intel_sprite.c | 4 +- 6 files changed, 129 insertions(+), 57 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 733f5f57bab..12e8cce7928 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -135,6 +135,7 @@ struct drm_i915_fence_reg { struct list_head lru_list; struct drm_i915_gem_object *obj; uint32_t setup_seqno; + int pin_count; }; struct sdvo_device_mapping { @@ -1159,6 +1160,24 @@ int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); +static inline void +i915_gem_object_pin_fence(struct drm_i915_gem_object *obj) +{ + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + dev_priv->fence_regs[obj->fence_reg].pin_count++; + } +} + +static inline void +i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj) +{ + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + dev_priv->fence_regs[obj->fence_reg].pin_count--; + } +} + void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); void i915_gem_clflush_object(struct drm_i915_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ff3066c4c76..c78930ed2e8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2435,6 +2435,8 @@ i915_gem_object_put_fence(struct drm_i915_gem_object *obj) if (obj->fence_reg != I915_FENCE_REG_NONE) { struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + + WARN_ON(dev_priv->fence_regs[obj->fence_reg].pin_count); i915_gem_clear_fence_reg(obj->base.dev, &dev_priv->fence_regs[obj->fence_reg]); @@ -2459,7 +2461,7 @@ i915_find_fence_reg(struct drm_device *dev, if (!reg->obj) return reg; - if (!reg->obj->pin_count) + if (!reg->pin_count) avail = reg; } @@ -2469,7 +2471,7 @@ i915_find_fence_reg(struct drm_device *dev, /* None available, try to steal one or wait for a user to finish */ avail = first = NULL; list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { - if (reg->obj->pin_count) + if (reg->pin_count) continue; if (first == NULL) @@ -2664,6 +2666,7 @@ i915_gem_clear_fence_reg(struct drm_device *dev, list_del_init(®->lru_list); reg->obj = NULL; reg->setup_seqno = 0; + reg->pin_count = 0; } /** diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 49b3ebc0e7a..4a43ef5dba3 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -461,6 +461,54 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, return ret; } +#define __EXEC_OBJECT_HAS_FENCE (1<<31) + +static int +pin_and_fence_object(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring) +{ + struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; + bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; + bool need_fence, need_mappable; + int ret; + + need_fence = + has_fenced_gpu_access && + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + need_mappable = + entry->relocation_count ? true : need_fence; + + ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); + if (ret) + return ret; + + if (has_fenced_gpu_access) { + if (entry->flags & EXEC_OBJECT_NEEDS_FENCE) { + if (obj->tiling_mode) { + ret = i915_gem_object_get_fence(obj, ring); + if (ret) + goto err_unpin; + + entry->flags |= __EXEC_OBJECT_HAS_FENCE; + i915_gem_object_pin_fence(obj); + } else { + ret = i915_gem_object_put_fence(obj); + if (ret) + goto err_unpin; + } + } + obj->pending_fenced_gpu_access = need_fence; + } + + entry->offset = obj->gtt_offset; + return 0; + +err_unpin: + i915_gem_object_unpin(obj); + return ret; +} + static int i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_file *file, @@ -518,6 +566,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, list_for_each_entry(obj, objects, exec_list) { struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; bool need_fence, need_mappable; + if (!obj->gtt_space) continue; @@ -532,58 +581,47 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, (need_mappable && !obj->map_and_fenceable)) ret = i915_gem_object_unbind(obj); else - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); + ret = pin_and_fence_object(obj, ring); if (ret) goto err; - - entry++; } /* Bind fresh objects */ list_for_each_entry(obj, objects, exec_list) { - struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; - bool need_fence; - - need_fence = - has_fenced_gpu_access && - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - - if (!obj->gtt_space) { - bool need_mappable = - entry->relocation_count ? true : need_fence; - - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); - if (ret) - break; - } + if (obj->gtt_space) + continue; - if (has_fenced_gpu_access) { - if (need_fence) { - ret = i915_gem_object_get_fence(obj, ring); - if (ret) - break; - } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode == I915_TILING_NONE) { - /* XXX pipelined! */ - ret = i915_gem_object_put_fence(obj); - if (ret) - break; - } - obj->pending_fenced_gpu_access = need_fence; + ret = pin_and_fence_object(obj, ring); + if (ret) { + int ret_ignore; + + /* This can potentially raise a harmless + * -EINVAL if we failed to bind in the above + * call. It cannot raise -EINTR since we know + * that the bo is freshly bound and so will + * not need to be flushed or waited upon. + */ + ret_ignore = i915_gem_object_unbind(obj); + (void)ret_ignore; + WARN_ON(obj->gtt_space); + break; } - - entry->offset = obj->gtt_offset; } /* Decrement pin count for bound objects */ list_for_each_entry(obj, objects, exec_list) { - if (obj->gtt_space) - i915_gem_object_unpin(obj); + struct drm_i915_gem_exec_object2 *entry; + + if (!obj->gtt_space) + continue; + + entry = obj->exec_entry; + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { + i915_gem_object_unpin_fence(obj); + entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; + } + + i915_gem_object_unpin(obj); } if (ret != -ENOSPC || retry > 1) @@ -600,16 +638,19 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, } while (1); err: - obj = list_entry(obj->exec_list.prev, - struct drm_i915_gem_object, - exec_list); - while (objects != &obj->exec_list) { - if (obj->gtt_space) - i915_gem_object_unpin(obj); + list_for_each_entry_continue_reverse(obj, objects, exec_list) { + struct drm_i915_gem_exec_object2 *entry; + + if (!obj->gtt_space) + continue; + + entry = obj->exec_entry; + if (entry->flags & __EXEC_OBJECT_HAS_FENCE) { + i915_gem_object_unpin_fence(obj); + entry->flags &= ~__EXEC_OBJECT_HAS_FENCE; + } - obj = list_entry(obj->exec_list.prev, - struct drm_i915_gem_object, - exec_list); + i915_gem_object_unpin(obj); } return ret; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0770671fa8a..fc9bc19f6db 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2041,6 +2041,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, ret = i915_gem_object_get_fence(obj, pipelined); if (ret) goto err_unpin; + + i915_gem_object_pin_fence(obj); } dev_priv->mm.interruptible = true; @@ -2053,6 +2055,12 @@ err_interruptible: return ret; } +void intel_unpin_fb_obj(struct drm_i915_gem_object *obj) +{ + i915_gem_object_unpin_fence(obj); + i915_gem_object_unpin(obj); +} + static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb, int x, int y) { @@ -2284,7 +2292,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, ret = intel_pipe_set_base_atomic(crtc, crtc->fb, x, y, LEAVE_ATOMIC_MODE_SET); if (ret) { - i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); DRM_ERROR("failed to update base address\n"); return ret; @@ -2292,7 +2300,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (old_fb) { intel_wait_for_vblank(dev, intel_crtc->pipe); - i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(old_fb)->obj); } mutex_unlock(&dev->struct_mutex); @@ -3355,7 +3363,7 @@ static void intel_crtc_disable(struct drm_crtc *crtc) if (crtc->fb) { mutex_lock(&dev->struct_mutex); - i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); + intel_unpin_fb_obj(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); } } @@ -7158,7 +7166,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) container_of(__work, struct intel_unpin_work, work); mutex_lock(&work->dev->struct_mutex); - i915_gem_object_unpin(work->old_fb_obj); + intel_unpin_fb_obj(work->old_fb_obj); drm_gem_object_unreference(&work->pending_flip_obj->base); drm_gem_object_unreference(&work->old_fb_obj->base); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 1348705faf6..9cec6c3937f 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -374,6 +374,7 @@ extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); +extern void intel_unpin_fb_obj(struct drm_i915_gem_object *obj); extern int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index d13989fda50..ad3bd929aec 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c @@ -503,7 +503,7 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, intel_wait_for_vblank(dev, to_intel_crtc(crtc)->pipe); mutex_lock(&dev->struct_mutex); } - i915_gem_object_unpin(old_obj); + intel_unpin_fb_obj(old_obj); } out_unlock: @@ -530,7 +530,7 @@ intel_disable_plane(struct drm_plane *plane) goto out; mutex_lock(&dev->struct_mutex); - i915_gem_object_unpin(intel_plane->obj); + intel_unpin_fb_obj(intel_plane->obj); intel_plane->obj = NULL; mutex_unlock(&dev->struct_mutex); out: -- cgit v1.2.3-70-g09d2 From 39965b376601314ba374b8fa3944f5957d4ff2de Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:09 +0100 Subject: drm/i915: don't trash the gtt when running out of fences With the fence accounting fixed up in the previous commit not finding enough fences is a fatal error and userspace bug. Trashing the entire gtt is not gonna turn up that missing fence, so don't to this by returning another error thatn ENOSPC. This has the added benefit that it's easier to distinguish fence accounting errors from gtt space accounting issues. TTM serves as precendence for the EDEADLK error code - it returns it when the reservation code needs resources already blocked by the current reservation. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c78930ed2e8..721924150d0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2566,7 +2566,7 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, reg = i915_find_fence_reg(dev, pipelined); if (reg == NULL) - return -ENOSPC; + return -EDEADLK; ret = i915_gem_object_flush_fence(obj, pipelined); if (ret) -- cgit v1.2.3-70-g09d2 From 08e14e80d0229262063139a95209fa0dc354feaa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:10 +0100 Subject: drm/i915: refactor debugfs open function Only forcewake has an open with special semantics, the other r/w debugfs only assign the file private pointer. Reviewed-by: Ben Widawsky Reviewed-by: Kenneth Graunke Reviewed-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 26 +++++--------------------- 1 file changed, 5 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5aa256861df..37740429600 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1415,8 +1415,8 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) } static int -i915_wedged_open(struct inode *inode, - struct file *filp) +i915_debugfs_common_open(struct inode *inode, + struct file *filp) { filp->private_data = inode->i_private; return 0; @@ -1472,20 +1472,12 @@ i915_wedged_write(struct file *filp, static const struct file_operations i915_wedged_fops = { .owner = THIS_MODULE, - .open = i915_wedged_open, + .open = i915_debugfs_common_open, .read = i915_wedged_read, .write = i915_wedged_write, .llseek = default_llseek, }; -static int -i915_max_freq_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t i915_max_freq_read(struct file *filp, char __user *ubuf, @@ -1542,20 +1534,12 @@ i915_max_freq_write(struct file *filp, static const struct file_operations i915_max_freq_fops = { .owner = THIS_MODULE, - .open = i915_max_freq_open, + .open = i915_debugfs_common_open, .read = i915_max_freq_read, .write = i915_max_freq_write, .llseek = default_llseek, }; -static int -i915_cache_sharing_open(struct inode *inode, - struct file *filp) -{ - filp->private_data = inode->i_private; - return 0; -} - static ssize_t i915_cache_sharing_read(struct file *filp, char __user *ubuf, @@ -1621,7 +1605,7 @@ i915_cache_sharing_write(struct file *filp, static const struct file_operations i915_cache_sharing_fops = { .owner = THIS_MODULE, - .open = i915_cache_sharing_open, + .open = i915_debugfs_common_open, .read = i915_cache_sharing_read, .write = i915_cache_sharing_write, .llseek = default_llseek, -- cgit v1.2.3-70-g09d2 From 6a9c308de0332b873720c629cb88f58d154b4f1d Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:11 +0100 Subject: drm/i915: refactor debugfs create functions All r/w debugfs files are created equal. v2: Add some newlines to make the code easier on the eyes as requested by Ben Widawsky. Reviewed-by: Ben Widawsky Reviewed-by: Kenneth Graunke Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 55 ++++++++++++------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 37740429600..9a2f3fcd220 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1637,21 +1637,6 @@ drm_add_fake_info_node(struct drm_minor *minor, return 0; } -static int i915_wedged_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_wedged", - S_IRUGO | S_IWUSR, - root, dev, - &i915_wedged_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_wedged_fops); -} - static int i915_forcewake_open(struct inode *inode, struct file *file) { struct drm_device *dev = inode->i_private; @@ -1713,34 +1698,22 @@ static int i915_forcewake_create(struct dentry *root, struct drm_minor *minor) return drm_add_fake_info_node(minor, ent, &i915_forcewake_fops); } -static int i915_max_freq_create(struct dentry *root, struct drm_minor *minor) -{ - struct drm_device *dev = minor->dev; - struct dentry *ent; - - ent = debugfs_create_file("i915_max_freq", - S_IRUGO | S_IWUSR, - root, dev, - &i915_max_freq_fops); - if (IS_ERR(ent)) - return PTR_ERR(ent); - - return drm_add_fake_info_node(minor, ent, &i915_max_freq_fops); -} - -static int i915_cache_sharing_create(struct dentry *root, struct drm_minor *minor) +static int i915_debugfs_create(struct dentry *root, + struct drm_minor *minor, + const char *name, + const struct file_operations *fops) { struct drm_device *dev = minor->dev; struct dentry *ent; - ent = debugfs_create_file("i915_cache_sharing", + ent = debugfs_create_file(name, S_IRUGO | S_IWUSR, root, dev, - &i915_cache_sharing_fops); + fops); if (IS_ERR(ent)) return PTR_ERR(ent); - return drm_add_fake_info_node(minor, ent, &i915_cache_sharing_fops); + return drm_add_fake_info_node(minor, ent, fops); } static struct drm_info_list i915_debugfs_list[] = { @@ -1789,17 +1762,25 @@ int i915_debugfs_init(struct drm_minor *minor) { int ret; - ret = i915_wedged_create(minor->debugfs_root, minor); + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_wedged", + &i915_wedged_fops); if (ret) return ret; ret = i915_forcewake_create(minor->debugfs_root, minor); if (ret) return ret; - ret = i915_max_freq_create(minor->debugfs_root, minor); + + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_max_freq", + &i915_max_freq_fops); if (ret) return ret; - ret = i915_cache_sharing_create(minor->debugfs_root, minor); + + ret = i915_debugfs_create(minor->debugfs_root, minor, + "i915_cache_sharing", + &i915_cache_sharing_fops); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From 653d7bed26a0c298dee7d60f6ab4bb442acf8b82 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:21 +0100 Subject: drm/i915: capture error_state also for stuck rings Since quite a while we also the basic output configuration in the error_state, so it should contain enough information to diagnose these MI_WAIT hangs. Reviewed-and-tested-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 1e75c44af56..4dedb314806 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1706,6 +1706,7 @@ void i915_hangcheck_elapsed(unsigned long data) dev_priv->last_instdone1 == instdone1) { if (dev_priv->hangcheck_count++ > 1) { DRM_ERROR("Hangcheck timer elapsed... GPU hung\n"); + i915_handle_error(dev, true); if (!IS_GEN2(dev)) { /* Is the chip hanging on a WAIT_FOR_EVENT? @@ -1713,7 +1714,6 @@ void i915_hangcheck_elapsed(unsigned long data) * and break the hang. This should work on * all but the second generation chipsets. */ - if (kick_ring(&dev_priv->ring[RCS])) goto repeat; @@ -1726,7 +1726,6 @@ void i915_hangcheck_elapsed(unsigned long data) goto repeat; } - i915_handle_error(dev, true); return; } } else { -- cgit v1.2.3-70-g09d2 From ff865f79764ca43bc601ff5a2499738451fc96dd Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:26 +0100 Subject: drm/i915: remove the i915_batchbuffer_info debugfs file With the error_state facility in place, this has outlived it's usefulness. It also oopses with the lates llc-reloc patches because it directly access objects through the gtt without any checks. Reviewed-by: Chris Wilson Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 40 ------------------------------------- 1 file changed, 40 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9a2f3fcd220..f0486059e44 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -564,45 +564,6 @@ static int i915_hws_info(struct seq_file *m, void *data) return 0; } -static void i915_dump_object(struct seq_file *m, - struct io_mapping *mapping, - struct drm_i915_gem_object *obj) -{ - int page, page_count, i; - - page_count = obj->base.size / PAGE_SIZE; - for (page = 0; page < page_count; page++) { - u32 *mem = io_mapping_map_wc(mapping, - obj->gtt_offset + page * PAGE_SIZE); - for (i = 0; i < PAGE_SIZE; i += 4) - seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); - io_mapping_unmap(mem); - } -} - -static int i915_batchbuffer_info(struct seq_file *m, void *data) -{ - struct drm_info_node *node = (struct drm_info_node *) m->private; - struct drm_device *dev = node->minor->dev; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret; - - ret = mutex_lock_interruptible(&dev->struct_mutex); - if (ret) - return ret; - - list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { - if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { - seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); - i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); - } - } - - mutex_unlock(&dev->struct_mutex); - return 0; -} - static int i915_ringbuffer_data(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -1739,7 +1700,6 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, - {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0}, {"i915_cur_delayinfo", i915_cur_delayinfo, 0}, -- cgit v1.2.3-70-g09d2 From 4ca4a250ac93d5538a2a5c98ee2bcf9195f38be4 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:27 +0100 Subject: drm/i915: reject GTT domain in relocations This confuses our domain tracking and can (for gtt write domains) lead to a subsequent oops. Tested by tests/gem_exec_bad_domains from i-g-t. Reviewed-by: Eric Anholt Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 4a43ef5dba3..123c51445a8 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -303,8 +303,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, reloc->write_domain); return ret; } - if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) { - DRM_ERROR("reloc with read/write CPU domains: " + if (unlikely((reloc->write_domain | reloc->read_domains) + & ~I915_GEM_GPU_DOMAINS)) { + DRM_ERROR("reloc with read/write non-GPU domains: " "obj %p target %d offset %d " "read %08x write %08x", obj, reloc->target_handle, -- cgit v1.2.3-70-g09d2 From cf579dfb82550e34de7ccf3ef090d8b834ccd3a9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:38:29 +0100 Subject: PM / Sleep: Introduce "late suspend" and "early resume" of devices The current device suspend/resume phases during system-wide power transitions appear to be insufficient for some platforms that want to use the same callback routines for saving device states and related operations during runtime suspend/resume as well as during system suspend/resume. In principle, they could point their .suspend_noirq() and .resume_noirq() to the same callback routines as their .runtime_suspend() and .runtime_resume(), respectively, but at least some of them require device interrupts to be enabled while the code in those routines is running. It also makes sense to have device suspend-resume callbacks that will be executed with runtime PM disabled and with device interrupts enabled in case someone needs to run some special code in that context during system-wide power transitions. Apart from this, .suspend_noirq() and .resume_noirq() were introduced as a workaround for drivers using shared interrupts and failing to prevent their interrupt handlers from accessing suspended hardware. It appears to be better not to use them for other porposes, or we may have to deal with some serious confusion (which seems to be happening already). For the above reasons, introduce new device suspend/resume phases, "late suspend" and "early resume" (and analogously for hibernation) whose callback will be executed with runtime PM disabled and with device interrupts enabled and whose callback pointers generally may point to runtime suspend/resume routines. Signed-off-by: Rafael J. Wysocki Reviewed-by: Mark Brown Reviewed-by: Kevin Hilman --- Documentation/power/devices.txt | 93 +++++++++------ arch/x86/kernel/apm_32.c | 11 +- drivers/base/power/main.c | 247 ++++++++++++++++++++++++++++++++++++---- drivers/xen/manage.c | 6 +- include/linux/pm.h | 43 +++++-- include/linux/suspend.h | 4 + kernel/kexec.c | 8 +- kernel/power/hibernate.c | 24 ++-- kernel/power/main.c | 8 +- kernel/power/suspend.c | 4 +- 10 files changed, 357 insertions(+), 91 deletions(-) (limited to 'drivers') diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 20af7def23c..872815cd41d 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt @@ -96,6 +96,12 @@ struct dev_pm_ops { int (*thaw)(struct device *dev); int (*poweroff)(struct device *dev); int (*restore)(struct device *dev); + int (*suspend_late)(struct device *dev); + int (*resume_early)(struct device *dev); + int (*freeze_late)(struct device *dev); + int (*thaw_early)(struct device *dev); + int (*poweroff_late)(struct device *dev); + int (*restore_early)(struct device *dev); int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*freeze_noirq)(struct device *dev); @@ -305,7 +311,7 @@ Entering System Suspend ----------------------- When the system goes into the standby or memory sleep state, the phases are: - prepare, suspend, suspend_noirq. + prepare, suspend, suspend_late, suspend_noirq. 1. The prepare phase is meant to prevent races by preventing new devices from being registered; the PM core would never know that all the @@ -324,7 +330,12 @@ When the system goes into the standby or memory sleep state, the phases are: appropriate low-power state, depending on the bus type the device is on, and they may enable wakeup events. - 3. The suspend_noirq phase occurs after IRQ handlers have been disabled, + 3 For a number of devices it is convenient to split suspend into the + "quiesce device" and "save device state" phases, in which cases + suspend_late is meant to do the latter. It is always executed after + runtime power management has been disabled for all devices. + + 4. The suspend_noirq phase occurs after IRQ handlers have been disabled, which means that the driver's interrupt handler will not be called while the callback method is running. The methods should save the values of the device's registers that weren't saved previously and finally put the @@ -359,7 +370,7 @@ Leaving System Suspend ---------------------- When resuming from standby or memory sleep, the phases are: - resume_noirq, resume, complete. + resume_noirq, resume_early, resume, complete. 1. The resume_noirq callback methods should perform any actions needed before the driver's interrupt handlers are invoked. This generally @@ -375,14 +386,18 @@ When resuming from standby or memory sleep, the phases are: device driver's ->pm.resume_noirq() method to perform device-specific actions. - 2. The resume methods should bring the the device back to its operating + 2. The resume_early methods should prepare devices for the execution of + the resume methods. This generally involves undoing the actions of the + preceding suspend_late phase. + + 3 The resume methods should bring the the device back to its operating state, so that it can perform normal I/O. This generally involves undoing the actions of the suspend phase. - 3. The complete phase uses only a bus callback. The method should undo the - actions of the prepare phase. Note, however, that new children may be - registered below the device as soon as the resume callbacks occur; it's - not necessary to wait until the complete phase. + 4. The complete phase should undo the actions of the prepare phase. Note, + however, that new children may be registered below the device as soon as + the resume callbacks occur; it's not necessary to wait until the + complete phase. At the end of these phases, drivers should be as functional as they were before suspending: I/O can be performed using DMA and IRQs, and the relevant clocks are @@ -429,8 +444,8 @@ an image of the system memory while everything is stable, reactivate all devices (thaw), write the image to permanent storage, and finally shut down the system (poweroff). The phases used to accomplish this are: - prepare, freeze, freeze_noirq, thaw_noirq, thaw, complete, - prepare, poweroff, poweroff_noirq + prepare, freeze, freeze_late, freeze_noirq, thaw_noirq, thaw_early, + thaw, complete, prepare, poweroff, poweroff_late, poweroff_noirq 1. The prepare phase is discussed in the "Entering System Suspend" section above. @@ -441,7 +456,11 @@ system (poweroff). The phases used to accomplish this are: save time it's best not to do so. Also, the device should not be prepared to generate wakeup events. - 3. The freeze_noirq phase is analogous to the suspend_noirq phase discussed + 3. The freeze_late phase is analogous to the suspend_late phase described + above, except that the device should not be put in a low-power state and + should not be allowed to generate wakeup events by it. + + 4. The freeze_noirq phase is analogous to the suspend_noirq phase discussed above, except again that the device should not be put in a low-power state and should not be allowed to generate wakeup events. @@ -449,15 +468,19 @@ At this point the system image is created. All devices should be inactive and the contents of memory should remain undisturbed while this happens, so that the image forms an atomic snapshot of the system state. - 4. The thaw_noirq phase is analogous to the resume_noirq phase discussed + 5. The thaw_noirq phase is analogous to the resume_noirq phase discussed above. The main difference is that its methods can assume the device is in the same state as at the end of the freeze_noirq phase. - 5. The thaw phase is analogous to the resume phase discussed above. Its + 6. The thaw_early phase is analogous to the resume_early phase described + above. Its methods should undo the actions of the preceding + freeze_late, if necessary. + + 7. The thaw phase is analogous to the resume phase discussed above. Its methods should bring the device back to an operating state, so that it can be used for saving the image if necessary. - 6. The complete phase is discussed in the "Leaving System Suspend" section + 8. The complete phase is discussed in the "Leaving System Suspend" section above. At this point the system image is saved, and the devices then need to be @@ -465,16 +488,19 @@ prepared for the upcoming system shutdown. This is much like suspending them before putting the system into the standby or memory sleep state, and the phases are similar. - 7. The prepare phase is discussed above. + 9. The prepare phase is discussed above. + + 10. The poweroff phase is analogous to the suspend phase. - 8. The poweroff phase is analogous to the suspend phase. + 11. The poweroff_late phase is analogous to the suspend_late phase. - 9. The poweroff_noirq phase is analogous to the suspend_noirq phase. + 12. The poweroff_noirq phase is analogous to the suspend_noirq phase. -The poweroff and poweroff_noirq callbacks should do essentially the same things -as the suspend and suspend_noirq callbacks. The only notable difference is that -they need not store the device register values, because the registers should -already have been stored during the freeze or freeze_noirq phases. +The poweroff, poweroff_late and poweroff_noirq callbacks should do essentially +the same things as the suspend, suspend_late and suspend_noirq callbacks, +respectively. The only notable difference is that they need not store the +device register values, because the registers should already have been stored +during the freeze, freeze_late or freeze_noirq phases. Leaving Hibernation @@ -518,22 +544,25 @@ To achieve this, the image kernel must restore the devices' pre-hibernation functionality. The operation is much like waking up from the memory sleep state, although it involves different phases: - restore_noirq, restore, complete + restore_noirq, restore_early, restore, complete 1. The restore_noirq phase is analogous to the resume_noirq phase. - 2. The restore phase is analogous to the resume phase. + 2. The restore_early phase is analogous to the resume_early phase. + + 3. The restore phase is analogous to the resume phase. - 3. The complete phase is discussed above. + 4. The complete phase is discussed above. -The main difference from resume[_noirq] is that restore[_noirq] must assume the -device has been accessed and reconfigured by the boot loader or the boot kernel. -Consequently the state of the device may be different from the state remembered -from the freeze and freeze_noirq phases. The device may even need to be reset -and completely re-initialized. In many cases this difference doesn't matter, so -the resume[_noirq] and restore[_norq] method pointers can be set to the same -routines. Nevertheless, different callback pointers are used in case there is a -situation where it actually matters. +The main difference from resume[_early|_noirq] is that restore[_early|_noirq] +must assume the device has been accessed and reconfigured by the boot loader or +the boot kernel. Consequently the state of the device may be different from the +state remembered from the freeze, freeze_late and freeze_noirq phases. The +device may even need to be reset and completely re-initialized. In many cases +this difference doesn't matter, so the resume[_early|_noirq] and +restore[_early|_norq] method pointers can be set to the same routines. +Nevertheless, different callback pointers are used in case there is a situation +where it actually does matter. Device Power Management Domains diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c index f76623cbe26..5d56931a15b 100644 --- a/arch/x86/kernel/apm_32.c +++ b/arch/x86/kernel/apm_32.c @@ -1234,8 +1234,7 @@ static int suspend(int vetoable) struct apm_user *as; dpm_suspend_start(PMSG_SUSPEND); - - dpm_suspend_noirq(PMSG_SUSPEND); + dpm_suspend_end(PMSG_SUSPEND); local_irq_disable(); syscore_suspend(); @@ -1259,9 +1258,9 @@ static int suspend(int vetoable) syscore_resume(); local_irq_enable(); - dpm_resume_noirq(PMSG_RESUME); - + dpm_resume_start(PMSG_RESUME); dpm_resume_end(PMSG_RESUME); + queue_event(APM_NORMAL_RESUME, NULL); spin_lock(&user_list_lock); for (as = user_list; as != NULL; as = as->next) { @@ -1277,7 +1276,7 @@ static void standby(void) { int err; - dpm_suspend_noirq(PMSG_SUSPEND); + dpm_suspend_end(PMSG_SUSPEND); local_irq_disable(); syscore_suspend(); @@ -1291,7 +1290,7 @@ static void standby(void) syscore_resume(); local_irq_enable(); - dpm_resume_noirq(PMSG_RESUME); + dpm_resume_start(PMSG_RESUME); } static apm_event_t get_event(void) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e2cc3d2e0ec..b462c0e341c 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -47,6 +47,7 @@ typedef int (*pm_callback_t)(struct device *); LIST_HEAD(dpm_list); LIST_HEAD(dpm_prepared_list); LIST_HEAD(dpm_suspended_list); +LIST_HEAD(dpm_late_early_list); LIST_HEAD(dpm_noirq_list); struct suspend_stats suspend_stats; @@ -245,6 +246,40 @@ static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state) return NULL; } +/** + * pm_late_early_op - Return the PM operation appropriate for given PM event. + * @ops: PM operations to choose from. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static pm_callback_t pm_late_early_op(const struct dev_pm_ops *ops, + pm_message_t state) +{ + switch (state.event) { +#ifdef CONFIG_SUSPEND + case PM_EVENT_SUSPEND: + return ops->suspend_late; + case PM_EVENT_RESUME: + return ops->resume_early; +#endif /* CONFIG_SUSPEND */ +#ifdef CONFIG_HIBERNATE_CALLBACKS + case PM_EVENT_FREEZE: + case PM_EVENT_QUIESCE: + return ops->freeze_late; + case PM_EVENT_HIBERNATE: + return ops->poweroff_late; + case PM_EVENT_THAW: + case PM_EVENT_RECOVER: + return ops->thaw_early; + case PM_EVENT_RESTORE: + return ops->restore_early; +#endif /* CONFIG_HIBERNATE_CALLBACKS */ + } + + return NULL; +} + /** * pm_noirq_op - Return the PM operation appropriate for given PM event. * @ops: PM operations to choose from. @@ -374,21 +409,21 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) TRACE_RESUME(0); if (dev->pm_domain) { - info = "EARLY power domain "; + info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); } else if (dev->type && dev->type->pm) { - info = "EARLY type "; + info = "noirq type "; callback = pm_noirq_op(dev->type->pm, state); } else if (dev->class && dev->class->pm) { - info = "EARLY class "; + info = "noirq class "; callback = pm_noirq_op(dev->class->pm, state); } else if (dev->bus && dev->bus->pm) { - info = "EARLY bus "; + info = "noirq bus "; callback = pm_noirq_op(dev->bus->pm, state); } if (!callback && dev->driver && dev->driver->pm) { - info = "EARLY driver "; + info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } @@ -399,13 +434,13 @@ static int device_resume_noirq(struct device *dev, pm_message_t state) } /** - * dpm_resume_noirq - Execute "early resume" callbacks for non-sysdev devices. + * dpm_resume_noirq - Execute "noirq resume" callbacks for all devices. * @state: PM transition of the system being carried out. * - * Call the "noirq" resume handlers for all devices marked as DPM_OFF_IRQ and + * Call the "noirq" resume handlers for all devices in dpm_noirq_list and * enable device drivers to receive interrupts. */ -void dpm_resume_noirq(pm_message_t state) +static void dpm_resume_noirq(pm_message_t state) { ktime_t starttime = ktime_get(); @@ -415,7 +450,7 @@ void dpm_resume_noirq(pm_message_t state) int error; get_device(dev); - list_move_tail(&dev->power.entry, &dpm_suspended_list); + list_move_tail(&dev->power.entry, &dpm_late_early_list); mutex_unlock(&dpm_list_mtx); error = device_resume_noirq(dev, state); @@ -423,6 +458,80 @@ void dpm_resume_noirq(pm_message_t state) suspend_stats.failed_resume_noirq++; dpm_save_failed_step(SUSPEND_RESUME_NOIRQ); dpm_save_failed_dev(dev_name(dev)); + pm_dev_err(dev, state, " noirq", error); + } + + mutex_lock(&dpm_list_mtx); + put_device(dev); + } + mutex_unlock(&dpm_list_mtx); + dpm_show_time(starttime, state, "noirq"); + resume_device_irqs(); +} + +/** + * device_resume_early - Execute an "early resume" callback for given device. + * @dev: Device to handle. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static int device_resume_early(struct device *dev, pm_message_t state) +{ + pm_callback_t callback = NULL; + char *info = NULL; + int error = 0; + + TRACE_DEVICE(dev); + TRACE_RESUME(0); + + if (dev->pm_domain) { + info = "early power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "early type "; + callback = pm_late_early_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "early class "; + callback = pm_late_early_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "early bus "; + callback = pm_late_early_op(dev->bus->pm, state); + } + + if (!callback && dev->driver && dev->driver->pm) { + info = "early driver "; + callback = pm_late_early_op(dev->driver->pm, state); + } + + error = dpm_run_callback(callback, dev, state, info); + + TRACE_RESUME(error); + return error; +} + +/** + * dpm_resume_early - Execute "early resume" callbacks for all devices. + * @state: PM transition of the system being carried out. + */ +static void dpm_resume_early(pm_message_t state) +{ + ktime_t starttime = ktime_get(); + + mutex_lock(&dpm_list_mtx); + while (!list_empty(&dpm_late_early_list)) { + struct device *dev = to_device(dpm_late_early_list.next); + int error; + + get_device(dev); + list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_unlock(&dpm_list_mtx); + + error = device_resume_early(dev, state); + if (error) { + suspend_stats.failed_resume_early++; + dpm_save_failed_step(SUSPEND_RESUME_EARLY); + dpm_save_failed_dev(dev_name(dev)); pm_dev_err(dev, state, " early", error); } @@ -431,9 +540,18 @@ void dpm_resume_noirq(pm_message_t state) } mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "early"); - resume_device_irqs(); } -EXPORT_SYMBOL_GPL(dpm_resume_noirq); + +/** + * dpm_resume_start - Execute "noirq" and "early" device callbacks. + * @state: PM transition of the system being carried out. + */ +void dpm_resume_start(pm_message_t state) +{ + dpm_resume_noirq(state); + dpm_resume_early(state); +} +EXPORT_SYMBOL_GPL(dpm_resume_start); /** * device_resume - Execute "resume" callbacks for given device. @@ -716,21 +834,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) char *info = NULL; if (dev->pm_domain) { - info = "LATE power domain "; + info = "noirq power domain "; callback = pm_noirq_op(&dev->pm_domain->ops, state); } else if (dev->type && dev->type->pm) { - info = "LATE type "; + info = "noirq type "; callback = pm_noirq_op(dev->type->pm, state); } else if (dev->class && dev->class->pm) { - info = "LATE class "; + info = "noirq class "; callback = pm_noirq_op(dev->class->pm, state); } else if (dev->bus && dev->bus->pm) { - info = "LATE bus "; + info = "noirq bus "; callback = pm_noirq_op(dev->bus->pm, state); } if (!callback && dev->driver && dev->driver->pm) { - info = "LATE driver "; + info = "noirq driver "; callback = pm_noirq_op(dev->driver->pm, state); } @@ -738,21 +856,21 @@ static int device_suspend_noirq(struct device *dev, pm_message_t state) } /** - * dpm_suspend_noirq - Execute "late suspend" callbacks for non-sysdev devices. + * dpm_suspend_noirq - Execute "noirq suspend" callbacks for all devices. * @state: PM transition of the system being carried out. * * Prevent device drivers from receiving interrupts and call the "noirq" suspend * handlers for all non-sysdev devices. */ -int dpm_suspend_noirq(pm_message_t state) +static int dpm_suspend_noirq(pm_message_t state) { ktime_t starttime = ktime_get(); int error = 0; suspend_device_irqs(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_suspended_list)) { - struct device *dev = to_device(dpm_suspended_list.prev); + while (!list_empty(&dpm_late_early_list)) { + struct device *dev = to_device(dpm_late_early_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -761,7 +879,7 @@ int dpm_suspend_noirq(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) { - pm_dev_err(dev, state, " late", error); + pm_dev_err(dev, state, " noirq", error); suspend_stats.failed_suspend_noirq++; dpm_save_failed_step(SUSPEND_SUSPEND_NOIRQ); dpm_save_failed_dev(dev_name(dev)); @@ -775,11 +893,96 @@ int dpm_suspend_noirq(pm_message_t state) mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); + else + dpm_show_time(starttime, state, "noirq"); + return error; +} + +/** + * device_suspend_late - Execute a "late suspend" callback for given device. + * @dev: Device to handle. + * @state: PM transition of the system being carried out. + * + * Runtime PM is disabled for @dev while this function is being executed. + */ +static int device_suspend_late(struct device *dev, pm_message_t state) +{ + pm_callback_t callback = NULL; + char *info = NULL; + + if (dev->pm_domain) { + info = "late power domain "; + callback = pm_late_early_op(&dev->pm_domain->ops, state); + } else if (dev->type && dev->type->pm) { + info = "late type "; + callback = pm_late_early_op(dev->type->pm, state); + } else if (dev->class && dev->class->pm) { + info = "late class "; + callback = pm_late_early_op(dev->class->pm, state); + } else if (dev->bus && dev->bus->pm) { + info = "late bus "; + callback = pm_late_early_op(dev->bus->pm, state); + } + + if (!callback && dev->driver && dev->driver->pm) { + info = "late driver "; + callback = pm_late_early_op(dev->driver->pm, state); + } + + return dpm_run_callback(callback, dev, state, info); +} + +/** + * dpm_suspend_late - Execute "late suspend" callbacks for all devices. + * @state: PM transition of the system being carried out. + */ +static int dpm_suspend_late(pm_message_t state) +{ + ktime_t starttime = ktime_get(); + int error = 0; + + mutex_lock(&dpm_list_mtx); + while (!list_empty(&dpm_suspended_list)) { + struct device *dev = to_device(dpm_suspended_list.prev); + + get_device(dev); + mutex_unlock(&dpm_list_mtx); + + error = device_suspend_late(dev, state); + + mutex_lock(&dpm_list_mtx); + if (error) { + pm_dev_err(dev, state, " late", error); + suspend_stats.failed_suspend_late++; + dpm_save_failed_step(SUSPEND_SUSPEND_LATE); + dpm_save_failed_dev(dev_name(dev)); + put_device(dev); + break; + } + if (!list_empty(&dev->power.entry)) + list_move(&dev->power.entry, &dpm_late_early_list); + put_device(dev); + } + mutex_unlock(&dpm_list_mtx); + if (error) + dpm_resume_early(resume_event(state)); else dpm_show_time(starttime, state, "late"); + return error; } -EXPORT_SYMBOL_GPL(dpm_suspend_noirq); + +/** + * dpm_suspend_end - Execute "late" and "noirq" device suspend callbacks. + * @state: PM transition of the system being carried out. + */ +int dpm_suspend_end(pm_message_t state) +{ + int error = dpm_suspend_late(state); + + return error ? : dpm_suspend_noirq(state); +} +EXPORT_SYMBOL_GPL(dpm_suspend_end); /** * legacy_suspend - Execute a legacy (bus or class) suspend callback for device. diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index ce4fa083186..9e14ae6cd49 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c @@ -129,9 +129,9 @@ static void do_suspend(void) printk(KERN_DEBUG "suspending xenstore...\n"); xs_suspend(); - err = dpm_suspend_noirq(PMSG_FREEZE); + err = dpm_suspend_end(PMSG_FREEZE); if (err) { - printk(KERN_ERR "dpm_suspend_noirq failed: %d\n", err); + printk(KERN_ERR "dpm_suspend_end failed: %d\n", err); goto out_resume; } @@ -149,7 +149,7 @@ static void do_suspend(void) err = stop_machine(xen_suspend, &si, cpumask_of(0)); - dpm_resume_noirq(si.cancelled ? PMSG_THAW : PMSG_RESTORE); + dpm_resume_start(si.cancelled ? PMSG_THAW : PMSG_RESTORE); if (err) { printk(KERN_ERR "failed to start xen_suspend: %d\n", err); diff --git a/include/linux/pm.h b/include/linux/pm.h index e4982ac3fbb..c68e1f22ac9 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -110,6 +110,10 @@ typedef struct pm_message { * Subsystem-level @suspend() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @suspend_late: Continue operations started by @suspend(). For a number of + * devices @suspend_late() may point to the same callback routine as the + * runtime suspend callback. + * * @resume: Executed after waking the system up from a sleep state in which the * contents of main memory were preserved. The exact action to perform * depends on the device's subsystem, but generally the driver is expected @@ -122,6 +126,10 @@ typedef struct pm_message { * Subsystem-level @resume() is executed for all devices after invoking * subsystem-level @resume_noirq() for all of them. * + * @resume_early: Prepare to execute @resume(). For a number of devices + * @resume_early() may point to the same callback routine as the runtime + * resume callback. + * * @freeze: Hibernation-specific, executed before creating a hibernation image. * Analogous to @suspend(), but it should not enable the device to signal * wakeup events or change its power state. The majority of subsystems @@ -131,6 +139,10 @@ typedef struct pm_message { * Subsystem-level @freeze() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @freeze_late: Continue operations started by @freeze(). Analogous to + * @suspend_late(), but it should not enable the device to signal wakeup + * events or change its power state. + * * @thaw: Hibernation-specific, executed after creating a hibernation image OR * if the creation of an image has failed. Also executed after a failing * attempt to restore the contents of main memory from such an image. @@ -140,15 +152,23 @@ typedef struct pm_message { * subsystem-level @thaw_noirq() for all of them. It also may be executed * directly after @freeze() in case of a transition error. * + * @thaw_early: Prepare to execute @thaw(). Undo the changes made by the + * preceding @freeze_late(). + * * @poweroff: Hibernation-specific, executed after saving a hibernation image. * Analogous to @suspend(), but it need not save the device's settings in * memory. * Subsystem-level @poweroff() is executed for all devices after invoking * subsystem-level @prepare() for all of them. * + * @poweroff_late: Continue operations started by @poweroff(). Analogous to + * @suspend_late(), but it need not save the device's settings in memory. + * * @restore: Hibernation-specific, executed after restoring the contents of main * memory from a hibernation image, analogous to @resume(). * + * @restore_early: Prepare to execute @restore(), analogous to @resume_early(). + * * @suspend_noirq: Complete the actions started by @suspend(). Carry out any * additional operations required for suspending the device that might be * racing with its driver's interrupt handler, which is guaranteed not to @@ -158,9 +178,10 @@ typedef struct pm_message { * @suspend_noirq() has returned successfully. If the device can generate * system wakeup signals and is enabled to wake up the system, it should be * configured to do so at that time. However, depending on the platform - * and device's subsystem, @suspend() may be allowed to put the device into - * the low-power state and configure it to generate wakeup signals, in - * which case it generally is not necessary to define @suspend_noirq(). + * and device's subsystem, @suspend() or @suspend_late() may be allowed to + * put the device into the low-power state and configure it to generate + * wakeup signals, in which case it generally is not necessary to define + * @suspend_noirq(). * * @resume_noirq: Prepare for the execution of @resume() by carrying out any * operations required for resuming the device that might be racing with @@ -171,9 +192,9 @@ typedef struct pm_message { * additional operations required for freezing the device that might be * racing with its driver's interrupt handler, which is guaranteed not to * run while @freeze_noirq() is being executed. - * The power state of the device should not be changed by either @freeze() - * or @freeze_noirq() and it should not be configured to signal system - * wakeup by any of these callbacks. + * The power state of the device should not be changed by either @freeze(), + * or @freeze_late(), or @freeze_noirq() and it should not be configured to + * signal system wakeup by any of these callbacks. * * @thaw_noirq: Prepare for the execution of @thaw() by carrying out any * operations required for thawing the device that might be racing with its @@ -249,6 +270,12 @@ struct dev_pm_ops { int (*thaw)(struct device *dev); int (*poweroff)(struct device *dev); int (*restore)(struct device *dev); + int (*suspend_late)(struct device *dev); + int (*resume_early)(struct device *dev); + int (*freeze_late)(struct device *dev); + int (*thaw_early)(struct device *dev); + int (*poweroff_late)(struct device *dev); + int (*restore_early)(struct device *dev); int (*suspend_noirq)(struct device *dev); int (*resume_noirq)(struct device *dev); int (*freeze_noirq)(struct device *dev); @@ -584,13 +611,13 @@ struct dev_pm_domain { #ifdef CONFIG_PM_SLEEP extern void device_pm_lock(void); -extern void dpm_resume_noirq(pm_message_t state); +extern void dpm_resume_start(pm_message_t state); extern void dpm_resume_end(pm_message_t state); extern void dpm_resume(pm_message_t state); extern void dpm_complete(pm_message_t state); extern void device_pm_unlock(void); -extern int dpm_suspend_noirq(pm_message_t state); +extern int dpm_suspend_end(pm_message_t state); extern int dpm_suspend_start(pm_message_t state); extern int dpm_suspend(pm_message_t state); extern int dpm_prepare(pm_message_t state); diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 91784a4f860..ac1c114c499 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -42,8 +42,10 @@ enum suspend_stat_step { SUSPEND_FREEZE = 1, SUSPEND_PREPARE, SUSPEND_SUSPEND, + SUSPEND_SUSPEND_LATE, SUSPEND_SUSPEND_NOIRQ, SUSPEND_RESUME_NOIRQ, + SUSPEND_RESUME_EARLY, SUSPEND_RESUME }; @@ -53,8 +55,10 @@ struct suspend_stats { int failed_freeze; int failed_prepare; int failed_suspend; + int failed_suspend_late; int failed_suspend_noirq; int failed_resume; + int failed_resume_early; int failed_resume_noirq; #define REC_FAILED_NUM 2 int last_failed_dev; diff --git a/kernel/kexec.c b/kernel/kexec.c index 7b088678670..a6a675cb981 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -1546,13 +1546,13 @@ int kernel_kexec(void) if (error) goto Resume_console; /* At this point, dpm_suspend_start() has been called, - * but *not* dpm_suspend_noirq(). We *must* call - * dpm_suspend_noirq() now. Otherwise, drivers for + * but *not* dpm_suspend_end(). We *must* call + * dpm_suspend_end() now. Otherwise, drivers for * some devices (e.g. interrupt controllers) become * desynchronized with the actual state of the * hardware at resume time, and evil weirdness ensues. */ - error = dpm_suspend_noirq(PMSG_FREEZE); + error = dpm_suspend_end(PMSG_FREEZE); if (error) goto Resume_devices; error = disable_nonboot_cpus(); @@ -1579,7 +1579,7 @@ int kernel_kexec(void) local_irq_enable(); Enable_cpus: enable_nonboot_cpus(); - dpm_resume_noirq(PMSG_RESTORE); + dpm_resume_start(PMSG_RESTORE); Resume_devices: dpm_resume_end(PMSG_RESTORE); Resume_console: diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 6d6d2887033..a5d4cf0aa03 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -245,8 +245,8 @@ void swsusp_show_speed(struct timeval *start, struct timeval *stop, * create_image - Create a hibernation image. * @platform_mode: Whether or not to use the platform driver. * - * Execute device drivers' .freeze_noirq() callbacks, create a hibernation image - * and execute the drivers' .thaw_noirq() callbacks. + * Execute device drivers' "late" and "noirq" freeze callbacks, create a + * hibernation image and run the drivers' "noirq" and "early" thaw callbacks. * * Control reappears in this routine after the subsequent restore. */ @@ -254,7 +254,7 @@ static int create_image(int platform_mode) { int error; - error = dpm_suspend_noirq(PMSG_FREEZE); + error = dpm_suspend_end(PMSG_FREEZE); if (error) { printk(KERN_ERR "PM: Some devices failed to power down, " "aborting hibernation\n"); @@ -306,7 +306,7 @@ static int create_image(int platform_mode) Platform_finish: platform_finish(platform_mode); - dpm_resume_noirq(in_suspend ? + dpm_resume_start(in_suspend ? (error ? PMSG_RECOVER : PMSG_THAW) : PMSG_RESTORE); return error; @@ -394,16 +394,16 @@ int hibernation_snapshot(int platform_mode) * resume_target_kernel - Restore system state from a hibernation image. * @platform_mode: Whether or not to use the platform driver. * - * Execute device drivers' .freeze_noirq() callbacks, restore the contents of - * highmem that have not been restored yet from the image and run the low-level - * code that will restore the remaining contents of memory and switch to the - * just restored target kernel. + * Execute device drivers' "noirq" and "late" freeze callbacks, restore the + * contents of highmem that have not been restored yet from the image and run + * the low-level code that will restore the remaining contents of memory and + * switch to the just restored target kernel. */ static int resume_target_kernel(bool platform_mode) { int error; - error = dpm_suspend_noirq(PMSG_QUIESCE); + error = dpm_suspend_end(PMSG_QUIESCE); if (error) { printk(KERN_ERR "PM: Some devices failed to power down, " "aborting resume\n"); @@ -460,7 +460,7 @@ static int resume_target_kernel(bool platform_mode) Cleanup: platform_restore_cleanup(platform_mode); - dpm_resume_noirq(PMSG_RECOVER); + dpm_resume_start(PMSG_RECOVER); return error; } @@ -518,7 +518,7 @@ int hibernation_platform_enter(void) goto Resume_devices; } - error = dpm_suspend_noirq(PMSG_HIBERNATE); + error = dpm_suspend_end(PMSG_HIBERNATE); if (error) goto Resume_devices; @@ -549,7 +549,7 @@ int hibernation_platform_enter(void) Platform_finish: hibernation_ops->finish(); - dpm_resume_noirq(PMSG_RESTORE); + dpm_resume_start(PMSG_RESTORE); Resume_devices: entering_platform_hibernation = false; diff --git a/kernel/power/main.c b/kernel/power/main.c index 9824b41e5a1..8c5014a4e05 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -165,16 +165,20 @@ static int suspend_stats_show(struct seq_file *s, void *unused) last_errno %= REC_FAILED_NUM; last_step = suspend_stats.last_failed_step + REC_FAILED_NUM - 1; last_step %= REC_FAILED_NUM; - seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n" - "%s: %d\n%s: %d\n%s: %d\n%s: %d\n", + seq_printf(s, "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n" + "%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n", "success", suspend_stats.success, "fail", suspend_stats.fail, "failed_freeze", suspend_stats.failed_freeze, "failed_prepare", suspend_stats.failed_prepare, "failed_suspend", suspend_stats.failed_suspend, + "failed_suspend_late", + suspend_stats.failed_suspend_late, "failed_suspend_noirq", suspend_stats.failed_suspend_noirq, "failed_resume", suspend_stats.failed_resume, + "failed_resume_early", + suspend_stats.failed_resume_early, "failed_resume_noirq", suspend_stats.failed_resume_noirq); seq_printf(s, "failures:\n last_failed_dev:\t%-s\n", diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 4fd51beed87..560a639614a 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -147,7 +147,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) goto Platform_finish; } - error = dpm_suspend_noirq(PMSG_SUSPEND); + error = dpm_suspend_end(PMSG_SUSPEND); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; @@ -189,7 +189,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) if (suspend_ops->wake) suspend_ops->wake(); - dpm_resume_noirq(PMSG_RESUME); + dpm_resume_start(PMSG_RESUME); Platform_finish: if (suspend_ops->finish) -- cgit v1.2.3-70-g09d2 From e470d06655e00749f6f9372e4fa4f20cea7ed7c5 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:38:41 +0100 Subject: PM / Sleep: Introduce generic callbacks for new device PM phases Introduce generic subsystem callbacks for the new phases of device suspend/resume during system power transitions: "late suspend", "early resume", "late freeze", "early thaw", "late poweroff", "early restore". Signed-off-by: Rafael J. Wysocki --- drivers/base/power/generic_ops.c | 157 ++++++++++++++++++++++++++------------- include/linux/pm.h | 6 ++ 2 files changed, 110 insertions(+), 53 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 10bdd793f0b..d03d290f31c 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -92,59 +92,28 @@ int pm_generic_prepare(struct device *dev) } /** - * __pm_generic_call - Generic suspend/freeze/poweroff/thaw subsystem callback. - * @dev: Device to handle. - * @event: PM transition of the system under way. - * @bool: Whether or not this is the "noirq" stage. - * - * Execute the PM callback corresponding to @event provided by the driver of - * @dev, if defined, and return its error code. Return 0 if the callback is - * not present. + * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. + * @dev: Device to suspend. */ -static int __pm_generic_call(struct device *dev, int event, bool noirq) +int pm_generic_suspend_noirq(struct device *dev) { const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; - int (*callback)(struct device *); - - if (!pm) - return 0; - - switch (event) { - case PM_EVENT_SUSPEND: - callback = noirq ? pm->suspend_noirq : pm->suspend; - break; - case PM_EVENT_FREEZE: - callback = noirq ? pm->freeze_noirq : pm->freeze; - break; - case PM_EVENT_HIBERNATE: - callback = noirq ? pm->poweroff_noirq : pm->poweroff; - break; - case PM_EVENT_RESUME: - callback = noirq ? pm->resume_noirq : pm->resume; - break; - case PM_EVENT_THAW: - callback = noirq ? pm->thaw_noirq : pm->thaw; - break; - case PM_EVENT_RESTORE: - callback = noirq ? pm->restore_noirq : pm->restore; - break; - default: - callback = NULL; - break; - } - return callback ? callback(dev) : 0; + return pm && pm->suspend_noirq ? pm->suspend_noirq(dev) : 0; } +EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); /** - * pm_generic_suspend_noirq - Generic suspend_noirq callback for subsystems. + * pm_generic_suspend_late - Generic suspend_late callback for subsystems. * @dev: Device to suspend. */ -int pm_generic_suspend_noirq(struct device *dev) +int pm_generic_suspend_late(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_SUSPEND, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->suspend_late ? pm->suspend_late(dev) : 0; } -EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); +EXPORT_SYMBOL_GPL(pm_generic_suspend_late); /** * pm_generic_suspend - Generic suspend callback for subsystems. @@ -152,7 +121,9 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend_noirq); */ int pm_generic_suspend(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_SUSPEND, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->suspend ? pm->suspend(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_suspend); @@ -162,17 +133,33 @@ EXPORT_SYMBOL_GPL(pm_generic_suspend); */ int pm_generic_freeze_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_FREEZE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze_noirq ? pm->freeze_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_freeze_noirq); +/** + * pm_generic_freeze_late - Generic freeze_late callback for subsystems. + * @dev: Device to freeze. + */ +int pm_generic_freeze_late(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze_late ? pm->freeze_late(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_freeze_late); + /** * pm_generic_freeze - Generic freeze callback for subsystems. * @dev: Device to freeze. */ int pm_generic_freeze(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_FREEZE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->freeze ? pm->freeze(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_freeze); @@ -182,17 +169,33 @@ EXPORT_SYMBOL_GPL(pm_generic_freeze); */ int pm_generic_poweroff_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_HIBERNATE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff_noirq ? pm->poweroff_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_poweroff_noirq); +/** + * pm_generic_poweroff_late - Generic poweroff_late callback for subsystems. + * @dev: Device to handle. + */ +int pm_generic_poweroff_late(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff_late ? pm->poweroff_late(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_poweroff_late); + /** * pm_generic_poweroff - Generic poweroff callback for subsystems. * @dev: Device to handle. */ int pm_generic_poweroff(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_HIBERNATE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->poweroff ? pm->poweroff(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_poweroff); @@ -202,17 +205,33 @@ EXPORT_SYMBOL_GPL(pm_generic_poweroff); */ int pm_generic_thaw_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_THAW, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw_noirq ? pm->thaw_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_thaw_noirq); +/** + * pm_generic_thaw_early - Generic thaw_early callback for subsystems. + * @dev: Device to thaw. + */ +int pm_generic_thaw_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw_early ? pm->thaw_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_thaw_early); + /** * pm_generic_thaw - Generic thaw callback for subsystems. * @dev: Device to thaw. */ int pm_generic_thaw(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_THAW, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->thaw ? pm->thaw(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_thaw); @@ -222,17 +241,33 @@ EXPORT_SYMBOL_GPL(pm_generic_thaw); */ int pm_generic_resume_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESUME, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume_noirq ? pm->resume_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_resume_noirq); +/** + * pm_generic_resume_early - Generic resume_early callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_resume_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume_early ? pm->resume_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_resume_early); + /** * pm_generic_resume - Generic resume callback for subsystems. * @dev: Device to resume. */ int pm_generic_resume(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESUME, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->resume ? pm->resume(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_resume); @@ -242,17 +277,33 @@ EXPORT_SYMBOL_GPL(pm_generic_resume); */ int pm_generic_restore_noirq(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESTORE, true); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore_noirq ? pm->restore_noirq(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_restore_noirq); +/** + * pm_generic_restore_early - Generic restore_early callback for subsystems. + * @dev: Device to resume. + */ +int pm_generic_restore_early(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore_early ? pm->restore_early(dev) : 0; +} +EXPORT_SYMBOL_GPL(pm_generic_restore_early); + /** * pm_generic_restore - Generic restore callback for subsystems. * @dev: Device to restore. */ int pm_generic_restore(struct device *dev) { - return __pm_generic_call(dev, PM_EVENT_RESTORE, false); + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + return pm && pm->restore ? pm->restore(dev) : 0; } EXPORT_SYMBOL_GPL(pm_generic_restore); diff --git a/include/linux/pm.h b/include/linux/pm.h index c68e1f22ac9..73c610573a7 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -632,17 +632,23 @@ extern void __suspend_report_result(const char *function, void *fn, int ret); extern int device_pm_wait_for_dev(struct device *sub, struct device *dev); extern int pm_generic_prepare(struct device *dev); +extern int pm_generic_suspend_late(struct device *dev); extern int pm_generic_suspend_noirq(struct device *dev); extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume_early(struct device *dev); extern int pm_generic_resume_noirq(struct device *dev); extern int pm_generic_resume(struct device *dev); extern int pm_generic_freeze_noirq(struct device *dev); +extern int pm_generic_freeze_late(struct device *dev); extern int pm_generic_freeze(struct device *dev); extern int pm_generic_thaw_noirq(struct device *dev); +extern int pm_generic_thaw_early(struct device *dev); extern int pm_generic_thaw(struct device *dev); extern int pm_generic_restore_noirq(struct device *dev); +extern int pm_generic_restore_early(struct device *dev); extern int pm_generic_restore(struct device *dev); extern int pm_generic_poweroff_noirq(struct device *dev); +extern int pm_generic_poweroff_late(struct device *dev); extern int pm_generic_poweroff(struct device *dev); extern void pm_generic_complete(struct device *dev); -- cgit v1.2.3-70-g09d2 From 0496c8ae366724a0a2136cec09a2e277e782c126 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 29 Jan 2012 20:39:02 +0100 Subject: PM / Domains: Run late/early device suspend callbacks at the right time After the introduction of the late/early phases of device suspend/resume during system-wide power transitions it is possible to make the generic PM domains code execute its default late/early device suspend/resume callbacks during those phases instead of the corresponding _noirq phases. The _noirq device suspend/resume phases were only used for executing those callbacks, because this was the only way it could be done, but now we can do better. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/domain.c | 157 +++++++++++++++++++++++++++++++------------- 1 file changed, 111 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index 978bbf7ac6a..12a03afe530 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -820,17 +820,16 @@ static int pm_genpd_suspend(struct device *dev) } /** - * pm_genpd_suspend_noirq - Late suspend of a device from an I/O PM domain. + * pm_genpd_suspend_late - Late suspend of a device from an I/O PM domain. * @dev: Device to suspend. * * Carry out a late suspend of a device under the assumption that its * pm_domain field points to the domain member of an object of type * struct generic_pm_domain representing a PM domain consisting of I/O devices. */ -static int pm_genpd_suspend_noirq(struct device *dev) +static int pm_genpd_suspend_late(struct device *dev) { struct generic_pm_domain *genpd; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -838,14 +837,28 @@ static int pm_genpd_suspend_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; + return genpd->suspend_power_off ? 0 : genpd_suspend_late(genpd, dev); +} - ret = genpd_suspend_late(genpd, dev); - if (ret) - return ret; +/** + * pm_genpd_suspend_noirq - Completion of suspend of device in an I/O PM domain. + * @dev: Device to suspend. + * + * Stop the device and remove power from the domain if all devices in it have + * been stopped. + */ +static int pm_genpd_suspend_noirq(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; - if (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev)) + if (genpd->suspend_power_off + || (dev->power.wakeup_path && genpd_dev_active_wakeup(genpd, dev))) return 0; genpd_stop_dev(genpd, dev); @@ -862,13 +875,10 @@ static int pm_genpd_suspend_noirq(struct device *dev) } /** - * pm_genpd_resume_noirq - Early resume of a device from an I/O power domain. + * pm_genpd_resume_noirq - Start of resume of device in an I/O PM domain. * @dev: Device to resume. * - * Carry out an early resume of a device under the assumption that its - * pm_domain field points to the domain member of an object of type - * struct generic_pm_domain representing a power domain consisting of I/O - * devices. + * Restore power to the device's PM domain, if necessary, and start the device. */ static int pm_genpd_resume_noirq(struct device *dev) { @@ -890,13 +900,34 @@ static int pm_genpd_resume_noirq(struct device *dev) */ pm_genpd_poweron(genpd); genpd->suspended_count--; - genpd_start_dev(genpd, dev); - return genpd_resume_early(genpd, dev); + return genpd_start_dev(genpd, dev); } /** - * pm_genpd_resume - Resume a device belonging to an I/O power domain. + * pm_genpd_resume_early - Early resume of a device in an I/O PM domain. + * @dev: Device to resume. + * + * Carry out an early resume of a device under the assumption that its + * pm_domain field points to the domain member of an object of type + * struct generic_pm_domain representing a power domain consisting of I/O + * devices. + */ +static int pm_genpd_resume_early(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_resume_early(genpd, dev); +} + +/** + * pm_genpd_resume - Resume of device in an I/O PM domain. * @dev: Device to resume. * * Resume a device under the assumption that its pm_domain field points to the @@ -917,7 +948,7 @@ static int pm_genpd_resume(struct device *dev) } /** - * pm_genpd_freeze - Freeze a device belonging to an I/O power domain. + * pm_genpd_freeze - Freezing a device in an I/O PM domain. * @dev: Device to freeze. * * Freeze a device under the assumption that its pm_domain field points to the @@ -938,7 +969,29 @@ static int pm_genpd_freeze(struct device *dev) } /** - * pm_genpd_freeze_noirq - Late freeze of a device from an I/O power domain. + * pm_genpd_freeze_late - Late freeze of a device in an I/O PM domain. + * @dev: Device to freeze. + * + * Carry out a late freeze of a device under the assumption that its + * pm_domain field points to the domain member of an object of type + * struct generic_pm_domain representing a power domain consisting of I/O + * devices. + */ +static int pm_genpd_freeze_late(struct device *dev) +{ + struct generic_pm_domain *genpd; + + dev_dbg(dev, "%s()\n", __func__); + + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_freeze_late(genpd, dev); +} + +/** + * pm_genpd_freeze_noirq - Completion of freezing a device in an I/O PM domain. * @dev: Device to freeze. * * Carry out a late freeze of a device under the assumption that its @@ -949,7 +1002,6 @@ static int pm_genpd_freeze(struct device *dev) static int pm_genpd_freeze_noirq(struct device *dev) { struct generic_pm_domain *genpd; - int ret; dev_dbg(dev, "%s()\n", __func__); @@ -957,20 +1009,31 @@ static int pm_genpd_freeze_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; + return genpd->suspend_power_off ? 0 : genpd_stop_dev(genpd, dev); +} - ret = genpd_freeze_late(genpd, dev); - if (ret) - return ret; +/** + * pm_genpd_thaw_noirq - Early thaw of device in an I/O PM domain. + * @dev: Device to thaw. + * + * Start the device, unless power has been removed from the domain already + * before the system transition. + */ +static int pm_genpd_thaw_noirq(struct device *dev) +{ + struct generic_pm_domain *genpd; - genpd_stop_dev(genpd, dev); + dev_dbg(dev, "%s()\n", __func__); - return 0; + genpd = dev_to_genpd(dev); + if (IS_ERR(genpd)) + return -EINVAL; + + return genpd->suspend_power_off ? 0 : genpd_start_dev(genpd, dev); } /** - * pm_genpd_thaw_noirq - Early thaw of a device from an I/O power domain. + * pm_genpd_thaw_early - Early thaw of device in an I/O PM domain. * @dev: Device to thaw. * * Carry out an early thaw of a device under the assumption that its @@ -978,7 +1041,7 @@ static int pm_genpd_freeze_noirq(struct device *dev) * struct generic_pm_domain representing a power domain consisting of I/O * devices. */ -static int pm_genpd_thaw_noirq(struct device *dev) +static int pm_genpd_thaw_early(struct device *dev) { struct generic_pm_domain *genpd; @@ -988,12 +1051,7 @@ static int pm_genpd_thaw_noirq(struct device *dev) if (IS_ERR(genpd)) return -EINVAL; - if (genpd->suspend_power_off) - return 0; - - genpd_start_dev(genpd, dev); - - return genpd_thaw_early(genpd, dev); + return genpd->suspend_power_off ? 0 : genpd_thaw_early(genpd, dev); } /** @@ -1018,13 +1076,11 @@ static int pm_genpd_thaw(struct device *dev) } /** - * pm_genpd_restore_noirq - Early restore of a device from an I/O power domain. + * pm_genpd_restore_noirq - Start of restore of device in an I/O PM domain. * @dev: Device to resume. * - * Carry out an early restore of a device under the assumption that its - * pm_domain field points to the domain member of an object of type - * struct generic_pm_domain representing a power domain consisting of I/O - * devices. + * Make sure the domain will be in the same power state as before the + * hibernation the system is resuming from and start the device if necessary. */ static int pm_genpd_restore_noirq(struct device *dev) { @@ -1054,9 +1110,8 @@ static int pm_genpd_restore_noirq(struct device *dev) pm_genpd_poweron(genpd); genpd->suspended_count--; - genpd_start_dev(genpd, dev); - return genpd_resume_early(genpd, dev); + return genpd_start_dev(genpd, dev); } /** @@ -1099,11 +1154,15 @@ static void pm_genpd_complete(struct device *dev) #define pm_genpd_prepare NULL #define pm_genpd_suspend NULL +#define pm_genpd_suspend_late NULL #define pm_genpd_suspend_noirq NULL +#define pm_genpd_resume_early NULL #define pm_genpd_resume_noirq NULL #define pm_genpd_resume NULL #define pm_genpd_freeze NULL +#define pm_genpd_freeze_late NULL #define pm_genpd_freeze_noirq NULL +#define pm_genpd_thaw_early NULL #define pm_genpd_thaw_noirq NULL #define pm_genpd_thaw NULL #define pm_genpd_restore_noirq NULL @@ -1450,7 +1509,7 @@ static int pm_genpd_default_suspend_late(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.suspend_late; - return cb ? cb(dev) : pm_generic_suspend_noirq(dev); + return cb ? cb(dev) : pm_generic_suspend_late(dev); } /** @@ -1461,7 +1520,7 @@ static int pm_genpd_default_resume_early(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.resume_early; - return cb ? cb(dev) : pm_generic_resume_noirq(dev); + return cb ? cb(dev) : pm_generic_resume_early(dev); } /** @@ -1494,7 +1553,7 @@ static int pm_genpd_default_freeze_late(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.freeze_late; - return cb ? cb(dev) : pm_generic_freeze_noirq(dev); + return cb ? cb(dev) : pm_generic_freeze_late(dev); } /** @@ -1505,7 +1564,7 @@ static int pm_genpd_default_thaw_early(struct device *dev) { int (*cb)(struct device *__dev) = dev_gpd_data(dev)->ops.thaw_early; - return cb ? cb(dev) : pm_generic_thaw_noirq(dev); + return cb ? cb(dev) : pm_generic_thaw_early(dev); } /** @@ -1564,16 +1623,22 @@ void pm_genpd_init(struct generic_pm_domain *genpd, genpd->domain.ops.runtime_idle = pm_generic_runtime_idle; genpd->domain.ops.prepare = pm_genpd_prepare; genpd->domain.ops.suspend = pm_genpd_suspend; + genpd->domain.ops.suspend_late = pm_genpd_suspend_late; genpd->domain.ops.suspend_noirq = pm_genpd_suspend_noirq; genpd->domain.ops.resume_noirq = pm_genpd_resume_noirq; + genpd->domain.ops.resume_early = pm_genpd_resume_early; genpd->domain.ops.resume = pm_genpd_resume; genpd->domain.ops.freeze = pm_genpd_freeze; + genpd->domain.ops.freeze_late = pm_genpd_freeze_late; genpd->domain.ops.freeze_noirq = pm_genpd_freeze_noirq; genpd->domain.ops.thaw_noirq = pm_genpd_thaw_noirq; + genpd->domain.ops.thaw_early = pm_genpd_thaw_early; genpd->domain.ops.thaw = pm_genpd_thaw; genpd->domain.ops.poweroff = pm_genpd_suspend; + genpd->domain.ops.poweroff_late = pm_genpd_suspend_late; genpd->domain.ops.poweroff_noirq = pm_genpd_suspend_noirq; genpd->domain.ops.restore_noirq = pm_genpd_restore_noirq; + genpd->domain.ops.restore_early = pm_genpd_resume_early; genpd->domain.ops.restore = pm_genpd_resume; genpd->domain.ops.complete = pm_genpd_complete; genpd->dev_ops.save_state = pm_genpd_default_save_state; -- cgit v1.2.3-70-g09d2 From c212acccc368a087a53559aac2b7d3be941b1252 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Sat, 28 Jan 2012 02:16:41 +0100 Subject: regmap: Properly round reg_bytes and val_bytes For the upcoming 2/6-format, we don't see debugfs output otherwise, since the current division results in 0. I'd think 10/14 is broken currently, too. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index b4475d87f4a..3c34526091d 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -167,9 +167,9 @@ struct regmap *regmap_init(struct device *dev, mutex_init(&map->lock); map->format.buf_size = (config->reg_bits + config->val_bits) / 8; - map->format.reg_bytes = config->reg_bits / 8; + map->format.reg_bytes = DIV_ROUND_UP(config->reg_bits, 8); map->format.pad_bytes = config->pad_bits / 8; - map->format.val_bytes = config->val_bits / 8; + map->format.val_bytes = DIV_ROUND_UP(config->val_bits, 8); map->format.buf_size += map->format.pad_bytes; map->dev = dev; map->bus = bus; -- cgit v1.2.3-70-g09d2 From 33f3f518fbb65d86f163083b74823e8bbe561bfc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:39 +0100 Subject: drm/i915: add per-ring fault reg to error_state This was pretty handy when figuring out what exactly went wrong with ppgtt and it might also be useful when we stop filling the entire gart with scratch page entries. Also add the gen6+ DONE reg while at it. v2: Chris Wilson suggested to allocate the error_state with kzalloc for better paranoia. Also kill existing spurious clears of the error_state while at it. Reviewed-by: Ben Widawsky Reviewed-by: Eugeni Dodonov Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 8 ++++++-- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_irq.c | 13 +++++++------ drivers/gpu/drm/i915/i915_reg.h | 2 ++ 4 files changed, 17 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f0486059e44..d4104904e58 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -718,8 +718,10 @@ static void i915_ring_error_state(struct seq_file *m, if (INTEL_INFO(dev)->gen >= 4) seq_printf(m, " INSTPS: 0x%08x\n", error->instps[ring]); seq_printf(m, " INSTPM: 0x%08x\n", error->instpm[ring]); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, " FADDR: 0x%08x\n", error->faddr[ring]); + seq_printf(m, " FAULT_REG: 0x%08x\n", error->fault_reg[ring]); + } seq_printf(m, " seqno: 0x%08x\n", error->seqno[ring]); } @@ -749,8 +751,10 @@ static int i915_error_state(struct seq_file *m, void *unused) for (i = 0; i < dev_priv->num_fence_regs; i++) seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "ERROR: 0x%08x\n", error->error); + seq_printf(m, "DONE_REG: 0x%08x\n", error->done_reg); + } i915_ring_error_state(m, dev, error, RCS); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 12e8cce7928..865de800756 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -165,6 +165,8 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno[I915_NUM_RINGS]; u64 bbaddr; + u32 fault_reg[I915_NUM_RINGS]; + u32 done_reg; u32 faddr[I915_NUM_RINGS]; u64 fence[I915_MAX_NUM_FENCES]; struct timeval time; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4dedb314806..64bb2127911 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -882,8 +882,10 @@ static void i915_record_ring_state(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { error->faddr[ring->id] = I915_READ(RING_DMA_FADD(ring->mmio_base)); + error->fault_reg[ring->id] = I915_READ(RING_FAULT_REG(ring)); + } if (INTEL_INFO(dev)->gen >= 4) { error->ipeir[ring->id] = I915_READ(RING_IPEIR(ring->mmio_base)); @@ -898,7 +900,6 @@ static void i915_record_ring_state(struct drm_device *dev, error->ipeir[ring->id] = I915_READ(IPEIR); error->ipehr[ring->id] = I915_READ(IPEHR); error->instdone[ring->id] = I915_READ(INSTDONE); - error->bbaddr = 0; } error->instpm[ring->id] = I915_READ(RING_INSTPM(ring->mmio_base)); @@ -932,7 +933,7 @@ static void i915_capture_error_state(struct drm_device *dev) return; /* Account for pipe specific data like PIPE*STAT */ - error = kmalloc(sizeof(*error), GFP_ATOMIC); + error = kzalloc(sizeof(*error), GFP_ATOMIC); if (!error) { DRM_DEBUG_DRIVER("out of memory, not capturing error state\n"); return; @@ -946,10 +947,10 @@ static void i915_capture_error_state(struct drm_device *dev) for_each_pipe(pipe) error->pipestat[pipe] = I915_READ(PIPESTAT(pipe)); - if (INTEL_INFO(dev)->gen >= 6) + if (INTEL_INFO(dev)->gen >= 6) { error->error = I915_READ(ERROR_GEN6); - else - error->error = 0; + error->done_reg = I915_READ(DONE_REG); + } i915_record_ring_state(dev, error, &dev_priv->ring[RCS]); if (HAS_BLT(dev)) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index d107a1d756a..f9607387c00 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -319,6 +319,8 @@ #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) #define RENDER_HWS_PGA_GEN7 (0x04080) +#define RING_FAULT_REG(ring) (0x4094 + 0x100*(ring)->id) +#define DONE_REG 0x40b0 #define BSD_HWS_PGA_GEN7 (0x04180) #define BLT_HWS_PGA_GEN7 (0x04280) #define RING_ACTHD(base) ((base)+0x74) -- cgit v1.2.3-70-g09d2 From 439aa0efd7a4a9ac225e94feee03824101c7d38e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 9 Jan 2012 10:32:47 +0100 Subject: mmc: mxcmmc: add missing dma_async_issue_pending Signed-off-by: Sascha Hauer Signed-off-by: Vinod Koul --- drivers/mmc/host/mxcmmc.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 4184b7946bb..f35b6bad047 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -267,6 +267,7 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) wmb(); dmaengine_submit(host->desc); + dma_async_issue_pending(host->dma); return 0; } -- cgit v1.2.3-70-g09d2 From d11519adc214c243ec606f186316f2667b677694 Mon Sep 17 00:00:00 2001 From: Praveena Nadahally Date: Wed, 25 Jan 2012 11:02:03 +0100 Subject: usb: gadget: Add Interface Association Descriptor to ECM Add IAD to bind the two interfaces of ECM so that it works properly in composite gadget mode. Signed-off-by: Thirupathi Signed-off-by: Praveena Nadahally Signed-off-by: Linus Walleij Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_ecm.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 11c07cb7d33..30b908f2a53 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c @@ -97,6 +97,20 @@ static inline unsigned ecm_bitrate(struct usb_gadget *g) /* interface descriptor: */ +static struct usb_interface_assoc_descriptor +ecm_iad_descriptor = { + .bLength = sizeof ecm_iad_descriptor, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + + /* .bFirstInterface = DYNAMIC, */ + .bInterfaceCount = 2, /* control + data */ + .bFunctionClass = USB_CLASS_COMM, + .bFunctionSubClass = USB_CDC_SUBCLASS_ETHERNET, + .bFunctionProtocol = USB_CDC_PROTO_NONE, + /* .iFunction = DYNAMIC */ +}; + + static struct usb_interface_descriptor ecm_control_intf = { .bLength = sizeof ecm_control_intf, .bDescriptorType = USB_DT_INTERFACE, @@ -199,6 +213,7 @@ static struct usb_endpoint_descriptor fs_ecm_out_desc = { static struct usb_descriptor_header *ecm_fs_function[] = { /* CDC ECM control descriptors */ + (struct usb_descriptor_header *) &ecm_iad_descriptor, (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, (struct usb_descriptor_header *) &ecm_union_desc, @@ -247,6 +262,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc = { static struct usb_descriptor_header *ecm_hs_function[] = { /* CDC ECM control descriptors */ + (struct usb_descriptor_header *) &ecm_iad_descriptor, (struct usb_descriptor_header *) &ecm_control_intf, (struct usb_descriptor_header *) &ecm_header_desc, (struct usb_descriptor_header *) &ecm_union_desc, @@ -339,6 +355,7 @@ static struct usb_string ecm_string_defs[] = { [0].s = "CDC Ethernet Control Model (ECM)", [1].s = NULL /* DYNAMIC */, [2].s = "CDC Ethernet Data", + [3].s = "CDC ECM", { } /* end of list */ }; @@ -674,6 +691,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f) if (status < 0) goto fail; ecm->ctrl_id = status; + ecm_iad_descriptor.bFirstInterface = status; ecm_control_intf.bInterfaceNumber = status; ecm_union_desc.bMasterInterface0 = status; @@ -864,6 +882,13 @@ ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN]) return status; ecm_string_defs[1].id = status; ecm_desc.iMACAddress = status; + + /* IAD label */ + status = usb_string_id(c->cdev); + if (status < 0) + return status; + ecm_string_defs[3].id = status; + ecm_iad_descriptor.iFunction = status; } /* allocate and initialize one new instance */ -- cgit v1.2.3-70-g09d2 From 5b3168763f507fd46285b7310fc2d18dafe7f1c7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 9 Jan 2012 10:32:49 +0100 Subject: dma: imx-dma: start transfer in issue_pending The DMA engine API requires that transfers are started in issue_pending instead of tx_submit. Fix this. Signed-off-by: Sascha Hauer [corrected change log to DMA engine API insteadof DMA API] Signed-off-by: Vinod Koul --- drivers/dma/imx-dma.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index e4383ee2c9a..3296a7337f2 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c @@ -186,8 +186,6 @@ static dma_cookie_t imxdma_tx_submit(struct dma_async_tx_descriptor *tx) cookie = imxdma_assign_cookie(imxdmac); - imx_dma_enable(imxdmac->imxdma_channel); - spin_unlock_irq(&imxdmac->lock); return cookie; @@ -332,9 +330,10 @@ static struct dma_async_tx_descriptor *imxdma_prep_dma_cyclic( static void imxdma_issue_pending(struct dma_chan *chan) { - /* - * Nothing to do. We only have a single descriptor - */ + struct imxdma_channel *imxdmac = to_imxdma_chan(chan); + + if (imxdmac->status == DMA_IN_PROGRESS) + imx_dma_enable(imxdmac->imxdma_channel); } static int __init imxdma_probe(struct platform_device *pdev) -- cgit v1.2.3-70-g09d2 From 2b4f130e05cb28a9794921aad5139615e94a7b02 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 9 Jan 2012 10:32:50 +0100 Subject: dma: imx-sdma: start transfer in issue_pending The DMA engine API requires that transfers are started in issue_pending instead of tx_submit. Fix this. Signed-off-by: Sascha Hauer [corrected change log to DMA engine API insteadof DMA API] Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index a8af379680c..e58dbf638cc 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -838,15 +838,12 @@ static dma_cookie_t sdma_tx_submit(struct dma_async_tx_descriptor *tx) { unsigned long flags; struct sdma_channel *sdmac = to_sdma_chan(tx->chan); - struct sdma_engine *sdma = sdmac->sdma; dma_cookie_t cookie; spin_lock_irqsave(&sdmac->lock, flags); cookie = sdma_assign_cookie(sdmac); - sdma_enable_channel(sdma, sdmac->channel); - spin_unlock_irqrestore(&sdmac->lock, flags); return cookie; @@ -1135,9 +1132,11 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan, static void sdma_issue_pending(struct dma_chan *chan) { - /* - * Nothing to do. We only have a single descriptor - */ + struct sdma_channel *sdmac = to_sdma_chan(chan); + struct sdma_engine *sdma = sdmac->sdma; + + if (sdmac->status == DMA_IN_PROGRESS) + sdma_enable_channel(sdma, sdmac->channel); } #define SDMA_SCRIPT_ADDRS_ARRAY_SIZE_V1 34 -- cgit v1.2.3-70-g09d2 From 1e0c66f49762fa1866ab20b1feb6e86a9aa4838f Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Sat, 28 Jan 2012 15:07:57 +0530 Subject: regulator: tps65910: Sleep control through external inputs Add support for sleep controls of different regulator through external inputs EN1, EN2 or EN3. Each regulator's output will be active when its external input is high and turns to OFF/Low power mode when its external input is low. The configuration parameters for sleep control is provided through board specific platform data. Signed-off-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/tps65910-regulator.c | 206 +++++++++++++++++++++++++++++++++ include/linux/mfd/tps65910.h | 8 ++ 2 files changed, 214 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c index 1d13cf997af..9092b7f998c 100644 --- a/drivers/regulator/tps65910-regulator.c +++ b/drivers/regulator/tps65910-regulator.c @@ -26,6 +26,9 @@ #include #define TPS65910_SUPPLY_STATE_ENABLED 0x1 +#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \ + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) /* supported VIO voltages in milivolts */ static const u16 VIO_VSEL_table[] = { @@ -252,6 +255,39 @@ static struct tps_info tps65911_regs[] = { }, }; +#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits)) +static unsigned int tps65910_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDD3, 1, 3), + EXT_CONTROL_REG_BITS(VDIG1, 0, 1), + EXT_CONTROL_REG_BITS(VDIG2, 0, 2), + EXT_CONTROL_REG_BITS(VPLL, 0, 6), + EXT_CONTROL_REG_BITS(VDAC, 0, 7), + EXT_CONTROL_REG_BITS(VAUX1, 0, 3), + EXT_CONTROL_REG_BITS(VAUX2, 0, 4), + EXT_CONTROL_REG_BITS(VAUX33, 0, 5), + EXT_CONTROL_REG_BITS(VMMC, 0, 0), +}; + +static unsigned int tps65911_ext_sleep_control[] = { + 0, + EXT_CONTROL_REG_BITS(VIO, 1, 0), + EXT_CONTROL_REG_BITS(VDD1, 1, 1), + EXT_CONTROL_REG_BITS(VDD2, 1, 2), + EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3), + EXT_CONTROL_REG_BITS(LDO1, 0, 1), + EXT_CONTROL_REG_BITS(LDO2, 0, 2), + EXT_CONTROL_REG_BITS(LDO3, 0, 7), + EXT_CONTROL_REG_BITS(LDO4, 0, 6), + EXT_CONTROL_REG_BITS(LDO5, 0, 3), + EXT_CONTROL_REG_BITS(LDO6, 0, 0), + EXT_CONTROL_REG_BITS(LDO7, 0, 5), + EXT_CONTROL_REG_BITS(LDO8, 0, 4), +}; + struct tps65910_reg { struct regulator_desc *desc; struct tps65910 *mfd; @@ -261,6 +297,8 @@ struct tps65910_reg { int num_regulators; int mode; int (*get_ctrl_reg)(int); + unsigned int *ext_sleep_control; + unsigned int board_ext_control[TPS65910_NUM_REGS]; }; static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) @@ -861,6 +899,131 @@ static struct regulator_ops tps65911_ops = { .list_voltage = tps65911_list_voltage, }; +static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic, + int id, int ext_sleep_config) +{ + struct tps65910 *mfd = pmic->mfd; + u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF; + u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF); + int ret; + + /* + * Regulator can not be control from multiple external input EN1, EN2 + * and EN3 together. + */ + if (ext_sleep_config & EXT_SLEEP_CONTROL) { + int en_count; + en_count = ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0); + en_count += ((ext_sleep_config & + TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0); + if (en_count > 1) { + dev_err(mfd->dev, + "External sleep control flag is not proper\n"); + return -EINVAL; + } + } + + pmic->board_ext_control[id] = ext_sleep_config; + + /* External EN1 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) + ret = tps65910_set_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN1_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN1\n"); + return ret; + } + + /* External EN2 control */ + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) + ret = tps65910_set_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN2_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN2\n"); + return ret; + } + + /* External EN3 control for TPS65910 LDO only */ + if ((tps65910_chip_id(mfd) == TPS65910) && + (id >= TPS65910_REG_VDIG1)) { + if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) + ret = tps65910_set_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + else + ret = tps65910_clear_bits(mfd, + TPS65910_EN3_LDO_ASS + regoffs, bit_pos); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring external control EN3\n"); + return ret; + } + } + + /* Return if no external control is selected */ + if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) { + /* Clear all sleep controls */ + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; + } + + /* + * For regulator that has separate operational and sleep register make + * sure that operational is used and clear sleep register to turn + * regulator off when external control is inactive + */ + if ((id == TPS65910_REG_VDD1) || + (id == TPS65910_REG_VDD2) || + ((id == TPS65911_REG_VDDCTRL) && + (tps65910_chip_id(mfd) == TPS65911))) { + int op_reg_add = pmic->get_ctrl_reg(id) + 1; + int sr_reg_add = pmic->get_ctrl_reg(id) + 2; + int opvsel = tps65910_reg_read(pmic, op_reg_add); + int srvsel = tps65910_reg_read(pmic, sr_reg_add); + if (opvsel & VDD1_OP_CMD_MASK) { + u8 reg_val = srvsel & VDD1_OP_SEL_MASK; + ret = tps65910_reg_write(pmic, op_reg_add, reg_val); + if (ret < 0) { + dev_err(mfd->dev, + "Error in configuring op register\n"); + return ret; + } + } + ret = tps65910_reg_write(pmic, sr_reg_add, 0); + if (ret < 0) { + dev_err(mfd->dev, "Error in settting sr register\n"); + return ret; + } + } + + ret = tps65910_clear_bits(mfd, + TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos); + if (!ret) + ret = tps65910_set_bits(mfd, + TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos); + if (ret < 0) + dev_err(mfd->dev, + "Error in configuring SLEEP register\n"); + return ret; +} + static __devinit int tps65910_probe(struct platform_device *pdev) { struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); @@ -891,11 +1054,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev) case TPS65910: pmic->get_ctrl_reg = &tps65910_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65910_regs); + pmic->ext_sleep_control = tps65910_ext_sleep_control; info = tps65910_regs; break; case TPS65911: pmic->get_ctrl_reg = &tps65911_get_ctrl_register; pmic->num_regulators = ARRAY_SIZE(tps65911_regs); + pmic->ext_sleep_control = tps65911_ext_sleep_control; info = tps65911_regs; break; default: @@ -958,6 +1123,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev) pmic->desc[i].ops = &tps65911_ops; } + err = tps65910_set_ext_sleep_config(pmic, i, + pmic_plat_data->regulator_ext_sleep_control[i]); + /* + * Failing on regulator for configuring externally control + * is not a serious issue, just throw warning. + */ + if (err < 0) + dev_warn(tps65910->dev, + "Failed to initialise ext control config\n"); + pmic->desc[i].type = REGULATOR_VOLTAGE; pmic->desc[i].owner = THIS_MODULE; @@ -1004,6 +1179,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev) return 0; } +static void tps65910_shutdown(struct platform_device *pdev) +{ + struct tps65910_reg *pmic = platform_get_drvdata(pdev); + int i; + + /* + * Before bootloader jumps to kernel, it makes sure that required + * external control signals are in desired state so that given rails + * can be configure accordingly. + * If rails are configured to be controlled from external control + * then before shutting down/rebooting the system, the external + * control configuration need to be remove from the rails so that + * its output will be available as per register programming even + * if external controls are removed. This is require when the POR + * value of the control signals are not in active state and before + * bootloader initializes it, the system requires the rail output + * to be active for booting. + */ + for (i = 0; i < pmic->num_regulators; i++) { + int err; + if (!pmic->rdev[i]) + continue; + + err = tps65910_set_ext_sleep_config(pmic, i, 0); + if (err < 0) + dev_err(&pdev->dev, + "Error in clearing external control\n"); + } +} + static struct platform_driver tps65910_driver = { .driver = { .name = "tps65910-pmic", @@ -1011,6 +1216,7 @@ static struct platform_driver tps65910_driver = { }, .probe = tps65910_probe, .remove = __devexit_p(tps65910_remove), + .shutdown = tps65910_shutdown, }; static int __init tps65910_init(void) diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h index d0cb12eba40..fa6c6bf7a54 100644 --- a/include/linux/mfd/tps65910.h +++ b/include/linux/mfd/tps65910.h @@ -768,6 +768,13 @@ /* Max number of TPS65910/11 regulators */ #define TPS65910_NUM_REGS 13 +/* External sleep controls through EN1/EN2/EN3 inputs*/ +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2 +#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4 +/* TPS65911 names the EN3 signal as SLEEP */ +#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x4 + /** * struct tps65910_board * Board platform data may be used to initialize regulators. @@ -779,6 +786,7 @@ struct tps65910_board { int irq_base; int vmbch_threshold; int vmbch2_threshold; + unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS]; struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; }; -- cgit v1.2.3-70-g09d2 From 608589b15f02e59e8c40df7ef861064f1b6fa504 Mon Sep 17 00:00:00 2001 From: wu guoxing Date: Mon, 30 Jan 2012 14:31:20 +0800 Subject: ARM/mx35/3ds: gpio: add mc9s08dz60 gpio function we only use the gpio function of mc9s08dz60 mcu chip, so just add the gpio driver, as this mcu will never be used in other board. Signed-off-by: Wu Guoxing Reviewed-by: Sascha Hauer Acked-by: Marc Kleine-Budde Signed-off-by: Grant Likely --- drivers/gpio/Kconfig | 6 ++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mc9s08dz60.c | 161 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 drivers/gpio/gpio-mc9s08dz60.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index d0c41188d4e..eaa7d3828e7 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -225,6 +225,12 @@ config GPIO_MAX732X_IRQ Say yes here to enable the max732x to be used as an interrupt controller. It requires the driver to be built in the kernel. +config GPIO_MC9S08DZ60 + bool "MX35 3DS BOARD MC9S08DZ60 GPIO functions" + depends on I2C && MACH_MX35_3DS + help + Select this to enable the MC9S08DZ60 GPIO driver + config GPIO_PCA953X tristate "PCA953x, PCA955x, TCA64xx, and MAX7310 I/O ports" depends on I2C diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index fa10df604c0..8863a7f2dec 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -26,6 +26,7 @@ obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o obj-$(CONFIG_GPIO_MAX7301) += gpio-max7301.o obj-$(CONFIG_GPIO_MAX732X) += gpio-max732x.o obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o +obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o diff --git a/drivers/gpio/gpio-mc9s08dz60.c b/drivers/gpio/gpio-mc9s08dz60.c new file mode 100644 index 00000000000..2738cc44d63 --- /dev/null +++ b/drivers/gpio/gpio-mc9s08dz60.c @@ -0,0 +1,161 @@ +/* + * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved. + * + * Author: Wu Guoxing + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#define GPIO_GROUP_NUM 2 +#define GPIO_NUM_PER_GROUP 8 +#define GPIO_NUM (GPIO_GROUP_NUM*GPIO_NUM_PER_GROUP) + +struct mc9s08dz60 { + struct i2c_client *client; + struct gpio_chip chip; +}; + +static inline struct mc9s08dz60 *to_mc9s08dz60(struct gpio_chip *gc) +{ + return container_of(gc, struct mc9s08dz60, chip); +} + + +static void mc9s_gpio_to_reg_and_bit(int offset, u8 *reg, u8 *bit) +{ + *reg = 0x20 + offset / GPIO_NUM_PER_GROUP; + *bit = offset % GPIO_NUM_PER_GROUP; +} + +static int mc9s08dz60_get_value(struct gpio_chip *gc, unsigned offset) +{ + u8 reg, bit; + s32 value; + struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc); + + mc9s_gpio_to_reg_and_bit(offset, ®, &bit); + value = i2c_smbus_read_byte_data(mc9s->client, reg); + + return (value >= 0) ? (value >> bit) & 0x1 : 0; +} + +static int mc9s08dz60_set(struct mc9s08dz60 *mc9s, unsigned offset, int val) +{ + u8 reg, bit; + s32 value; + + mc9s_gpio_to_reg_and_bit(offset, ®, &bit); + value = i2c_smbus_read_byte_data(mc9s->client, reg); + if (value >= 0) { + if (val) + value |= 1 << bit; + else + value &= ~(1 << bit); + + return i2c_smbus_write_byte_data(mc9s->client, reg, value); + } else + return value; + +} + + +static void mc9s08dz60_set_value(struct gpio_chip *gc, unsigned offset, int val) +{ + struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc); + + mc9s08dz60_set(mc9s, offset, val); +} + +static int mc9s08dz60_direction_output(struct gpio_chip *gc, + unsigned offset, int val) +{ + struct mc9s08dz60 *mc9s = to_mc9s08dz60(gc); + + return mc9s08dz60_set(mc9s, offset, val); +} + +static int mc9s08dz60_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct mc9s08dz60 *mc9s; + + mc9s = kzalloc(sizeof(*mc9s), GFP_KERNEL); + if (!mc9s) + return -ENOMEM; + + mc9s->chip.label = client->name; + mc9s->chip.base = -1; + mc9s->chip.dev = &client->dev; + mc9s->chip.owner = THIS_MODULE; + mc9s->chip.ngpio = GPIO_NUM; + mc9s->chip.can_sleep = 1; + mc9s->chip.get = mc9s08dz60_get_value; + mc9s->chip.set = mc9s08dz60_set_value; + mc9s->chip.direction_output = mc9s08dz60_direction_output; + mc9s->client = client; + i2c_set_clientdata(client, mc9s); + + ret = gpiochip_add(&mc9s->chip); + if (ret) + goto error; + + return 0; + + error: + kfree(mc9s); + return ret; +} + +static int mc9s08dz60_remove(struct i2c_client *client) +{ + struct mc9s08dz60 *mc9s; + int ret; + + mc9s = i2c_get_clientdata(client); + + ret = gpiochip_remove(&mc9s->chip); + if (!ret) + kfree(mc9s); + + return ret; + +} + +static const struct i2c_device_id mc9s08dz60_id[] = { + {"mc9s08dz60", 0}, + {}, +}; + +MODULE_DEVICE_TABLE(i2c, mc9s08dz60_id); + +static struct i2c_driver mc9s08dz60_i2c_driver = { + .driver = { + .owner = THIS_MODULE, + .name = "mc9s08dz60", + }, + .probe = mc9s08dz60_probe, + .remove = mc9s08dz60_remove, + .id_table = mc9s08dz60_id, +}; + +module_i2c_driver(mc9s08dz60_i2c_driver); + +MODULE_AUTHOR("Freescale Semiconductor, Inc. " + "Wu Guoxing "); +MODULE_DESCRIPTION("mc9s08dz60 gpio function on mx35 3ds board"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From 41b2d62702730b0c6bc5a40722e423bb0338311a Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Mon, 30 Jan 2012 10:53:55 -0500 Subject: ath9k: use WARN_ON_ONCE in ath_rc_get_highest_rix The device seems to survive the issue, so no need to flood the logs about it... Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/rc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index b3c3798fe51..635b592ad96 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -694,7 +694,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc, return rate; /* This should not happen */ - WARN_ON(1); + WARN_ON_ONCE(1); rate = ath_rc_priv->valid_rate_index[0]; -- cgit v1.2.3-70-g09d2 From 4191f19792bf91267835eb090d970e9cd6277a65 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 30 Jan 2012 15:08:16 +0100 Subject: regmap: if format_write is used, declare all registers as "unreadable" Using .format_write means, we have a custom function to write to the chip, but not to read back. Also, mark registers as "not precious" and "not volatile" which is implicit because we cannot read them. Make those functions use 'regmap_readable' to reuse the checks done there. Signed-off-by: Wolfram Sang Signed-off-by: Mark Brown --- drivers/base/regmap/regmap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 3c34526091d..b7198f57b69 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -36,6 +36,9 @@ bool regmap_readable(struct regmap *map, unsigned int reg) if (map->max_register && reg > map->max_register) return false; + if (map->format.format_write) + return false; + if (map->readable_reg) return map->readable_reg(map->dev, reg); @@ -44,7 +47,7 @@ bool regmap_readable(struct regmap *map, unsigned int reg) bool regmap_volatile(struct regmap *map, unsigned int reg) { - if (map->max_register && reg > map->max_register) + if (!regmap_readable(map, reg)) return false; if (map->volatile_reg) @@ -55,7 +58,7 @@ bool regmap_volatile(struct regmap *map, unsigned int reg) bool regmap_precious(struct regmap *map, unsigned int reg) { - if (map->max_register && reg > map->max_register) + if (!regmap_readable(map, reg)) return false; if (map->precious_reg) -- cgit v1.2.3-70-g09d2 From 8b1c36b357153f491ddea5363fdd397109c3326f Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 30 Jan 2012 16:53:37 +0000 Subject: sfc: MTD: Leave the DEBUG macro alone no longer defines DEBUG so we do not need to un-define it here. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/mtd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/mtd.c b/drivers/net/ethernet/sfc/mtd.c index eff49da458e..79c19227204 100644 --- a/drivers/net/ethernet/sfc/mtd.c +++ b/drivers/net/ethernet/sfc/mtd.c @@ -10,7 +10,6 @@ #include #include -#undef DEBUG /* has its own use for DEBUG */ #include #include #include -- cgit v1.2.3-70-g09d2 From 068c6ff1cbbfc09eed2b892dd7b0572dd6737785 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 29 Jan 2012 16:52:05 +0000 Subject: drm/i915: Remove the upper limit on the bo size for mapping into the CPU domain The original intention of comparing the bo against the mappable GTT limits was to prevent a subsequent faulting of the bo into the GTT from clearing the entire GTT in vain. However, that was clearly a cut'n'paste mistake as a CPU mapping never binds the bo into the aperture. Whilst there may be some merit to limiting the maximum size of the bo to something that can be utilized by the GPU, that limit itself does not belong as a safeguard to mmapping the bo, so remove the check entirely. Signed-off-by: Chris Wilson Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 721924150d0..df23c627341 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1141,7 +1141,6 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap *args = data; struct drm_gem_object *obj; unsigned long addr; @@ -1153,11 +1152,6 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; - if (obj->size > dev_priv->mm.gtt_mappable_end) { - drm_gem_object_unreference_unlocked(obj); - return -E2BIG; - } - down_write(¤t->mm->mmap_sem); addr = do_mmap(obj->filp, 0, args->size, PROT_READ | PROT_WRITE, MAP_SHARED, -- cgit v1.2.3-70-g09d2 From 06e63c57acbb1df7c35ebe846ae416a8b88dfafa Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 30 Jan 2012 16:55:05 +0000 Subject: sfc: Use a more sensible cast in efx_rx_buf_offset() This function returns the page offset of the buffer, which can be calculated based on either its DMA address or its virtual address. It used to use the virtual address and we would cast that to unsigned long, as anything smaller would result in a compiler warning. Now that it's using the DMA address we should use unsigned int, matching the return type. It is also unnecessary to use __force. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index a33aef25ead..1dfda5e2791 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -98,7 +98,7 @@ static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, /* Offset is always within one page, so we don't need to consider * the page order. */ - return ((__force unsigned long) buf->dma_addr & (PAGE_SIZE - 1)) + + return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) -- cgit v1.2.3-70-g09d2 From 3396c7823efb3a5b8630388c464e1034ea031ced Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 Jan 2012 13:36:01 +0000 Subject: drivers/net: fix up stale paths from driver reorg The reorganization of the driver layout in drivers/net left behind some stale paths in comments and in Kconfig help text. Bring them up to date. No actual change to any code takes place here. Signed-off-by: Paul Gortmaker CC: Jeff Kirsher Signed-off-by: David S. Miller --- Documentation/magic-number.txt | 2 +- Documentation/networking/phy.txt | 3 ++- Documentation/zh_CN/magic-number.txt | 2 +- drivers/net/can/slcan.c | 2 +- drivers/net/ethernet/3com/Kconfig | 2 +- drivers/net/ethernet/8390/ax88796.c | 2 +- drivers/net/ethernet/8390/axnet_cs.c | 2 +- drivers/net/ethernet/8390/pcnet_cs.c | 2 +- drivers/net/ethernet/amd/Kconfig | 2 +- drivers/net/ethernet/amd/am79c961a.c | 2 +- drivers/net/ethernet/amd/am79c961a.h | 2 +- drivers/net/ethernet/dec/tulip/21142.c | 2 +- drivers/net/ethernet/dec/tulip/eeprom.c | 2 +- drivers/net/ethernet/dec/tulip/interrupt.c | 2 +- drivers/net/ethernet/dec/tulip/media.c | 2 +- drivers/net/ethernet/dec/tulip/pnic.c | 2 +- drivers/net/ethernet/dec/tulip/pnic2.c | 2 +- drivers/net/ethernet/dec/tulip/timer.c | 2 +- drivers/net/ethernet/dec/tulip/tulip.h | 2 +- drivers/net/ethernet/ethoc.c | 2 +- drivers/net/ethernet/freescale/fec_mpc52xx.h | 2 +- drivers/net/ethernet/freescale/gianfar.c | 2 +- drivers/net/ethernet/freescale/gianfar.h | 2 +- drivers/net/ethernet/freescale/gianfar_ethtool.c | 2 +- drivers/net/ethernet/freescale/gianfar_sysfs.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_ethtool.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_hw.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_main.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_phyp.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_phyp.h | 2 +- drivers/net/ethernet/ibm/ehea/ehea_qmr.c | 2 +- drivers/net/ethernet/ibm/ehea/ehea_qmr.h | 2 +- drivers/net/ethernet/ibm/emac/core.c | 2 +- drivers/net/ethernet/ibm/emac/core.h | 2 +- drivers/net/ethernet/ibm/emac/debug.c | 2 +- drivers/net/ethernet/ibm/emac/debug.h | 2 +- drivers/net/ethernet/ibm/emac/emac.h | 2 +- drivers/net/ethernet/ibm/emac/mal.c | 2 +- drivers/net/ethernet/ibm/emac/mal.h | 2 +- drivers/net/ethernet/ibm/emac/phy.c | 2 +- drivers/net/ethernet/ibm/emac/phy.h | 2 +- drivers/net/ethernet/ibm/emac/rgmii.c | 2 +- drivers/net/ethernet/ibm/emac/rgmii.h | 2 +- drivers/net/ethernet/ibm/emac/tah.c | 2 +- drivers/net/ethernet/ibm/emac/tah.h | 2 +- drivers/net/ethernet/ibm/emac/zmii.c | 2 +- drivers/net/ethernet/ibm/emac/zmii.h | 2 +- drivers/net/ethernet/micrel/ks8851.c | 2 +- drivers/net/ethernet/micrel/ks8851.h | 2 +- drivers/net/ethernet/micrel/ks8851_mll.c | 2 +- drivers/net/ethernet/micrel/ksz884x.c | 2 +- drivers/net/ethernet/netx-eth.c | 2 +- drivers/net/ethernet/realtek/Kconfig | 10 +++++----- 54 files changed, 59 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt index abf481f780e..82761a31d64 100644 --- a/Documentation/magic-number.txt +++ b/Documentation/magic-number.txt @@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h MGSLPC_MAGIC 0x5402 mgslpc_info drivers/char/pcmcia/synclink_cs.c TTY_LDISC_MAGIC 0x5403 tty_ldisc include/linux/tty_ldisc.h USB_SERIAL_MAGIC 0x6702 usb_serial drivers/usb/serial/usb-serial.h -FULL_DUPLEX_MAGIC 0x6969 drivers/net/tulip/de2104x.c +FULL_DUPLEX_MAGIC 0x6969 drivers/net/ethernet/dec/tulip/de2104x.c USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt index 9eb1ba52013..95e5f5985a2 100644 --- a/Documentation/networking/phy.txt +++ b/Documentation/networking/phy.txt @@ -62,7 +62,8 @@ The MDIO bus 5) The bus must also be declared somewhere as a device, and registered. As an example for how one driver implemented an mdio bus driver, see - drivers/net/gianfar_mii.c and arch/ppc/syslib/mpc85xx_devices.c + drivers/net/ethernet/freescale/fsl_pq_mdio.c and an associated DTS file + for one of the users. (e.g. "git grep fsl,.*-mdio arch/powerpc/boot/dts/") Connecting to a PHY diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt index c278f412dc6..f606ba8598c 100644 --- a/Documentation/zh_CN/magic-number.txt +++ b/Documentation/zh_CN/magic-number.txt @@ -89,7 +89,7 @@ TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h MGSLPC_MAGIC 0x5402 mgslpc_info drivers/char/pcmcia/synclink_cs.c TTY_LDISC_MAGIC 0x5403 tty_ldisc include/linux/tty_ldisc.h USB_SERIAL_MAGIC 0x6702 usb_serial drivers/usb/serial/usb-serial.h -FULL_DUPLEX_MAGIC 0x6969 drivers/net/tulip/de2104x.c +FULL_DUPLEX_MAGIC 0x6969 drivers/net/ethernet/dec/tulip/de2104x.c USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 3f1ebcc2cb8..579e7fca644 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -1,7 +1,7 @@ /* * slcan.c - serial line CAN interface driver (using tty line discipline) * - * This file is derived from linux/drivers/net/slip.c + * This file is derived from linux/drivers/net/slip/slip.c * * slip.c Authors : Laurence Culhane * Fred N. van Kempen diff --git a/drivers/net/ethernet/3com/Kconfig b/drivers/net/ethernet/3com/Kconfig index a8bb30cf512..bad4fa6815c 100644 --- a/drivers/net/ethernet/3com/Kconfig +++ b/drivers/net/ethernet/3com/Kconfig @@ -97,7 +97,7 @@ config VORTEX available from . More specific information is in and in the comments at - the beginning of . + the beginning of . To compile this support as a module, choose M here. diff --git a/drivers/net/ethernet/8390/ax88796.c b/drivers/net/ethernet/8390/ax88796.c index 0f92e3567f6..c30adcc9828 100644 --- a/drivers/net/ethernet/8390/ax88796.c +++ b/drivers/net/ethernet/8390/ax88796.c @@ -1,4 +1,4 @@ -/* drivers/net/ax88796.c +/* drivers/net/ethernet/8390/ax88796.c * * Copyright 2005,2007 Simtec Electronics * Ben Dooks diff --git a/drivers/net/ethernet/8390/axnet_cs.c b/drivers/net/ethernet/8390/axnet_cs.c index bba51cdc74a..5de394368ff 100644 --- a/drivers/net/ethernet/8390/axnet_cs.c +++ b/drivers/net/ethernet/8390/axnet_cs.c @@ -192,7 +192,7 @@ static int get_prom(struct pcmcia_device *link) unsigned int ioaddr = dev->base_addr; int i, j; - /* This is based on drivers/net/ne.c */ + /* This is based on drivers/net/ethernet/8390/ne.c */ struct { u_char value, offset; } program_seq[] = { diff --git a/drivers/net/ethernet/8390/pcnet_cs.c b/drivers/net/ethernet/8390/pcnet_cs.c index 053b2551a72..f2a4e5de18c 100644 --- a/drivers/net/ethernet/8390/pcnet_cs.c +++ b/drivers/net/ethernet/8390/pcnet_cs.c @@ -326,7 +326,7 @@ static hw_info_t *get_prom(struct pcmcia_device *link) u_char prom[32]; int i, j; - /* This is lifted straight from drivers/net/ne.c */ + /* This is lifted straight from drivers/net/ethernet/8390/ne.c */ struct { u_char value, offset; } program_seq[] = { diff --git a/drivers/net/ethernet/amd/Kconfig b/drivers/net/ethernet/amd/Kconfig index 238b537b68f..8350f4b37a8 100644 --- a/drivers/net/ethernet/amd/Kconfig +++ b/drivers/net/ethernet/amd/Kconfig @@ -113,7 +113,7 @@ config DEPCA If you have a network (Ethernet) card of this type, say Y and read the Ethernet-HOWTO, available from as well as - . + . To compile this driver as a module, choose M here. The module will be called depca. diff --git a/drivers/net/ethernet/amd/am79c961a.c b/drivers/net/ethernet/amd/am79c961a.c index 7d5ded80d2d..216ae87b945 100644 --- a/drivers/net/ethernet/amd/am79c961a.c +++ b/drivers/net/ethernet/amd/am79c961a.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/am79c961.c + * linux/drivers/net/ethernet/amd/am79c961a.c * * by Russell King 1995-2001. * diff --git a/drivers/net/ethernet/amd/am79c961a.h b/drivers/net/ethernet/amd/am79c961a.h index fd634d32756..9f384b79507 100644 --- a/drivers/net/ethernet/amd/am79c961a.h +++ b/drivers/net/ethernet/amd/am79c961a.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/arm/am79c961a.h + * linux/drivers/net/ethernet/amd/am79c961a.h * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/net/ethernet/dec/tulip/21142.c b/drivers/net/ethernet/dec/tulip/21142.c index 25b8deedbef..36985827265 100644 --- a/drivers/net/ethernet/dec/tulip/21142.c +++ b/drivers/net/ethernet/dec/tulip/21142.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/21142.c + drivers/net/ethernet/dec/tulip/21142.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/eeprom.c b/drivers/net/ethernet/dec/tulip/eeprom.c index 14d5b611783..ed7d1dcd956 100644 --- a/drivers/net/ethernet/dec/tulip/eeprom.c +++ b/drivers/net/ethernet/dec/tulip/eeprom.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/eeprom.c + drivers/net/ethernet/dec/tulip/eeprom.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/interrupt.c b/drivers/net/ethernet/dec/tulip/interrupt.c index 4fb8c8c0a42..feaee7424bd 100644 --- a/drivers/net/ethernet/dec/tulip/interrupt.c +++ b/drivers/net/ethernet/dec/tulip/interrupt.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/interrupt.c + drivers/net/ethernet/dec/tulip/interrupt.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/media.c b/drivers/net/ethernet/dec/tulip/media.c index beeb17b52ad..ae937c6749e 100644 --- a/drivers/net/ethernet/dec/tulip/media.c +++ b/drivers/net/ethernet/dec/tulip/media.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/media.c + drivers/net/ethernet/dec/tulip/media.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/pnic.c b/drivers/net/ethernet/dec/tulip/pnic.c index 9c16e4ad02a..5364563c437 100644 --- a/drivers/net/ethernet/dec/tulip/pnic.c +++ b/drivers/net/ethernet/dec/tulip/pnic.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/pnic.c + drivers/net/ethernet/dec/tulip/pnic.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/pnic2.c b/drivers/net/ethernet/dec/tulip/pnic2.c index 04a7e477eaf..5895fc43f6e 100644 --- a/drivers/net/ethernet/dec/tulip/pnic2.c +++ b/drivers/net/ethernet/dec/tulip/pnic2.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/pnic2.c + drivers/net/ethernet/dec/tulip/pnic2.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/timer.c b/drivers/net/ethernet/dec/tulip/timer.c index 19078d28ffb..768379b8aee 100644 --- a/drivers/net/ethernet/dec/tulip/timer.c +++ b/drivers/net/ethernet/dec/tulip/timer.c @@ -1,5 +1,5 @@ /* - drivers/net/tulip/timer.c + drivers/net/ethernet/dec/tulip/timer.c Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/dec/tulip/tulip.h b/drivers/net/ethernet/dec/tulip/tulip.h index fb3887c18dc..38431a155f0 100644 --- a/drivers/net/ethernet/dec/tulip/tulip.h +++ b/drivers/net/ethernet/dec/tulip/tulip.h @@ -1,5 +1,5 @@ /* - drivers/net/tulip/tulip.h + drivers/net/ethernet/dec/tulip/tulip.h Copyright 2000,2001 The Linux Kernel Team Written/copyright 1994-2001 by Donald Becker. diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 60f0e788cc2..388c592b5ef 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ethoc.c + * linux/drivers/net/ethernet/ethoc.c * * Copyright (C) 2007-2008 Avionic Design Development GmbH * Copyright (C) 2008-2009 Avionic Design GmbH diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.h b/drivers/net/ethernet/freescale/fec_mpc52xx.h index 41d2dffde55..10afa54dd06 100644 --- a/drivers/net/ethernet/freescale/fec_mpc52xx.h +++ b/drivers/net/ethernet/freescale/fec_mpc52xx.h @@ -1,5 +1,5 @@ /* - * drivers/drivers/net/fec_mpc52xx/fec.h + * drivers/net/ethernet/freescale/fec_mpc52xx.h * * Driver for the MPC5200 Fast Ethernet Controller * diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 39d160d353a..adb0ae4e419 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.c + * drivers/net/ethernet/freescale/gianfar.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h index 40c33a7554c..4fe0f342ace 100644 --- a/drivers/net/ethernet/freescale/gianfar.h +++ b/drivers/net/ethernet/freescale/gianfar.h @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar.h + * drivers/net/ethernet/freescale/gianfar.h * * Gianfar Ethernet Driver * Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560 diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 5a3b2e5b288..5a78d55f46e 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_ethtool.c + * drivers/net/ethernet/freescale/gianfar_ethtool.c * * Gianfar Ethernet Driver * Ethtool support for Gianfar Enet diff --git a/drivers/net/ethernet/freescale/gianfar_sysfs.c b/drivers/net/ethernet/freescale/gianfar_sysfs.c index 64f4094ac7f..cd14a4d449c 100644 --- a/drivers/net/ethernet/freescale/gianfar_sysfs.c +++ b/drivers/net/ethernet/freescale/gianfar_sysfs.c @@ -1,5 +1,5 @@ /* - * drivers/net/gianfar_sysfs.c + * drivers/net/ethernet/freescale/gianfar_sysfs.c * * Gianfar Ethernet Driver * This driver is designed for the non-CPM ethernet controllers diff --git a/drivers/net/ethernet/ibm/ehea/ehea.h b/drivers/net/ethernet/ibm/ehea/ehea.h index 6650068c996..b8e46cc31e5 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea.h +++ b/drivers/net/ethernet/ibm/ehea/ehea.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea.h + * linux/drivers/net/ethernet/ibm/ehea/ehea.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c index 6bdd8e36e56..95837b99a46 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_ethtool.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_ethtool.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_hw.h b/drivers/net/ethernet/ibm/ehea/ehea_hw.h index 1a2fe4dc3eb..180d4128a71 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_hw.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_hw.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_hw.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_hw.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 5d5fb262718..14507d1e78c 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_main.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_main.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c index 0506967b904..30f903332e9 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_phyp.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h index 2f8174c248b..52c456ec4d6 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_phyp.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_phyp.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_phyp.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_phyp.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c index c25b05b94da..4fb47f14dbf 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.c @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_qmr.c + * linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.c * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h index 337a47ecf4a..8e4a70c20ab 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_qmr.h +++ b/drivers/net/ethernet/ibm/ehea/ehea_qmr.h @@ -1,5 +1,5 @@ /* - * linux/drivers/net/ehea/ehea_qmr.h + * linux/drivers/net/ethernet/ibm/ehea/ehea_qmr.h * * eHEA ethernet device driver for IBM eServer System p * diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index 2abce965c7b..d47c16e02d0 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/core.c + * drivers/net/ethernet/ibm/emac/core.c * * Driver for PowerPC 4xx on-chip ethernet controller. * diff --git a/drivers/net/ethernet/ibm/emac/core.h b/drivers/net/ethernet/ibm/emac/core.h index fa3ec57935f..bade29690c7 100644 --- a/drivers/net/ethernet/ibm/emac/core.h +++ b/drivers/net/ethernet/ibm/emac/core.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/core.h + * drivers/net/ethernet/ibm/emac/core.h * * Driver for PowerPC 4xx on-chip ethernet controller. * diff --git a/drivers/net/ethernet/ibm/emac/debug.c b/drivers/net/ethernet/ibm/emac/debug.c index 8c6c1e2a875..b16b4828b64 100644 --- a/drivers/net/ethernet/ibm/emac/debug.c +++ b/drivers/net/ethernet/ibm/emac/debug.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/debug.c + * drivers/net/ethernet/ibm/emac/debug.c * * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. * diff --git a/drivers/net/ethernet/ibm/emac/debug.h b/drivers/net/ethernet/ibm/emac/debug.h index 90477fe69d0..59a92d5870b 100644 --- a/drivers/net/ethernet/ibm/emac/debug.h +++ b/drivers/net/ethernet/ibm/emac/debug.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/debug.h + * drivers/net/ethernet/ibm/emac/debug.h * * Driver for PowerPC 4xx on-chip ethernet controller, debug print routines. * diff --git a/drivers/net/ethernet/ibm/emac/emac.h b/drivers/net/ethernet/ibm/emac/emac.h index 1568278d759..b44bd243fb5 100644 --- a/drivers/net/ethernet/ibm/emac/emac.h +++ b/drivers/net/ethernet/ibm/emac/emac.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/emac.h + * drivers/net/ethernet/ibm/emac/emac.h * * Register definitions for PowerPC 4xx on-chip ethernet contoller * diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c index f3c50b97ec6..479e43e2f1e 100644 --- a/drivers/net/ethernet/ibm/emac/mal.c +++ b/drivers/net/ethernet/ibm/emac/mal.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/mal.c + * drivers/net/ethernet/ibm/emac/mal.c * * Memory Access Layer (MAL) support * diff --git a/drivers/net/ethernet/ibm/emac/mal.h b/drivers/net/ethernet/ibm/emac/mal.h index d06f985bda3..e431a32e3d6 100644 --- a/drivers/net/ethernet/ibm/emac/mal.h +++ b/drivers/net/ethernet/ibm/emac/mal.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/mal.h + * drivers/net/ethernet/ibm/emac/mal.h * * Memory Access Layer (MAL) support * diff --git a/drivers/net/ethernet/ibm/emac/phy.c b/drivers/net/ethernet/ibm/emac/phy.c index ab4e5969fe6..d3b9d103353 100644 --- a/drivers/net/ethernet/ibm/emac/phy.c +++ b/drivers/net/ethernet/ibm/emac/phy.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/phy.c + * drivers/net/ethernet/ibm/emac/phy.c * * Driver for PowerPC 4xx on-chip ethernet controller, PHY support. * Borrowed from sungem_phy.c, though I only kept the generic MII diff --git a/drivers/net/ethernet/ibm/emac/phy.h b/drivers/net/ethernet/ibm/emac/phy.h index 5d2bf4cbe50..d7e41ec3746 100644 --- a/drivers/net/ethernet/ibm/emac/phy.h +++ b/drivers/net/ethernet/ibm/emac/phy.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/phy.h + * drivers/net/ethernet/ibm/emac/phy.h * * Driver for PowerPC 4xx on-chip ethernet controller, PHY support * diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index 4fa53f3def6..05484f918ee 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/rgmii.c + * drivers/net/ethernet/ibm/emac/rgmii.c * * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/rgmii.h b/drivers/net/ethernet/ibm/emac/rgmii.h index 9296b6c5f92..668bceeff4a 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.h +++ b/drivers/net/ethernet/ibm/emac/rgmii.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/rgmii.h + * drivers/net/ethernet/ibm/emac/rgmii.h * * Driver for PowerPC 4xx on-chip ethernet controller, RGMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index 5f51bf7c9dc..0d9881efe2f 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/tah.c + * drivers/net/ethernet/ibm/emac/tah.c * * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. * diff --git a/drivers/net/ethernet/ibm/emac/tah.h b/drivers/net/ethernet/ibm/emac/tah.h index 3437ab4964c..350b7096a04 100644 --- a/drivers/net/ethernet/ibm/emac/tah.h +++ b/drivers/net/ethernet/ibm/emac/tah.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/tah.h + * drivers/net/ethernet/ibm/emac/tah.h * * Driver for PowerPC 4xx on-chip ethernet controller, TAH support. * diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index 97449e786d6..e799a6116ba 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/zmii.c + * drivers/net/ethernet/ibm/emac/zmii.c * * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. * diff --git a/drivers/net/ethernet/ibm/emac/zmii.h b/drivers/net/ethernet/ibm/emac/zmii.h index ceaed823a83..455bfb08549 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.h +++ b/drivers/net/ethernet/ibm/emac/zmii.h @@ -1,5 +1,5 @@ /* - * drivers/net/ibm_newemac/zmii.h + * drivers/net/ethernet/ibm/emac/zmii.h * * Driver for PowerPC 4xx on-chip ethernet controller, ZMII bridge support. * diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 6b35e7da9a9..134c4d07936 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.c +/* drivers/net/ethernet/micrel/ks8851.c * * Copyright 2009 Simtec Electronics * http://www.simtec.co.uk/ diff --git a/drivers/net/ethernet/micrel/ks8851.h b/drivers/net/ethernet/micrel/ks8851.h index b0fae86aaca..852256ef1f2 100644 --- a/drivers/net/ethernet/micrel/ks8851.h +++ b/drivers/net/ethernet/micrel/ks8851.h @@ -1,4 +1,4 @@ -/* drivers/net/ks8851.h +/* drivers/net/ethernet/micrel/ks8851.h * * Copyright 2009 Simtec Electronics * Ben Dooks diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index e58e78e5c93..a37264e61a2 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1,5 +1,5 @@ /** - * drivers/net/ks8851_mll.c + * drivers/net/ethernet/micrel/ks8851_mll.c * Copyright (c) 2009 Micrel Inc. * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index e52cd310ae7..2725d693c3c 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -1,5 +1,5 @@ /** - * drivers/net/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver + * drivers/net/ethernet/micrel/ksx884x.c - Micrel KSZ8841/2 PCI Ethernet driver * * Copyright (c) 2009-2010 Micrel, Inc. * Tristram Ha diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index 8d288af16fc..a18bb10b4f0 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -1,5 +1,5 @@ /* - * drivers/net/netx-eth.c + * drivers/net/ethernet/netx-eth.c * * Copyright (c) 2005 Sascha Hauer , Pengutronix * diff --git a/drivers/net/ethernet/realtek/Kconfig b/drivers/net/ethernet/realtek/Kconfig index 0578859a3c7..5821966f9f2 100644 --- a/drivers/net/ethernet/realtek/Kconfig +++ b/drivers/net/ethernet/realtek/Kconfig @@ -24,11 +24,11 @@ config ATP select CRC32 ---help--- This is a network (Ethernet) device which attaches to your parallel - port. Read as well as the Ethernet-HOWTO, - available from , if you - want to use this. If you intend to use this driver, you should have - said N to the "Parallel printer support", because the two drivers - don't like each other. + port. Read as well as the + Ethernet-HOWTO, available from , + if you want to use this. If you intend to use this driver, you + should have said N to the "Parallel printer support", because the two + drivers don't like each other. To compile this driver as a module, choose M here: the module will be called atp. -- cgit v1.2.3-70-g09d2 From 5e6bbedd8238edbfee03d2950369edb08773cd3c Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Fri, 27 Jan 2012 13:55:46 +0000 Subject: drivers/net: strip unused module code from sun3_82586.c This code is clearly unused, since it has a #error right in it. Given the vintage of sun3 hardware, it is probably safe to assume that there is little interest in adding new functionality to the driver now, so just delete the unused block of code. Signed-off-by: Paul Gortmaker Signed-off-by: Sam Creasey Signed-off-by: David S. Miller --- drivers/net/ethernet/i825xx/sun3_82586.c | 25 ------------------------- 1 file changed, 25 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/i825xx/sun3_82586.c b/drivers/net/ethernet/i825xx/sun3_82586.c index 6ef5e11d1c8..296cf8a0ee5 100644 --- a/drivers/net/ethernet/i825xx/sun3_82586.c +++ b/drivers/net/ethernet/i825xx/sun3_82586.c @@ -28,7 +28,6 @@ static int automatic_resume = 0; /* experimental .. better should be zero */ static int rfdadd = 0; /* rfdadd=1 may be better for 8K MEM cards */ static int fifo=0x8; /* don't change */ -#include #include #include #include @@ -1151,28 +1150,6 @@ static void set_multicast_list(struct net_device *dev) netif_wake_queue(dev); } -#ifdef MODULE -#error This code is not currently supported as a module -static struct net_device *dev_sun3_82586; - -int init_module(void) -{ - dev_sun3_82586 = sun3_82586_probe(-1); - if (IS_ERR(dev_sun3_82586)) - return PTR_ERR(dev_sun3_82586); - return 0; -} - -void cleanup_module(void) -{ - unsigned long ioaddr = dev_sun3_82586->base_addr; - unregister_netdev(dev_sun3_82586); - release_region(ioaddr, SUN3_82586_TOTAL_SIZE); - iounmap((void *)ioaddr); - free_netdev(dev_sun3_82586); -} -#endif /* MODULE */ - #if 0 /* * DUMP .. we expect a not running CMD unit and enough space @@ -1209,5 +1186,3 @@ void sun3_82586_dump(struct net_device *dev,void *ptr) printk("\n"); } #endif - -MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 5f1127ffbae3029fde5dc1464ec3c26cdf34cb80 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 24 Jan 2012 13:50:16 +0200 Subject: ath6kl: fix testmode when fw-2.bin or fw-3.bin is used Testmode (TCMD and ART) was not enabled when fw-2.bin or fw-3.bin files were available, fix that by fetching testmode file just after the board file but before rest of the firmware files are fetched. I also added testmode field to struct ath6kl and moved the module parameter to core.c. Now all module parameters are grouped in one place. Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.c | 4 ++ drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/init.c | 74 +++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 0d92e7179f8..2a5198185d5 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -28,11 +28,13 @@ unsigned int debug_mask; static bool suspend_cutpower; static unsigned int uart_debug; static unsigned int ath6kl_p2p; +static unsigned int testmode; module_param(debug_mask, uint, 0644); module_param(suspend_cutpower, bool, 0444); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); +module_param(testmode, uint, 0644); int ath6kl_core_init(struct ath6kl *ar) { @@ -76,6 +78,8 @@ int ath6kl_core_init(struct ath6kl *ar) goto err_power_off; } + ar->testmode = testmode; + ret = ath6kl_init_fetch_firmwares(ar); if (ret) goto err_htc_cleanup; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ed9fcc11b5f..7f1869d00d7 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -532,6 +532,7 @@ struct ath6kl { struct wiphy *wiphy; enum ath6kl_state state; + unsigned int testmode; struct ath6kl_bmi bmi; const struct ath6kl_hif_ops *hif_ops; diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index 4d8eb1cca6e..bf56e5f1761 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -27,10 +27,6 @@ #include "debug.h" #include "hif-ops.h" -static unsigned int testmode; - -module_param(testmode, uint, 0644); - static const struct ath6kl_hw hw_list[] = { { .id = AR6003_HW_2_0_VERSION, @@ -731,39 +727,54 @@ static int ath6kl_fetch_otp_file(struct ath6kl *ar) return 0; } -static int ath6kl_fetch_fw_file(struct ath6kl *ar) +static int ath6kl_fetch_testmode_file(struct ath6kl *ar) { char filename[100]; int ret; - if (ar->fw != NULL) + if (ar->testmode == 0) return 0; - if (testmode) { - ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", - testmode); - if (testmode == 2) { - if (ar->hw.fw.utf == NULL) { - ath6kl_warn("testmode 2 not supported\n"); - return -EOPNOTSUPP; - } + ath6kl_dbg(ATH6KL_DBG_BOOT, "testmode %d\n", ar->testmode); - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.utf); - } else { - if (ar->hw.fw.tcmd == NULL) { - ath6kl_warn("testmode 1 not supported\n"); - return -EOPNOTSUPP; - } + if (ar->testmode == 2) { + if (ar->hw.fw.utf == NULL) { + ath6kl_warn("testmode 2 not supported\n"); + return -EOPNOTSUPP; + } - snprintf(filename, sizeof(filename), "%s/%s", - ar->hw.fw.dir, ar->hw.fw.tcmd); + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.utf); + } else { + if (ar->hw.fw.tcmd == NULL) { + ath6kl_warn("testmode 1 not supported\n"); + return -EOPNOTSUPP; } - set_bit(TESTMODE, &ar->flag); - goto get_fw; + snprintf(filename, sizeof(filename), "%s/%s", + ar->hw.fw.dir, ar->hw.fw.tcmd); } + set_bit(TESTMODE, &ar->flag); + + ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); + if (ret) { + ath6kl_err("Failed to get testmode %d firmware file %s: %d\n", + ar->testmode, filename, ret); + return ret; + } + + return 0; +} + +static int ath6kl_fetch_fw_file(struct ath6kl *ar) +{ + char filename[100]; + int ret; + + if (ar->fw != NULL) + return 0; + /* FIXME: remove WARN_ON() as we won't support FW API 1 for long */ if (WARN_ON(ar->hw.fw.fw == NULL)) return -EINVAL; @@ -771,7 +782,6 @@ static int ath6kl_fetch_fw_file(struct ath6kl *ar) snprintf(filename, sizeof(filename), "%s/%s", ar->hw.fw.dir, ar->hw.fw.fw); -get_fw: ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len); if (ret) { ath6kl_err("Failed to get firmware file %s: %d\n", @@ -812,7 +822,7 @@ static int ath6kl_fetch_testscript_file(struct ath6kl *ar) char filename[100]; int ret; - if (testmode != 2) + if (ar->testmode != 2) return 0; if (ar->fw_testscript != NULL) @@ -927,6 +937,10 @@ static int ath6kl_fetch_fw_apin(struct ath6kl *ar, const char *name) ath6kl_dbg(ATH6KL_DBG_BOOT, "found fw image ie (%zd B)\n", ie_len); + /* in testmode we already might have a fw file */ + if (ar->fw != NULL) + break; + ar->fw = kmemdup(data, ie_len, GFP_KERNEL); if (ar->fw == NULL) { @@ -1038,6 +1052,10 @@ int ath6kl_init_fetch_firmwares(struct ath6kl *ar) if (ret) return ret; + ret = ath6kl_fetch_testmode_file(ar); + if (ret) + return ret; + ret = ath6kl_fetch_fw_apin(ar, ATH6KL_FW_API3_FILE); if (ret == 0) { ar->fw_api = 3; @@ -1283,7 +1301,7 @@ static int ath6kl_upload_testscript(struct ath6kl *ar) u32 address, param; int ret; - if (testmode != 2) + if (ar->testmode != 2) return 0; if (ar->fw_testscript == NULL) -- cgit v1.2.3-70-g09d2 From c86515412f0c364f2d45029b45d5909614087af3 Mon Sep 17 00:00:00 2001 From: Vasanthakumar Thiagarajan Date: Thu, 26 Jan 2012 13:17:18 +0530 Subject: ath6kl: Fix kernel panic during rx aggregation "ath6kl: Define a structure for connection specific aggregation information" introduces this. In aggr_conn_init(), vif->aggr_cntxt is assigned to aggr_conn->aggr_info, but vif->aggr_cntxt is not initialized at this point, this would end up accessing an invalid pointer in aggregation receive path. Fix this by passing the correct aggr_info to aggr_conn_init(). The panic trace would look like. [] panic+0xa1/0x1c6 [] ? kmsg_dump+0xfd/0x160 [] oops_end+0xea/0xf0 [] no_context+0x11d/0x2d0 [] __bad_area_nosemaphore+0x14d/0x230 [] ? do_page_fault+0x30d/0x520 [] bad_area_nosemaphore+0x13/0x20 [] do_page_fault+0x3bd/0x520 [] ? __lock_acquire+0x320/0x1680 [] ? trace_hardirqs_off_thunk+0x3a/0x3c [] page_fault+0x25/0x30 [] ? aggr_slice_amsdu+0xdf/0x170 [ath6kl_core] [] aggr_deque_frms+0xbc/0x190 [ath6kl_core] [] ath6kl_rx+0x3e4/0xae0 [ath6kl_core] [] ath6kl_htc_rxmsg_pending_handler+0x8b7/0xf10 [ath6kl_core] [] ? mmc_do_release_host+0x70/0x90 [mmc_core] [] ? mmc_release_host+0x2a/0x50 [mmc_core] [] ? ath6kl_alloc_amsdu_rxbuf+0x140/0x140 [ath6kl_core] [] ath6kl_hif_intr_bh_handler+0x362/0x510 [ath6kl_core] [] ath6kl_sdio_irq_handler+0x60/0xb0 [ath6kl_sdio] [] sdio_irq_thread+0xec/0x320 [mmc_core] [] ? sdio_claim_irq+0x220/0x220 [mmc_core] [] ? sdio_claim_irq+0x220/0x220 [mmc_core] [] kthread+0xbe/0xd0 [] kernel_thread_helper+0x4/0x10 [] ? retint_restore_args+0x13/0x13 [] ? __init_kthread_worker+0x70/0x70 [] ? gs_change+0x13/0x13 Signed-off-by: Vasanthakumar Thiagarajan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.h | 3 ++- drivers/net/wireless/ath/ath6kl/main.c | 2 +- drivers/net/wireless/ath/ath6kl/txrx.c | 7 ++++--- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 7f1869d00d7..426f269e8ab 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -715,7 +715,8 @@ void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie); int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev); struct aggr_info *aggr_init(struct ath6kl_vif *vif); -void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn); +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn); void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint); void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count); diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c index 39da1f98da8..b96d01a7919 100644 --- a/drivers/net/wireless/ath/ath6kl/main.c +++ b/drivers/net/wireless/ath/ath6kl/main.c @@ -74,7 +74,7 @@ static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid, ar->sta_list_index = ar->sta_list_index | (1 << free_slot); ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid); - aggr_conn_init(vif, sta->aggr_conn); + aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn); } static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i) diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c index 62c12102e14..a3dc6943c7f 100644 --- a/drivers/net/wireless/ath/ath6kl/txrx.c +++ b/drivers/net/wireless/ath/ath6kl/txrx.c @@ -1674,7 +1674,8 @@ void aggr_recv_addba_req_evt(struct ath6kl_vif *vif, u8 tid_mux, u16 seq_no, rxtid->aggr = true; } -void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) +void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info *aggr_info, + struct aggr_info_conn *aggr_conn) { struct rxtid *rxtid; u8 i; @@ -1684,7 +1685,7 @@ void aggr_conn_init(struct ath6kl_vif *vif, struct aggr_info_conn *aggr_conn) init_timer(&aggr_conn->timer); aggr_conn->timer.function = aggr_timeout; aggr_conn->timer.data = (unsigned long) aggr_conn; - aggr_conn->aggr_info = vif->aggr_cntxt; + aggr_conn->aggr_info = aggr_info; aggr_conn->timer_scheduled = false; @@ -1716,7 +1717,7 @@ struct aggr_info *aggr_init(struct ath6kl_vif *vif) return NULL; } - aggr_conn_init(vif, p_aggr->aggr_conn); + aggr_conn_init(vif, p_aggr, p_aggr->aggr_conn); skb_queue_head_init(&p_aggr->rx_amsdu_freeq); ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS); -- cgit v1.2.3-70-g09d2 From e390af779dc671551800514d391928f5a798089a Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:09 +0530 Subject: ath6kl: Re-architect suspend mode handling in ath6kl_sdio_suspend Using this patch, the user can bypass existing auto suspend mode selection logic and force ath6kl to enter into the suspend mode what he/she wants. If the user doesn't choose any suspend mode while doing insmod of the driver, auto suspend mode selection logic will kick in and choose suspend mode based on the host SDIO controller capability. Generic module parameter is required to specify suspend mode including Deep Sleep and WOW while doing insmod. Renaming existing mod param variable suspend_cutpower would be sufficient to meet this requirement. New module parameter suspend_mode can take any one of the below suspend state, 1. cut power 2. deep sleep 3. wow Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/core.c | 12 +++-- drivers/net/wireless/ath/ath6kl/core.h | 4 +- drivers/net/wireless/ath/ath6kl/sdio.c | 86 +++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/core.c b/drivers/net/wireless/ath/ath6kl/core.c index 2a5198185d5..722ca59b88c 100644 --- a/drivers/net/wireless/ath/ath6kl/core.c +++ b/drivers/net/wireless/ath/ath6kl/core.c @@ -25,13 +25,13 @@ #include "cfg80211.h" unsigned int debug_mask; -static bool suspend_cutpower; +static unsigned int suspend_mode; static unsigned int uart_debug; static unsigned int ath6kl_p2p; static unsigned int testmode; module_param(debug_mask, uint, 0644); -module_param(suspend_cutpower, bool, 0444); +module_param(suspend_mode, uint, 0644); module_param(uart_debug, uint, 0644); module_param(ath6kl_p2p, uint, 0644); module_param(testmode, uint, 0644); @@ -147,8 +147,12 @@ int ath6kl_core_init(struct ath6kl *ar) ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER | ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST; - if (suspend_cutpower) - ar->conf_flags |= ATH6KL_CONF_SUSPEND_CUTPOWER; + if (suspend_mode && + suspend_mode >= WLAN_POWER_STATE_CUT_PWR && + suspend_mode <= WLAN_POWER_STATE_WOW) + ar->suspend_mode = suspend_mode; + else + ar->suspend_mode = 0; if (uart_debug) ar->conf_flags |= ATH6KL_CONF_UART_DEBUG; diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index 426f269e8ab..ce572c04b92 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -196,8 +196,7 @@ struct ath6kl_fw_ie { #define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1) #define ATH6KL_CONF_ENABLE_11N BIT(2) #define ATH6KL_CONF_ENABLE_TX_BURST BIT(3) -#define ATH6KL_CONF_SUSPEND_CUTPOWER BIT(4) -#define ATH6KL_CONF_UART_DEBUG BIT(5) +#define ATH6KL_CONF_UART_DEBUG BIT(4) enum wlan_low_pwr_state { WLAN_POWER_STATE_ON, @@ -619,6 +618,7 @@ struct ath6kl { } hw; u16 conf_flags; + u16 suspend_mode; wait_queue_head_t event_wq; struct ath6kl_mbox_info mbox_info; diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index d9f55914b89..07dcf00ca1a 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -779,7 +779,7 @@ out: return ret; } -static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_set_sdio_pm_caps(struct ath6kl *ar) { struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); struct sdio_func *func = ar_sdio->func; @@ -790,60 +790,82 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sdio suspend pm_caps 0x%x\n", flags); - if (!(flags & MMC_PM_KEEP_POWER) || - (ar->conf_flags & ATH6KL_CONF_SUSPEND_CUTPOWER)) { - /* as host doesn't support keep power we need to cut power */ - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, - NULL); - } + if (!(flags & MMC_PM_WAKE_SDIO_IRQ) || + !(flags & MMC_PM_KEEP_POWER)) + return -EINVAL; ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) { - printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n", - ret); + ath6kl_err("set sdio keep pwr flag failed: %d\n", ret); return ret; } - if (!(flags & MMC_PM_WAKE_SDIO_IRQ)) - goto deepsleep; - /* sdio irq wakes up host */ + ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + if (ret) + ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + + return ret; +} + +static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar); + struct sdio_func *func = ar_sdio->func; + mmc_pm_flag_t flags; + int ret; if (ar->state == ATH6KL_STATE_SCHED_SCAN) { + ath6kl_dbg(ATH6KL_DBG_SUSPEND, "sched scan is in progress\n"); + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_SCHED_SCAN, NULL); - if (ret) { - ath6kl_warn("Schedule scan suspend failed: %d", ret); - return ret; - } - - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); if (ret) - ath6kl_warn("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + return 0; } - if (wow) { - /* - * The host sdio controller is capable of keep power and - * sdio irq wake up at this point. It's fine to continue - * wow suspend operation. - */ + if (ar->suspend_mode == WLAN_POWER_STATE_WOW || + (!ar->suspend_mode && wow)) { + + ret = ath6kl_set_sdio_pm_caps(ar); + if (ret) + goto cut_pwr; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_WOW, wow); if (ret) - return ret; + goto cut_pwr; + + return 0; + } + + if (ar->suspend_mode == WLAN_POWER_STATE_DEEP_SLEEP || + !ar->suspend_mode) { - ret = sdio_set_host_pm_flags(func, MMC_PM_WAKE_SDIO_IRQ); + flags = sdio_get_host_pm_caps(func); + if (!(flags & MMC_PM_KEEP_POWER)) + goto cut_pwr; + + ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); if (ret) - ath6kl_err("set sdio wake irq flag failed: %d\n", ret); + goto cut_pwr; - return ret; + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, + NULL); + if (ret) + goto cut_pwr; + + return 0; } -deepsleep: - return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); +cut_pwr: + return ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_CUTPOWER, NULL); } static int ath6kl_sdio_resume(struct ath6kl *ar) -- cgit v1.2.3-70-g09d2 From d91e8eee046e0d4ae7a8a585616b5ce800f54568 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:10 +0530 Subject: ath6kl: Configure WOW patterns while going to wow_suspend First preference is given to the user configured WOW patterns. If the user doesn't configure any patterns (for ex, via iw command), the default patterns will be configured based on the current mode (vif->nw_type) while going to WOW suspend. Summary of changes: * ath6kl_wow_ap() is added to configure the below default patterns when the system enters into WOW suspend in AP mode. + Unicast IP, EAPOL-like and ARP packet pattern + ARP packet pattern + mDNS/SSDP/LLMNR pattern + DHCP broadcast pattern * ath6kl_wow_sta() is added to configure the below default patterns when the system enters into WOW suspend in STA mode. + Unicast packet pattern + mDNS/SSDP/LLMNR pattern * Move the user provided WOW patterns configuration code from ath6kl_wow_suspend() to a separate function called ath6kl_wow_usr(). * Two argument variable's ('filter' and 'mask) data type in ath6kl_wmi_add_wow_pattern_cmd() are changed from 'u8 *' to 'const u8 *'. This is needed to make all pattern and mask arrays to be 'static const u8' in the caller function. * New conditional check is added to make sure user configured pattern count is within the limit (WOW_MAX_FILTERS_PER_LIST). Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 231 +++++++++++++++++++++++------ drivers/net/wireless/ath/ath6kl/wmi.c | 3 +- drivers/net/wireless/ath/ath6kl/wmi.h | 3 +- 3 files changed, 193 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index fed7b8077f5..e676cfccedf 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1723,32 +1723,14 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) return 0; } -static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif, + struct cfg80211_wowlan *wow, u32 *filter) { - struct in_device *in_dev; - struct in_ifaddr *ifa; - struct ath6kl_vif *vif; - int ret, pos, left; - u32 filter = 0; + int ret, pos; + u8 mask[WOW_MASK_SIZE]; u16 i; - u8 mask[WOW_MASK_SIZE], index = 0; - __be32 ips[MAX_IP_ADDRS]; - - vif = ath6kl_vif_first(ar); - if (!vif) - return -EIO; - - if (!ath6kl_cfg80211_ready(vif)) - return -EIO; - - if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; - /* Clear existing WOW patterns */ - for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) - ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, - WOW_LIST_ID, i); - /* Configure new WOW patterns */ + /* Configure the patterns that we received from the user. */ for (i = 0; i < wow->n_patterns; i++) { /* @@ -1771,14 +1753,194 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) * matched from the first byte of received pkt in the firmware. */ ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, - vif->fw_vif_idx, WOW_LIST_ID, - wow->patterns[i].pattern_len, - 0 /* pattern offset */, - wow->patterns[i].pattern, mask); + vif->fw_vif_idx, WOW_LIST_ID, + wow->patterns[i].pattern_len, + 0 /* pattern offset */, + wow->patterns[i].pattern, mask); if (ret) return ret; } + if (wow->disconnect) + *filter |= WOW_FILTER_OPTION_NWK_DISASSOC; + + if (wow->magic_pkt) + *filter |= WOW_FILTER_OPTION_MAGIC_PACKET; + + if (wow->gtk_rekey_failure) + *filter |= WOW_FILTER_OPTION_GTK_ERROR; + + if (wow->eap_identity_req) + *filter |= WOW_FILTER_OPTION_EAP_REQ; + + if (wow->four_way_handshake) + *filter |= WOW_FILTER_OPTION_8021X_4WAYHS; + + return 0; +} + +static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08 }; + static const u8 unicst_mask[] = { 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x7f }; + u8 unicst_offset = 0; + static const u8 arp_pattern[] = { 0x08, 0x06 }; + static const u8 arp_mask[] = { 0xff, 0xff }; + u8 arp_offset = 20; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ }; + static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ }; + u8 dhcp_offset = 0; + int ret; + + /* Setup unicast IP, EAPOL-like and ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(unicst_pattern), unicst_offset, + unicst_pattern, unicst_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast IP pattern\n"); + return ret; + } + + /* Setup all ARP pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(arp_pattern), arp_offset, + arp_pattern, arp_mask); + if (ret) { + ath6kl_err("failed to add WOW ARP pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n"); + return ret; + } + + /* Setup all DHCP broadcast pkt pattern */ + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(dhcp_pattern), dhcp_offset, + dhcp_pattern, dhcp_mask); + if (ret) { + ath6kl_err("failed to add WOW DHCP broadcast pattern\n"); + return ret; + } + + return 0; +} + +static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif) +{ + struct net_device *ndev = vif->ndev; + static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 }; + static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 }; + u8 discvr_offset = 38; + u8 mac_mask[ETH_ALEN]; + int ret; + + /* Setup unicast pkt pattern */ + memset(mac_mask, 0xff, ETH_ALEN); + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + ETH_ALEN, 0, ndev->dev_addr, + mac_mask); + if (ret) { + ath6kl_err("failed to add WOW unicast pattern\n"); + return ret; + } + + /* + * Setup multicast pattern for mDNS 224.0.0.251, + * SSDP 239.255.255.250 and LLMNR 224.0.0.252 + */ + if ((ndev->flags & IFF_ALLMULTI) || + (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) { + ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi, + vif->fw_vif_idx, WOW_LIST_ID, + sizeof(discvr_pattern), discvr_offset, + discvr_pattern, discvr_mask); + if (ret) { + ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR " + "pattern\n"); + return ret; + } + } + + return 0; +} + +static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) +{ + struct in_device *in_dev; + struct in_ifaddr *ifa; + struct ath6kl_vif *vif; + int ret, left; + u32 filter = 0; + u16 i; + u8 index = 0; + __be32 ips[MAX_IP_ADDRS]; + + vif = ath6kl_vif_first(ar); + if (!vif) + return -EIO; + + if (!ath6kl_cfg80211_ready(vif)) + return -EIO; + + if (!test_bit(CONNECTED, &vif->flags)) + return -EINVAL; + + if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) + return -EINVAL; + + /* Clear existing WOW patterns */ + for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++) + ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx, + WOW_LIST_ID, i); + + /* + * Skip the default WOW pattern configuration + * if the driver receives any WOW patterns from + * the user. + */ + if (wow) + ret = ath6kl_wow_usr(ar, vif, wow, &filter); + else if (vif->nw_type == AP_NETWORK) + ret = ath6kl_wow_ap(ar, vif); + else + ret = ath6kl_wow_sta(ar, vif); + + if (ret) + return ret; + /* Setup own IP addr for ARP agent. */ in_dev = __in_dev_get_rtnl(vif->ndev); if (!in_dev) @@ -1806,21 +1968,6 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) } skip_arp: - if (wow->disconnect) - filter |= WOW_FILTER_OPTION_NWK_DISASSOC; - - if (wow->magic_pkt) - filter |= WOW_FILTER_OPTION_MAGIC_PACKET; - - if (wow->gtk_rekey_failure) - filter |= WOW_FILTER_OPTION_GTK_ERROR; - - if (wow->eap_identity_req) - filter |= WOW_FILTER_OPTION_EAP_REQ; - - if (wow->four_way_handshake) - filter |= WOW_FILTER_OPTION_8021X_4WAYHS; - ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_WOW_MODE_ENABLE, filter, diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 5d678bf372d..9c8e4dfbfa0 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2620,7 +2620,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask) + u8 filter_offset, const u8 *filter, + const u8 *mask) { struct sk_buff *skb; struct wmi_add_wow_pattern_cmd *cmd; diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 48e9d2641d6..85698ef2dd8 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -2461,7 +2461,8 @@ int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, u32 filter, u16 host_req_delay); int ath6kl_wmi_add_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u8 list_id, u8 filter_size, - u8 filter_offset, u8 *filter, u8 *mask); + u8 filter_offset, const u8 *filter, + const u8 *mask); int ath6kl_wmi_del_wow_pattern_cmd(struct wmi *wmi, u8 if_idx, u16 list_id, u16 filter_id); int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi); -- cgit v1.2.3-70-g09d2 From 081c7a84e969453716e2a7bd315417067c3643ad Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:11 +0530 Subject: ath6kl: Wait for host sleep mode cmd processed event during WOW suspend For every WMI_SET_HOST_SLEEP_MODE_CMDID command (send from the host), the firmware sends WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID as an acknowledgement to the host. In order to being sync with the firmware, the host has to wait for WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENT event before going to the suspend state. This patch ensures ath6kl_wow_suspend() waits until it gets this event after sending set host sleep mode command. This patch adds, * New command WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID in WMI event table. * New WMI function ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx() to process the event. * New flag HOST_SLEEP_MODE_CMD_PROCESSED in VIF flags to record the arrival of the event. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 15 +++++++++++++++ drivers/net/wireless/ath/ath6kl/core.h | 1 + drivers/net/wireless/ath/ath6kl/wmi.c | 17 +++++++++++++++++ drivers/net/wireless/ath/ath6kl/wmi.h | 2 ++ 4 files changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index e676cfccedf..1902e2fa1a6 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1975,11 +1975,26 @@ skip_arp: if (ret) return ret; + clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx, ATH6KL_HOST_MODE_ASLEEP); if (ret) return ret; + left = wait_event_interruptible_timeout(ar->event_wq, + test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags), + WMI_TIMEOUT); + if (left == 0) { + ath6kl_warn("timeout, didn't get host sleep cmd " + "processed event\n"); + ret = -ETIMEDOUT; + } else if (left < 0) { + ath6kl_warn("error while waiting for host sleep cmd " + "processed event %d\n", left); + ret = left; + } + if (ar->tx_pending[ar->ctrl_ep]) { left = wait_event_interruptible_timeout(ar->event_wq, ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT); diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h index ce572c04b92..c4d66e066dc 100644 --- a/drivers/net/wireless/ath/ath6kl/core.h +++ b/drivers/net/wireless/ath/ath6kl/core.h @@ -451,6 +451,7 @@ enum ath6kl_vif_state { DTIM_PERIOD_AVAIL, WLAN_ENABLED, STATS_UPDATE_PEND, + HOST_SLEEP_MODE_CMD_PROCESSED, }; struct ath6kl_vif { diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c index 9c8e4dfbfa0..18fa9aa8af9 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.c +++ b/drivers/net/wireless/ath/ath6kl/wmi.c @@ -2590,6 +2590,18 @@ int ath6kl_wmi_set_host_sleep_mode_cmd(struct wmi *wmi, u8 if_idx, return ret; } +/* This command has zero length payload */ +static int ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(struct wmi *wmi, + struct ath6kl_vif *vif) +{ + struct ath6kl *ar = wmi->parent_dev; + + set_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags); + wake_up(&ar->event_wq); + + return 0; +} + int ath6kl_wmi_set_wow_mode_cmd(struct wmi *wmi, u8 if_idx, enum ath6kl_wow_mode wow_mode, u32 filter, u16 host_req_delay) @@ -3556,6 +3568,11 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb) ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n"); ret = ath6kl_wmi_tx_complete_event_rx(datap, len); break; + case WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID: + ath6kl_dbg(ATH6KL_DBG_WMI, + "WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID"); + ret = ath6kl_wmi_host_sleep_mode_cmd_prcd_evt_rx(wmi, vif); + break; case WMI_REMAIN_ON_CHNL_EVENTID: ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REMAIN_ON_CHNL_EVENTID\n"); ret = ath6kl_wmi_remain_on_chnl_event_rx(wmi, datap, len, vif); diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h index 85698ef2dd8..e7919869725 100644 --- a/drivers/net/wireless/ath/ath6kl/wmi.h +++ b/drivers/net/wireless/ath/ath6kl/wmi.h @@ -1357,6 +1357,8 @@ enum wmi_event_id { WMI_P2P_START_SDPD_EVENTID, WMI_P2P_SDPD_RX_EVENTID, + WMI_SET_HOST_SLEEP_MODE_CMD_PROCESSED_EVENTID = 0x1047, + WMI_THIN_RESERVED_START_EVENTID = 0x8000, /* Events in this range are reserved for thinmode */ WMI_THIN_RESERVED_END_EVENTID = 0x8fff, -- cgit v1.2.3-70-g09d2 From 3c411a434414f4320ce926bee3733e34ba0ea407 Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 30 Jan 2012 17:13:12 +0530 Subject: ath6kl: Return a proper error code when not in connected state Error code ENOTCONN is more suitable than EINVAL to report when the driver is not in connected state in ath6kl_wow_suspend(). I found this during code review. Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 1902e2fa1a6..5934e40ee55 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1916,7 +1916,7 @@ static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) return -EIO; if (!test_bit(CONNECTED, &vif->flags)) - return -EINVAL; + return -ENOTCONN; if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST)) return -EINVAL; -- cgit v1.2.3-70-g09d2 From c9c4b6f6c28354f1df9bd288dc33ba7ae0e66aaa Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:15 +0100 Subject: drm/i915: fix swizzle detection for gen3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It looks like the desktop variants of i915 and i945 also have the DCC register to control dram channel interleave and cpu side bit6 swizzling. Unfortunately internal Cspec/ConfigDB documentation for these ancient chips have already been dropped and there seem to be no archives. Also somebody thought the swizzling behaviour is surely a worthy secret to keep and redacted any mention of these fields from the published Intel datasheets. I suspect the hw engineers were really proud of the page coloring they've achieved in their first dual channel dram controller with bit17 - after all Bspec explains in great length the optimal layout of page frame numbers modulo 4 for the color and depth buffers, too. Later on when they've started to work on VT-d they shamefully discoverd their stupidity and tried to cover the tracks ... Tested-by: Daniel Vetter (i915g) Tested-by: Pavel Ondračka (i945g) Tested-by: Chris Wilson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=42625 Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_tiling.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 31d334d9d9d..861223bf394 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -107,10 +107,10 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) */ swizzle_x = I915_BIT_6_SWIZZLE_NONE; swizzle_y = I915_BIT_6_SWIZZLE_NONE; - } else if (IS_MOBILE(dev)) { + } else if (IS_MOBILE(dev) || (IS_GEN3(dev) && !IS_G33(dev))) { uint32_t dcc; - /* On mobile 9xx chipsets, channel interleave by the CPU is + /* On 9xx chipsets, channel interleave by the CPU is * determined by DCC. For single-channel, neither the CPU * nor the GPU do swizzling. For dual channel interleaved, * the GPU's interleave is bit 9 and 10 for X tiled, and bit -- cgit v1.2.3-70-g09d2 From ea16a3cdb9218a2389fafc804356c1914c157654 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:16 +0100 Subject: drm/i915: add debugfs file for swizzling information This will also come handy for the gen6+ swizzling support, where the driver is supposed to control swizzling depending upon dram configuration. v2: CxDRB3 are 16 bit regs! Noticed by Chris Wilson. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index d4104904e58..681cbe4e6e2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1379,6 +1379,55 @@ static int i915_gen6_forcewake_count_info(struct seq_file *m, void *data) return 0; } +static const char *swizzle_string(unsigned swizzle) +{ + switch(swizzle) { + case I915_BIT_6_SWIZZLE_NONE: + return "none"; + case I915_BIT_6_SWIZZLE_9: + return "bit9"; + case I915_BIT_6_SWIZZLE_9_10: + return "bit9/bit10"; + case I915_BIT_6_SWIZZLE_9_11: + return "bit9/bit11"; + case I915_BIT_6_SWIZZLE_9_10_11: + return "bit9/bit10/bit11"; + case I915_BIT_6_SWIZZLE_9_17: + return "bit9/bit17"; + case I915_BIT_6_SWIZZLE_9_10_17: + return "bit9/bit10/bit17"; + case I915_BIT_6_SWIZZLE_UNKNOWN: + return "unkown"; + } + + return "bug"; +} + +static int i915_swizzle_info(struct seq_file *m, void *data) +{ + struct drm_info_node *node = (struct drm_info_node *) m->private; + struct drm_device *dev = node->minor->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + mutex_lock(&dev->struct_mutex); + seq_printf(m, "bit6 swizzle for X-tiling = %s\n", + swizzle_string(dev_priv->mm.bit_6_swizzle_x)); + seq_printf(m, "bit6 swizzle for Y-tiling = %s\n", + swizzle_string(dev_priv->mm.bit_6_swizzle_y)); + + if (IS_GEN3(dev) || IS_GEN4(dev)) { + seq_printf(m, "DDC = 0x%08x\n", + I915_READ(DCC)); + seq_printf(m, "C0DRB3 = 0x%04x\n", + I915_READ16(C0DRB3)); + seq_printf(m, "C1DRB3 = 0x%04x\n", + I915_READ16(C1DRB3)); + } + mutex_unlock(&dev->struct_mutex); + + return 0; +} + static int i915_debugfs_common_open(struct inode *inode, struct file *filp) @@ -1719,6 +1768,7 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_framebuffer", i915_gem_framebuffer_info, 0}, {"i915_context_status", i915_context_status, 0}, {"i915_gen6_forcewake_count", i915_gen6_forcewake_count_info, 0}, + {"i915_swizzle_info", i915_swizzle_info, 0}, }; #define I915_DEBUGFS_ENTRIES ARRAY_SIZE(i915_debugfs_list) -- cgit v1.2.3-70-g09d2 From d273bb20c00340748e3ca9730f87524ec5abbd64 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Fri, 27 Jan 2012 13:59:25 -0600 Subject: rtlwifi: Move pr_fmt macros to a single location Although the rtlwifi family of devices contains 11 copies of the pr_fmt macro, the macro is not defined for all routines that need it. By moving the macro to wifi.h, a single copy is available for all routines. Signed-off-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 7 +++---- drivers/net/wireless/rtlwifi/cam.c | 2 -- drivers/net/wireless/rtlwifi/core.h | 2 -- drivers/net/wireless/rtlwifi/debug.c | 2 ++ drivers/net/wireless/rtlwifi/pci.c | 4 ++-- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 5 +---- drivers/net/wireless/rtlwifi/rtl8192c/main.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 5 ++--- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192cu/mac.c | 6 ++---- drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 1 - drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 7 ++----- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/phy.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 2 -- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 7 ++----- drivers/net/wireless/rtlwifi/usb.c | 7 ++----- drivers/net/wireless/rtlwifi/usb.h | 1 - drivers/net/wireless/rtlwifi/wifi.h | 2 ++ 19 files changed, 21 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index ff3e393bc10..7a95a544a9b 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -27,10 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include #include "wifi.h" #include "rc.h" #include "base.h" @@ -39,6 +35,9 @@ #include "ps.h" #include "regd.h" +#include +#include + /* *NOTICE!!!: This file will be very big, we hsould *keep it clear under follwing roles: diff --git a/drivers/net/wireless/rtlwifi/cam.c b/drivers/net/wireless/rtlwifi/cam.c index 8fd820d85ee..5c7d57947d2 100644 --- a/drivers/net/wireless/rtlwifi/cam.c +++ b/drivers/net/wireless/rtlwifi/cam.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include "wifi.h" #include "cam.h" diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index a45c3892e36..57569e0e3d4 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -30,8 +30,6 @@ #ifndef __RTL_CORE_H__ #define __RTL_CORE_H__ -#include - #define RTL_SUPPORTED_FILTERS \ (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | FIF_CONTROL | \ diff --git a/drivers/net/wireless/rtlwifi/debug.c b/drivers/net/wireless/rtlwifi/debug.c index 67dcbcdfaa7..bdda9b2fffe 100644 --- a/drivers/net/wireless/rtlwifi/debug.c +++ b/drivers/net/wireless/rtlwifi/debug.c @@ -28,6 +28,8 @@ #include "wifi.h" +#include + void rtl_dbgp_flag_init(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 4326fd1e319..e4d1dcfe829 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -27,13 +27,13 @@ * *****************************************************************************/ -#include -#include "core.h" #include "wifi.h" +#include "core.h" #include "pci.h" #include "base.h" #include "ps.h" #include "efuse.h" +#include static const u16 pcibridge_vendors[PCI_BRIDGE_VENDOR_MAX] = { PCI_VENDOR_ID_INTEL, diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 75be221fde4..82bbc8384ac 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -27,16 +27,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include #include "../wifi.h" #include "../pci.h" #include "../base.h" #include "../rtl8192ce/reg.h" #include "../rtl8192ce/def.h" #include "fw_common.h" +#include static void _rtl92c_enable_fw_download(struct ieee80211_hw *hw, bool enable) { diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/main.c b/drivers/net/wireless/rtlwifi/rtl8192c/main.c index 8ae65b57612..918b1d129e7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/main.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/main.c @@ -27,8 +27,8 @@ * *****************************************************************************/ -#include #include "../wifi.h" +#include MODULE_AUTHOR("lizhaoming "); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 7e59b689bff..460dc925b4e 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -27,9 +27,6 @@ * *****************************************************************************/ -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -43,6 +40,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92c_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index edb52987f5e..7f171682d3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c index d028f6f2199..025bdc2eba4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c @@ -27,10 +27,6 @@ * ****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include - #include "../wifi.h" #include "../pci.h" #include "../usb.h" @@ -44,6 +40,8 @@ #include "mac.h" #include "trx.h" +#include + /* macro to shorten lines */ #define LINK_Q ui_link_quality diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index aec8cae733a..c04c3be5bd4 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -41,7 +41,6 @@ #include "trx.h" #include "led.h" #include "hw.h" -#include #include MODULE_AUTHOR("Georgia "); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index b8d7fe39e5a..bf625f9e632 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -27,11 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -44,6 +39,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92d_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index 625c9eb0a11..cbaf1f345c6 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../efuse.h" #include "../base.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c index adfac569b67..05b4e2790e9 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/phy.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "../pci.h" #include "../ps.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c index 46be4cc8ba9..ad51906124d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c @@ -27,8 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include "../wifi.h" #include "reg.h" #include "def.h" diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 3bc0128deea..0c47310b39b 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -27,11 +27,6 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include - #include "../wifi.h" #include "../core.h" #include "../pci.h" @@ -45,6 +40,8 @@ #include "trx.h" #include "led.h" +#include + static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) { struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 78194e30fcd..e7a7ea96f42 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -25,16 +25,13 @@ * *****************************************************************************/ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include "core.h" #include "wifi.h" +#include "core.h" #include "usb.h" #include "base.h" #include "ps.h" #include "rtl8192c/fw_common.h" +#include #define REALTEK_USB_VENQT_READ 0xC0 #define REALTEK_USB_VENQT_WRITE 0x40 diff --git a/drivers/net/wireless/rtlwifi/usb.h b/drivers/net/wireless/rtlwifi/usb.h index cdad7c2507e..43846b32915 100644 --- a/drivers/net/wireless/rtlwifi/usb.h +++ b/drivers/net/wireless/rtlwifi/usb.h @@ -28,7 +28,6 @@ #ifndef __RTL_USB_H__ #define __RTL_USB_H__ -#include #include #define RTL_RX_DESC_SIZE 24 diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index b2d98548500..1e5fffb2db0 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -30,6 +30,8 @@ #ifndef __RTL_WIFI_H__ #define __RTL_WIFI_H__ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include -- cgit v1.2.3-70-g09d2 From 0a79bb57d46c7ee93de0e262cebb46f6f6f6a1a7 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 28 Jan 2012 08:30:49 -0800 Subject: iwlwifi: fix typo Fix few places of typo Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-testmode.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h index 185b69ef753..f97d06169b4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.h +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.h @@ -111,17 +111,17 @@ * * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: * @IWL_TM_CMD_APP2DEV_INDIRECT_REG_WRITE32: - * commands from user applicaiton to indirectly access peripheral register + * commands from user application to indirectly access peripheral register * * @IWL_TM_CMD_APP2DEV_READ_SRAM: * @IWL_TM_CMD_APP2DEV_DUMP_SRAM: - * commands from user applicaiton to read data in sram + * commands from user application to read data in sram * - * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Weak On Wireless LAN uCode image + * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device * @IWL_TM_CMD_APP2DEV_GET_FW_INFO: - * retrieve informration of existing loaded uCode image + * retrieve information of existing loaded uCode image * */ enum iwl_tm_cmd_t { -- cgit v1.2.3-70-g09d2 From 2b2db58d65edcab4bcc9d6fdd2770bb0275cdac4 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 28 Jan 2012 08:30:50 -0800 Subject: iwlwifi: fix uCode event tracing Fix multiple bugs in event tracing: 1) If you enable uCode tracing with the device down, it will still attempt to access the device and continuously log "MAC is in deep sleep!" errors. Fix this by only starting logging when the device is actually alive. 2) Now you can set the flag when the device is down, but logging doesn't happen when you bring it up. To fix that, start logging when the device comes alive. This means we don't log before -- we could do that but I don't need it right now. 3) For some reason we read the error instead of the event log -- use the right pointer. 4) Optimise SRAM reading of event log header. 5) Fix reading write pointer == capacity, which can happen due to racy SRAM access 6) Most importantly: fix an error where we would try to read WAY too many events (like 2^32-300) when we read the wrap counter before it is updated by the uCode -- this does happen in practice and will cause the driver to hang the machine. 7) Finally, change the timer to 10ms instead of 100ms as 100ms is too slow to capture all data with a normal event log and with 100ms the log will wrap multiple times before we have a chance to read it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 99 +++++++++++++++++++++--------- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 ++- drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +- 3 files changed, 76 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 7321e7d3140..3e429a3e518 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -315,7 +315,7 @@ static void iwl_bg_statistics_periodic(unsigned long data) static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, u32 start_idx, u32 num_events, - u32 mode) + u32 capacity, u32 mode) { u32 i; u32 ptr; /* SRAM byte address of log data */ @@ -338,6 +338,15 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); rmb(); + /* + * Refuse to read more than would have fit into the log from + * the current start_idx. This used to happen due to the race + * described below, but now WARN because the code below should + * prevent it from happening here. + */ + if (WARN_ON(num_events > capacity - start_idx)) + num_events = capacity - start_idx; + /* * "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. @@ -346,12 +355,11 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { - trace_iwlwifi_dev_ucode_cont_event(priv, - 0, time, ev); + trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); } else { data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - trace_iwlwifi_dev_ucode_cont_event(priv, - time, data, ev); + trace_iwlwifi_dev_ucode_cont_event(priv, time, + data, ev); } } /* Allow device to power down */ @@ -362,53 +370,83 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, static void iwl_continuous_event_trace(struct iwl_priv *priv) { u32 capacity; /* event log capacity in # entries */ + struct { + u32 capacity; + u32 mode; + u32 wrap_counter; + u32 write_counter; + } __packed read; u32 base; /* SRAM byte address of event log header */ u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */ u32 num_wraps; /* # times uCode wrapped to top of log */ u32 next_entry; /* index of next entry to be written by uCode */ - base = priv->shrd->device_pointers.error_event_table; + base = priv->shrd->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - capacity = iwl_read_targ_mem(bus(priv), base); - num_wraps = iwl_read_targ_mem(bus(priv), - base + (2 * sizeof(u32))); - mode = iwl_read_targ_mem(bus(priv), base + (1 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(priv), - base + (3 * sizeof(u32))); + iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); + + capacity = read.capacity; + mode = read.mode; + num_wraps = read.wrap_counter; + next_entry = read.write_counter; } else return; + /* + * Unfortunately, the uCode doesn't use temporary variables. + * Therefore, it can happen that we read next_entry == capacity, + * which really means next_entry == 0. + */ + if (unlikely(next_entry == capacity)) + next_entry = 0; + /* + * Additionally, the uCode increases the write pointer before + * the wraps counter, so if the write pointer is smaller than + * the old write pointer (wrap occurred) but we read that no + * wrap occurred, we actually read between the next_entry and + * num_wraps update (this does happen in practice!!) -- take + * that into account by increasing num_wraps. + */ + if (unlikely(next_entry < priv->event_log.next_entry && + num_wraps == priv->event_log.num_wraps)) + num_wraps++; + if (num_wraps == priv->event_log.num_wraps) { - iwl_print_cont_event_trace(priv, - base, priv->event_log.next_entry, - next_entry - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + next_entry - priv->event_log.next_entry, + capacity, mode); + priv->event_log.non_wraps_count++; } else { - if ((num_wraps - priv->event_log.num_wraps) > 1) + if (num_wraps - priv->event_log.num_wraps > 1) priv->event_log.wraps_more_count++; else priv->event_log.wraps_once_count++; + trace_iwlwifi_dev_ucode_wrap_event(priv, num_wraps - priv->event_log.num_wraps, next_entry, priv->event_log.next_entry); + if (next_entry < priv->event_log.next_entry) { - iwl_print_cont_event_trace(priv, base, - priv->event_log.next_entry, - capacity - priv->event_log.next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, priv->event_log.next_entry, + capacity - priv->event_log.next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } else { - iwl_print_cont_event_trace(priv, base, - next_entry, capacity - next_entry, - mode); + iwl_print_cont_event_trace( + priv, base, next_entry, + capacity - next_entry, + capacity, mode); - iwl_print_cont_event_trace(priv, base, 0, - next_entry, mode); + iwl_print_cont_event_trace( + priv, base, 0, next_entry, capacity, mode); } } + priv->event_log.num_wraps = num_wraps; priv->event_log.next_entry = next_entry; } @@ -1219,6 +1257,11 @@ int iwl_alive_start(struct iwl_priv *priv) if (iwl_is_rfkill(priv->shrd)) return -ERFKILL; + if (priv->event_log.ucode_trace) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } + /* download priority table before any calibration request */ if (cfg(priv)->bt_params && cfg(priv)->bt_params->advanced_bt_coexist) { diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index f837f32bb71..978a1d4c6a0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -2131,9 +2131,10 @@ static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, if (trace) { priv->event_log.ucode_trace = true; - /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ - mod_timer(&priv->ucode_trace, - jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); + if (iwl_is_alive(priv->shrd)) { + /* start collecting data now */ + mod_timer(&priv->ucode_trace, jiffies); + } } else { priv->event_log.ucode_trace = false; del_timer_sync(&priv->ucode_trace); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 4579d61da25..af846002150 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -661,7 +661,7 @@ struct traffic_stats { * schedule the timer to wake up every UCODE_TRACE_PERIOD milliseconds * to perform continuous uCode event logging operation if enabled */ -#define UCODE_TRACE_PERIOD (100) +#define UCODE_TRACE_PERIOD (10) /* * iwl_event_log: current uCode event log position -- cgit v1.2.3-70-g09d2 From dcc3ec04c14d6d840fdcc5be0ddd752a7daf7ec4 Mon Sep 17 00:00:00 2001 From: Wey-Yi Guy Date: Sat, 28 Jan 2012 08:30:51 -0800 Subject: iwlwifi: add option to disalbe LED Led has no use for some platform. Add additional module parameter option to disable LED Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-led.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-shared.h | 2 ++ 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3e429a3e518..90315c69cdf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -2097,7 +2097,7 @@ MODULE_PARM_DESC(bt_coex_active, "enable wifi/bt co-exist (default: enable)"); module_param_named(led_mode, iwlagn_mod_params.led_mode, int, S_IRUGO); MODULE_PARM_DESC(led_mode, "0=system default, " - "1=On(RF On)/Off(RF Off), 2=blinking (default: 0)"); + "1=On(RF On)/Off(RF Off), 2=blinking, 3=Off (default: 0)"); module_param_named(power_save, iwlagn_mod_params.power_save, bool, S_IRUGO); diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index eca79087afb..8761438f153 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -177,6 +177,10 @@ void iwl_leds_init(struct iwl_priv *priv) int mode = iwlagn_mod_params.led_mode; int ret; + if (mode == IWL_LED_DISABLE) { + IWL_INFO(priv, "Led disabled\n"); + return; + } if (mode == IWL_LED_DEFAULT) mode = cfg(priv)->led_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index e406d49f418..04975b7b65b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -264,11 +264,13 @@ enum iwl_pa_type { * LED ON = RF ON * LED OFF = RF OFF * IWL_LED_BLINK: adjust led blink rate based on blink table + * IWL_LED_DISABLE: led disabled */ enum iwl_led_mode { IWL_LED_DEFAULT, IWL_LED_RF_STATE, IWL_LED_BLINK, + IWL_LED_DISABLE, }; /** -- cgit v1.2.3-70-g09d2 From 2ed81710ccc0ccebe177481b8d4ac584f9c2b569 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sat, 28 Jan 2012 08:30:52 -0800 Subject: iwlwifi: always restrict scan dwell in P2P Whenever the PAN (P2P) context is active, it has timers in the uCode that prevent sleep, so scanning can't be out of channel for more than the beacon interval programmed into the device. Before this patch, a full scan including any passive channels when P2P was active would stall forever because it wouldn't find time to execute the passive requests (for default beacon intervals of 100 TU.) Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy Signed-off-by: John W. Linville --- drivers/net/wireless/iwlwifi/iwl-scan.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 2aea20bf0f1..7f2e3a1c80e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -414,10 +414,25 @@ static u16 iwl_limit_dwell(struct iwl_priv *priv, u16 dwell_time) for_each_context(priv, ctx) { u16 value; - if (!iwl_is_associated_ctx(ctx)) - continue; - if (ctx->staging.dev_type == RXON_DEV_TYPE_P2P) + switch (ctx->staging.dev_type) { + case RXON_DEV_TYPE_P2P: + /* no timing constraints */ continue; + case RXON_DEV_TYPE_ESS: + default: + /* timing constraints if associated */ + if (!iwl_is_associated_ctx(ctx)) + continue; + break; + case RXON_DEV_TYPE_CP: + case RXON_DEV_TYPE_2STA: + /* + * These seem to always have timers for TBTT + * active in uCode even when not associated yet. + */ + break; + } + value = ctx->beacon_int; if (!value) value = IWL_PASSIVE_DWELL_BASE; -- cgit v1.2.3-70-g09d2 From 0ed7b93e307fd02188a33b80897069d3acc76485 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 30 Jan 2012 14:17:18 +0530 Subject: ath9k_htc: Load firmware asynchronously This patch modifies ath9k_htc to load the needed firmware in an asynchronous manner, fixing timeouts that were introduced with the new udev changes. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hif_usb.c | 154 ++++++++++++++++++++----------- drivers/net/wireless/ath/ath9k/hif_usb.h | 3 +- 2 files changed, 101 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index 77c8ded8de5..f317515d8bf 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -968,8 +968,7 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) ath9k_hif_usb_dealloc_rx_urbs(hif_dev); } -static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, - u32 drv_info) +static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; const void *data = hif_dev->firmware->data; @@ -1000,7 +999,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, } kfree(buf); - if (IS_AR7010_DEVICE(drv_info)) + if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info)) firm_offset = AR7010_FIRMWARE_TEXT; else firm_offset = AR9271_FIRMWARE_TEXT; @@ -1021,28 +1020,18 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev, return 0; } -static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) +static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev) { - int ret, idx; struct usb_host_interface *alt = &hif_dev->interface->altsetting[0]; struct usb_endpoint_descriptor *endp; + int ret, idx; - /* Request firmware */ - ret = request_firmware(&hif_dev->firmware, hif_dev->fw_name, - &hif_dev->udev->dev); - if (ret) { - dev_err(&hif_dev->udev->dev, - "ath9k_htc: Firmware - %s not found\n", hif_dev->fw_name); - goto err_fw_req; - } - - /* Download firmware */ - ret = ath9k_hif_usb_download_fw(hif_dev, drv_info); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Firmware - %s download failed\n", hif_dev->fw_name); - goto err_fw_download; + return ret; } /* On downloading the firmware to the target, the USB descriptor of EP4 @@ -1064,23 +1053,84 @@ static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, u32 drv_info) if (ret) { dev_err(&hif_dev->udev->dev, "ath9k_htc: Unable to allocate URBs\n"); - goto err_fw_download; + return ret; } return 0; - -err_fw_download: - release_firmware(hif_dev->firmware); -err_fw_req: - hif_dev->firmware = NULL; - return ret; } static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) { ath9k_hif_usb_dealloc_urbs(hif_dev); - if (hif_dev->firmware) - release_firmware(hif_dev->firmware); +} + +/* + * If initialization fails or the FW cannot be retrieved, + * detach the device. + */ +static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) +{ + struct device *parent = hif_dev->udev->dev.parent; + + complete(&hif_dev->fw_done); + + if (parent) + device_lock(parent); + + device_release_driver(&hif_dev->udev->dev); + + if (parent) + device_unlock(parent); +} + +static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) +{ + struct hif_device_usb *hif_dev = context; + int ret; + + if (!fw) { + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Failed to get firmware %s\n", + hif_dev->fw_name); + goto err_fw; + } + + hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, + &hif_dev->udev->dev); + if (hif_dev->htc_handle == NULL) { + goto err_fw; + } + + hif_dev->firmware = fw; + + /* Proceed with initialization */ + + ret = ath9k_hif_usb_dev_init(hif_dev); + if (ret) + goto err_dev_init; + + ret = ath9k_htc_hw_init(hif_dev->htc_handle, + &hif_dev->interface->dev, + hif_dev->usb_device_id->idProduct, + hif_dev->udev->product, + hif_dev->usb_device_id->driver_info); + if (ret) { + ret = -EINVAL; + goto err_htc_hw_init; + } + + complete(&hif_dev->fw_done); + + return; + +err_htc_hw_init: + ath9k_hif_usb_dev_deinit(hif_dev); +err_dev_init: + ath9k_htc_hw_free(hif_dev->htc_handle); + release_firmware(fw); + hif_dev->firmware = NULL; +err_fw: + ath9k_hif_usb_firmware_fail(hif_dev); } /* @@ -1155,20 +1205,16 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, } usb_get_dev(udev); + hif_dev->udev = udev; hif_dev->interface = interface; - hif_dev->device_id = id->idProduct; + hif_dev->usb_device_id = id; #ifdef CONFIG_PM udev->reset_resume = 1; #endif usb_set_intfdata(interface, hif_dev); - hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, - &hif_dev->udev->dev); - if (hif_dev->htc_handle == NULL) { - ret = -ENOMEM; - goto err_htc_hw_alloc; - } + init_completion(&hif_dev->fw_done); /* Find out which firmware to load */ @@ -1177,29 +1223,22 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface, else hif_dev->fw_name = FIRMWARE_AR9271; - ret = ath9k_hif_usb_dev_init(hif_dev, id->driver_info); - if (ret) { - ret = -EINVAL; - goto err_hif_init_usb; - } - - ret = ath9k_htc_hw_init(hif_dev->htc_handle, - &interface->dev, hif_dev->device_id, - hif_dev->udev->product, id->driver_info); + ret = request_firmware_nowait(THIS_MODULE, true, hif_dev->fw_name, + &hif_dev->udev->dev, GFP_KERNEL, + hif_dev, ath9k_hif_usb_firmware_cb); if (ret) { - ret = -EINVAL; - goto err_htc_hw_init; + dev_err(&hif_dev->udev->dev, + "ath9k_htc: Async request for firmware %s failed\n", + hif_dev->fw_name); + goto err_fw_req; } - dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); + dev_info(&hif_dev->udev->dev, "ath9k_htc: Firmware %s requested\n", + hif_dev->fw_name); return 0; -err_htc_hw_init: - ath9k_hif_usb_dev_deinit(hif_dev); -err_hif_init_usb: - ath9k_htc_hw_free(hif_dev->htc_handle); -err_htc_hw_alloc: +err_fw_req: usb_set_intfdata(interface, NULL); kfree(hif_dev); usb_put_dev(udev); @@ -1234,9 +1273,15 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) if (!hif_dev) return; - ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); - ath9k_htc_hw_free(hif_dev->htc_handle); - ath9k_hif_usb_dev_deinit(hif_dev); + wait_for_completion(&hif_dev->fw_done); + + if (hif_dev->firmware) { + ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); + ath9k_htc_hw_free(hif_dev->htc_handle); + ath9k_hif_usb_dev_deinit(hif_dev); + release_firmware(hif_dev->firmware); + } + usb_set_intfdata(interface, NULL); if (!unplugged && (hif_dev->flags & HIF_USB_START)) @@ -1276,8 +1321,7 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) return ret; if (hif_dev->firmware) { - ret = ath9k_hif_usb_download_fw(hif_dev, - htc_handle->drv_priv->ah->hw_version.usbdev); + ret = ath9k_hif_usb_download_fw(hif_dev); if (ret) goto fail_resume; } else { diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 794f63094e5..487ff658b4c 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -87,10 +87,11 @@ struct cmd_buf { #define HIF_USB_START BIT(0) struct hif_device_usb { - u16 device_id; struct usb_device *udev; struct usb_interface *interface; + const struct usb_device_id *usb_device_id; const struct firmware *firmware; + struct completion fw_done; struct htc_target *htc_handle; struct hif_usb_tx tx; struct usb_anchor regout_submitted; -- cgit v1.2.3-70-g09d2 From feced2012e665468258a5c89b7f2a90b4e5695a4 Mon Sep 17 00:00:00 2001 From: Sujith Manoharan Date: Mon, 30 Jan 2012 14:21:42 +0530 Subject: ath9k: Print the correct channel mode channelFlags doesn't contain the operating HT mode. Use IS_CHAN_HT40 to determine if the current channel is in HT40 mode. Signed-off-by: Sujith Manoharan Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/main.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4a00806e285..ec82e926bad 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -340,9 +340,7 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan, fastcc = false; ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n", - hchan->channel, !!(hchan->channelFlags & (CHANNEL_HT40MINUS | - CHANNEL_HT40PLUS)), - fastcc); + hchan->channel, IS_CHAN_HT40(hchan), fastcc); r = ath9k_hw_reset(ah, hchan, caldata, fastcc); if (r) { -- cgit v1.2.3-70-g09d2 From b0302aba812bcc39291cdab9ad7e37008f352a91 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Mon, 30 Jan 2012 09:54:49 -0600 Subject: rtlwifi: Convert to asynchronous firmware load This patch addresses a kernel bugzilla report and two recent mail threads. The kernel bugzilla report is https://bugzilla.kernel.org/show_bug.cgi?id=42632, which reports a udev timeout on boot. The first mail thread, which was on LKML (http://lkml.indiana.edu/hypermail/ linux/kernel/1112.3/00965.html) was for a WARNING that occurs after a suspend/resume cycle for rtl8192cu. The scond mail thread (http://marc.info/?l=linux-wireless&m=132655490826766&w=2) concerned changes in udev that break drivers that delay while firmware is loaded on modprobe. This patch converts all rtlwifi-based drivers to use the asynchronous firmware loading mechanism. Drivers rtl8192ce, rtl8192cu and rtl8192de share a common callback routine. Driver rtl8192se needs different handling of the firmware, thus it has its own code. Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/base.c | 1 + drivers/net/wireless/rtlwifi/core.c | 46 +++++++++++++++- drivers/net/wireless/rtlwifi/core.h | 2 + drivers/net/wireless/rtlwifi/pci.c | 26 ++++----- drivers/net/wireless/rtlwifi/pci.h | 1 - drivers/net/wireless/rtlwifi/ps.c | 3 +- drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 10 +--- drivers/net/wireless/rtlwifi/rtl8192ce/hw.c | 6 +-- drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 24 +++------ drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 35 ++++++------ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 29 ++++------ drivers/net/wireless/rtlwifi/rtl8192de/fw.c | 8 +-- drivers/net/wireless/rtlwifi/rtl8192de/hw.c | 3 -- drivers/net/wireless/rtlwifi/rtl8192de/sw.c | 38 ++++++------- drivers/net/wireless/rtlwifi/rtl8192se/fw.c | 2 +- drivers/net/wireless/rtlwifi/rtl8192se/hw.c | 16 +++--- drivers/net/wireless/rtlwifi/rtl8192se/led.c | 5 +- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 65 +++++++++++++++++------ drivers/net/wireless/rtlwifi/usb.c | 34 +++++------- drivers/net/wireless/rtlwifi/wifi.h | 4 +- 20 files changed, 194 insertions(+), 164 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/base.c b/drivers/net/wireless/rtlwifi/base.c index 7a95a544a9b..df5655cc55c 100644 --- a/drivers/net/wireless/rtlwifi/base.c +++ b/drivers/net/wireless/rtlwifi/base.c @@ -410,6 +410,7 @@ void rtl_init_rfkill(struct ieee80211_hw *hw) wiphy_rfkill_start_polling(hw->wiphy); } +EXPORT_SYMBOL(rtl_init_rfkill); void rtl_deinit_rfkill(struct ieee80211_hw *hw) { diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c index 0ee01ab2e4f..f231b918043 100644 --- a/drivers/net/wireless/rtlwifi/core.c +++ b/drivers/net/wireless/rtlwifi/core.c @@ -31,8 +31,50 @@ #include "core.h" #include "cam.h" #include "base.h" +#include "pci.h" #include "ps.h" +#include + +void rtl_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + release_firmware(firmware); + return; + } + memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); + rtlpriv->rtlhal.fwsize = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} +EXPORT_SYMBOL(rtl_fw_cb); + /*mutex for start & stop is must here. */ static int rtl_op_start(struct ieee80211_hw *hw) { @@ -254,10 +296,12 @@ static int rtl_op_config(struct ieee80211_hw *hw, u32 changed) * because that will cause nullfunc send by mac80211 * fail, and cause pkt loss, we have tested that 5mA * is worked very well */ - if (!rtlpriv->psc.multi_buffered) + if (!rtlpriv->psc.multi_buffered) { queue_delayed_work(rtlpriv->works.rtl_wq, &rtlpriv->works.ps_work, MSECS(5)); + pr_info("In section\n"); + } } else { rtl_swlps_rf_awake(hw); rtlpriv->psc.sw_ps_enabled = false; diff --git a/drivers/net/wireless/rtlwifi/core.h b/drivers/net/wireless/rtlwifi/core.h index 57569e0e3d4..2fe46a1b4f1 100644 --- a/drivers/net/wireless/rtlwifi/core.h +++ b/drivers/net/wireless/rtlwifi/core.h @@ -40,4 +40,6 @@ #define RTL_SUPPORTED_CTRL_FILTER 0xFF extern const struct ieee80211_ops rtl_ops; +void rtl_fw_cb(const struct firmware *firmware, void *context); + #endif diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index e4d1dcfe829..5cb2199435d 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1565,6 +1565,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw) rtlpci->driver_is_goingto_unload = true; rtlpriv->cfg->ops->hw_disable(hw); + /* some things are not needed if firmware not available */ + if (!rtlpriv->max_fw_size) + return; rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags); @@ -1779,6 +1782,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, rtlpriv = hw->priv; pcipriv = (void *)rtlpriv->priv; pcipriv->dev.pdev = pdev; + init_completion(&rtlpriv->firmware_loading_complete); /* init cfg & intf_ops */ rtlpriv->rtlhal.interface = INTF_PCI; @@ -1799,7 +1803,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, err = pci_request_regions(pdev, KBUILD_MODNAME); if (err) { RT_ASSERT(false, "Can't obtain PCI resources\n"); - return err; + goto fail2; } pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); @@ -1862,15 +1866,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, goto fail3; } - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Can't register mac80211 hw\n"); - goto fail3; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, @@ -1878,9 +1873,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, goto fail3; } - /*init rfkill */ - rtl_init_rfkill(hw); - rtlpci = rtl_pcidev(pcipriv); err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt, IRQF_SHARED, KBUILD_MODNAME, hw); @@ -1889,24 +1881,22 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, "%s: failed to register IRQ handler\n", wiphy_name(hw->wiphy)); goto fail3; - } else { - rtlpci->irq_alloc = 1; } + rtlpci->irq_alloc = 1; - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; fail3: pci_set_drvdata(pdev, NULL); rtl_deinit_core(hw); _rtl_pci_io_handler_release(hw); - ieee80211_free_hw(hw); if (rtlpriv->io.pci_mem_start != 0) pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start); fail2: pci_release_regions(pdev); + complete(&rtlpriv->firmware_loading_complete); fail1: @@ -1925,6 +1915,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev) struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); struct rtl_mac *rtlmac = rtl_mac(rtlpriv); + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group); diff --git a/drivers/net/wireless/rtlwifi/pci.h b/drivers/net/wireless/rtlwifi/pci.h index 99d81ede17b..241448fc9ed 100644 --- a/drivers/net/wireless/rtlwifi/pci.h +++ b/drivers/net/wireless/rtlwifi/pci.h @@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, void rtl_pci_disconnect(struct pci_dev *pdev); int rtl_pci_suspend(struct device *dev); int rtl_pci_resume(struct device *dev); - static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr) { return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr); diff --git a/drivers/net/wireless/rtlwifi/ps.c b/drivers/net/wireless/rtlwifi/ps.c index b151266ef9f..15f86eaa1cd 100644 --- a/drivers/net/wireless/rtlwifi/ps.c +++ b/drivers/net/wireless/rtlwifi/ps.c @@ -47,7 +47,8 @@ bool rtl_ps_enable_nic(struct ieee80211_hw *hw) "Driver is already down!\n"); /*<2> Enable Adapter */ - rtlpriv->cfg->ops->hw_init(hw); + if (rtlpriv->cfg->ops->hw_init(hw)) + return 1; RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); /*<3> Enable Interrupt */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c index 82bbc8384ac..c20b3c30f62 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c +++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c @@ -257,10 +257,9 @@ int rtl92c_download_fw(struct ieee80211_hw *hw) u32 fwsize; enum version_8192c version = rtlhal->version; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware; pfwdata = (u8 *) rtlhal->pfirmware; fwsize = rtlhal->fwsize; @@ -512,15 +511,8 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw, void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *p_cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } - memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len); _rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c index c5aced459cd..48c7b5d3fc5 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c @@ -917,10 +917,7 @@ int rtl92ce_hw_init(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; @@ -1193,7 +1190,6 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 u1b_tmp; u32 u4b_tmp; @@ -1204,7 +1200,7 @@ static void _rtl92ce_poweroff_adapter(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); - if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) + if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) rtl92c_firmware_selfreset(hw); rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c index 460dc925b4e..2c3b73366cd 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c @@ -91,9 +91,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) int err; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - char *fw_name = NULL; rtl8192ce_bt_reg_init(hw); @@ -165,26 +163,20 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw) /* request fw */ if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && !IS_92C_SERIAL(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU.bin"; + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin"; else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version)) - fw_name = "rtlwifi/rtl8192cfwU_B.bin"; - else - fw_name = rtlpriv->cfg->fw_name; - err = request_firmware(&firmware, fw_name, rtlpriv->io.dev); + rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin"; + + rtlpriv->max_fw_size = 0x4000; + pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 7f171682d3d..0c74d4f2eeb 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -997,10 +997,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW now..\n"); err = 1; - rtlhal->fw_ready = false; return err; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; /* h2c */ _rtl92cu_phy_param_tab_init(hw); @@ -1094,23 +1091,21 @@ static void _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM) if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { /* reset MCU ready status */ rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); - if (rtlhal->fw_ready) { - /* 8051 reset by self */ - rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); - while ((retry_cnts++ < 100) && - (FEN_CPUEN & rtl_read_word(rtlpriv, - REG_SYS_FUNC_EN))) { - udelay(50); - } - if (retry_cnts >= 100) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "#####=> 8051 reset failed!.........................\n"); - /* if 8051 reset fail, reset MAC. */ - rtl_write_byte(rtlpriv, - REG_SYS_FUNC_EN + 1, - 0x50); - udelay(100); - } + /* 8051 reset by self */ + rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); + while ((retry_cnts++ < 100) && + (FEN_CPUEN & rtl_read_word(rtlpriv, + REG_SYS_FUNC_EN))) { + udelay(50); + } + if (retry_cnts >= 100) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "#####=> 8051 reset failed!.........................\n"); + /* if 8051 reset fail, reset MAC. */ + rtl_write_byte(rtlpriv, + REG_SYS_FUNC_EN + 1, + 0x50); + udelay(100); } } /* Reset MAC and Enable 8051 */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index c04c3be5bd4..82c85286ab2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c @@ -53,7 +53,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin"); static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - const struct firmware *firmware; int err; rtlpriv->dm.dm_initialgain_enable = true; @@ -61,29 +60,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw) rtlpriv->dm.disable_framebursting = false; rtlpriv->dm.thermalvalue = 0; rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug; - rtlpriv->rtlhal.pfirmware = vmalloc(0x4000); + + /* for firmware buf */ + rtlpriv->rtlhal.pfirmware = vzalloc(0x4000); if (!rtlpriv->rtlhal.pfirmware) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't alloc buffer for fw\n"); return 1; } - /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); - if (err) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Failed to request firmware!\n"); - return 1; - } - if (firmware->size > 0x4000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); + + pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0x4000; + err = request_firmware_nowait(THIS_MODULE, 1, + rtlpriv->cfg->fw_name, rtlpriv->io.dev, + GFP_KERNEL, hw, rtl_fw_cb); + return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c index b59de75a364..f548a8d0068 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c @@ -253,7 +253,7 @@ int rtl92d_download_fw(struct ieee80211_hw *hw) bool fw_downloaded = false, fwdl_in_process = false; unsigned long flags; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; fwsize = rtlhal->fwsize; pfwheader = (u8 *) rtlhal->pfirmware; @@ -532,14 +532,8 @@ static void _rtl92d_fill_h2c_command(struct ieee80211_hw *hw, void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw, u8 element_id, u32 cmd_len, u8 *cmdbuffer) { - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u32 tmp_cmdbuf[2]; - if (rtlhal->fw_ready == false) { - RT_ASSERT(false, - "return H2C cmd because of Fw download fail!!!\n"); - return; - } memset(tmp_cmdbuf, 0, 8); memcpy(tmp_cmdbuf, cmdbuffer, cmd_len); _rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf); diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c index 695bccb4375..7d877125db2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c @@ -931,10 +931,7 @@ int rtl92de_hw_init(struct ieee80211_hw *hw) if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "Failed to download FW. Init HW without FW..\n"); - rtlhal->fw_ready = false; return 1; - } else { - rtlhal->fw_ready = true; } rtlhal->last_hmeboxnum = 0; rtlpriv->psc.fw_current_inpsmode = false; diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c index bf625f9e632..4898c502974 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c @@ -91,7 +91,6 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) u8 tid; struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; static int header_print; rtlpriv->dm.dm_initialgain_enable = true; @@ -167,6 +166,15 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) else if (rtlpriv->psc.reg_fwctrl_lps == 3) rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE; + /* for early mode */ + rtlpriv->rtlhal.earlymode_enable = true; + for (tid = 0; tid < 8; tid++) + skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); + + /* Only load firmware for first MAC */ + if (header_print) + return 0; + /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(0x8000); if (!rtlpriv->rtlhal.pfirmware) { @@ -175,33 +183,21 @@ static int rtl92d_init_sw_vars(struct ieee80211_hw *hw) return 1; } - if (!header_print) { - pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); - pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); - header_print++; - } + rtlpriv->max_fw_size = 0x8000; + pr_info("Driver for Realtek RTL8192DE WLAN interface\n"); + pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name); + header_print++; + /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > 0x8000) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size); - rtlpriv->rtlhal.fwsize = firmware->size; - release_firmware(firmware); - /* for early mode */ - rtlpriv->rtlhal.earlymode_enable = true; - for (tid = 0; tid < 8; tid++) - skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]); return 0; } diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c index 595ecd22ffa..0d8bf565700 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c @@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_hw *hw) u8 fwstatus = FW_STATUS_INIT; bool rtstatus = true; - if (!rtlhal->pfirmware) + if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware) return 1; firmware = (struct rt_firmware *)rtlhal->pfirmware; diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c index cbaf1f345c6..22098c2f38f 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c @@ -949,10 +949,9 @@ int rtl92se_hw_init(struct ieee80211_hw *hw) rtstatus = rtl92s_download_fw(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); - rtlhal->fw_ready = false; - } else { - rtlhal->fw_ready = true; + "Failed to download FW. Init HW without FW now... " + "Please copy FW into /lib/firmware/rtlwifi\n"); + return 1; } /* After FW download, we have to reset MAC register */ @@ -1215,9 +1214,14 @@ void rtl92se_enable_interrupt(struct ieee80211_hw *hw) void rtl92se_disable_interrupt(struct ieee80211_hw *hw) { - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); + struct rtl_priv *rtlpriv; + struct rtl_pci *rtlpci; + rtlpriv = rtl_priv(hw); + /* if firmware not available, no interrupts */ + if (!rtlpriv || !rtlpriv->max_fw_size) + return; + rtlpci = rtl_pcidev(rtl_pcipriv(hw)); rtl_write_dword(rtlpriv, INTA_MASK, 0); rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/led.c b/drivers/net/wireless/rtlwifi/rtl8192se/led.c index ef4211bca58..44949b5cbb8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c @@ -76,10 +76,13 @@ void rtl92se_sw_led_on(struct ieee80211_hw *hw, struct rtl_led *pled) void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled) { - struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_priv *rtlpriv; struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); u8 ledcfg; + rtlpriv = rtl_priv(hw); + if (!rtlpriv || rtlpriv->max_fw_size) + return; RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD, "LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin); diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 0c47310b39b..ca38dd9f356 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -30,6 +30,8 @@ #include "../wifi.h" #include "../core.h" #include "../pci.h" +#include "../base.h" +#include "../pci.h" #include "reg.h" #include "def.h" #include "phy.h" @@ -86,12 +88,53 @@ static void rtl92s_init_aspm_vars(struct ieee80211_hw *hw) rtlpci->const_support_pciaspm = 2; } +static void rtl92se_fw_cb(const struct firmware *firmware, void *context) +{ + struct ieee80211_hw *hw = context; + struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rtl_pci *rtlpci = rtl_pcidev(pcipriv); + struct rt_firmware *pfirmware = NULL; + int err; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { + pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name); + rtlpriv->max_fw_size = 0; + return; + } + if (firmware->size > rtlpriv->max_fw_size) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Firmware is too big!\n"); + release_firmware(firmware); + return; + } + pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; + memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); + pfirmware->sz_fw_tmpbufferlen = firmware->size; + release_firmware(firmware); + + err = ieee80211_register_hw(hw); + if (err) { + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Can't register mac80211 hw\n"); + return; + } else { + rtlpriv->mac80211.mac80211_registered = 1; + } + rtlpci->irq_alloc = 1; + set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); + + /*init rfkill */ + rtl_init_rfkill(hw); +} + static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); - const struct firmware *firmware; - struct rt_firmware *pfirmware = NULL; int err = 0; u16 earlyrxthreshold = 7; @@ -189,27 +232,19 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) return 1; } + rtlpriv->max_fw_size = sizeof(struct rt_firmware); + pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); /* request fw */ - err = request_firmware(&firmware, rtlpriv->cfg->fw_name, - rtlpriv->io.dev); + err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name, + rtlpriv->io.dev, GFP_KERNEL, hw, + rtl92se_fw_cb); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Failed to request firmware!\n"); return 1; } - if (firmware->size > sizeof(struct rt_firmware)) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "Firmware is too big!\n"); - release_firmware(firmware); - return 1; - } - - pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware; - memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size); - pfirmware->sz_fw_tmpbufferlen = firmware->size; - release_firmware(firmware); return err; } diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index e7a7ea96f42..ffcf89fe45e 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -664,15 +664,17 @@ static int rtl_usb_start(struct ieee80211_hw *hw) struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); err = rtlpriv->cfg->ops->hw_init(hw); - rtl_init_rx_config(hw); + if (!err) { + rtl_init_rx_config(hw); - /* Enable software */ - SET_USB_START(rtlusb); - /* should after adapter start and interrupt enable. */ - set_hal_start(rtlhal); + /* Enable software */ + SET_USB_START(rtlusb); + /* should after adapter start and interrupt enable. */ + set_hal_start(rtlhal); - /* Start bulk IN */ - _rtl_usb_receive(hw); + /* Start bulk IN */ + _rtl_usb_receive(hw); + } return err; } @@ -949,6 +951,7 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, return -ENOMEM; } rtlpriv = hw->priv; + init_completion(&rtlpriv->firmware_loading_complete); SET_IEEE80211_DEV(hw, &intf->dev); udev = interface_to_usbdev(intf); usb_get_dev(udev); @@ -982,24 +985,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf, goto error_out; } - /*init rfkill */ - /* rtl_init_rfkill(hw); */ - - err = ieee80211_register_hw(hw); - if (err) { - RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, - "Can't register mac80211 hw\n"); - goto error_out; - } else { - rtlpriv->mac80211.mac80211_registered = 1; - } - set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; error_out: rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); - ieee80211_free_hw(hw); usb_put_dev(udev); + complete(&rtlpriv->firmware_loading_complete); return -ENODEV; } EXPORT_SYMBOL(rtl_usb_probe); @@ -1013,6 +1004,9 @@ void rtl_usb_disconnect(struct usb_interface *intf) if (unlikely(!rtlpriv)) return; + + /* just in case driver is removed before firmware callback */ + wait_for_completion(&rtlpriv->firmware_loading_complete); /*ieee80211_unregister_hw will call ops_stop */ if (rtlmac->mac80211_registered == 1) { ieee80211_unregister_hw(hw); diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h index 1e5fffb2db0..b591614c3b9 100644 --- a/drivers/net/wireless/rtlwifi/wifi.h +++ b/drivers/net/wireless/rtlwifi/wifi.h @@ -38,6 +38,7 @@ #include #include #include +#include #include "debug.h" #define RF_CHANGE_BY_INIT 0 @@ -1047,7 +1048,6 @@ struct rtl_hal { u16 fw_subversion; bool h2c_setinprogress; u8 last_hmeboxnum; - bool fw_ready; /*Reserve page start offset except beacon in TxQ. */ u8 fw_rsvdpage_startoffset; u8 h2c_txcmd_seq; @@ -1593,6 +1593,7 @@ struct rtl_debug { }; struct rtl_priv { + struct completion firmware_loading_complete; struct rtl_locks locks; struct rtl_works works; struct rtl_mac mac80211; @@ -1614,6 +1615,7 @@ struct rtl_priv { struct rtl_rate_priv *rate_priv; struct rtl_debug dbg; + int max_fw_size; /* *hal_cfg : for diff cards -- cgit v1.2.3-70-g09d2 From c0eb46766d395da8d62148bda2e59bad5e6ee2f2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 30 Jan 2012 19:56:52 +0000 Subject: regmap: Implement managed regmap_init() Save error handling and unwinding code in drivers by providing managed versions of the regmap init functions, simplifying usage. Signed-off-by: Mark Brown --- drivers/base/regmap/regmap-i2c.c | 17 +++++++++++++++++ drivers/base/regmap/regmap-spi.c | 17 +++++++++++++++++ drivers/base/regmap/regmap.c | 39 +++++++++++++++++++++++++++++++++++++++ include/linux/regmap.h | 8 ++++++++ 4 files changed, 81 insertions(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-i2c.c b/drivers/base/regmap/regmap-i2c.c index 38621ec87c0..9a3a8c56438 100644 --- a/drivers/base/regmap/regmap-i2c.c +++ b/drivers/base/regmap/regmap-i2c.c @@ -111,4 +111,21 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, } EXPORT_SYMBOL_GPL(regmap_init_i2c); +/** + * devm_regmap_init_i2c(): Initialise managed register map + * + * @i2c: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The regmap will be automatically freed by the + * device management code. + */ +struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, + const struct regmap_config *config) +{ + return devm_regmap_init(&i2c->dev, ®map_i2c, config); +} +EXPORT_SYMBOL_GPL(devm_regmap_init_i2c); + MODULE_LICENSE("GPL"); diff --git a/drivers/base/regmap/regmap-spi.c b/drivers/base/regmap/regmap-spi.c index 2560658de34..7c0c35a39c3 100644 --- a/drivers/base/regmap/regmap-spi.c +++ b/drivers/base/regmap/regmap-spi.c @@ -70,4 +70,21 @@ struct regmap *regmap_init_spi(struct spi_device *spi, } EXPORT_SYMBOL_GPL(regmap_init_spi); +/** + * devm_regmap_init_spi(): Initialise register map + * + * @spi: Device that will be interacted with + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. The map will be automatically freed by the + * device management code. + */ +struct regmap *devm_regmap_init_spi(struct spi_device *spi, + const struct regmap_config *config) +{ + return devm_regmap_init(&spi->dev, ®map_spi, config); +} +EXPORT_SYMBOL_GPL(devm_regmap_init_spi); + MODULE_LICENSE("GPL"); diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index be10a4ff660..839cc82bd17 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c @@ -258,6 +258,45 @@ err: } EXPORT_SYMBOL_GPL(regmap_init); +static void devm_regmap_release(struct device *dev, void *res) +{ + regmap_exit(*(struct regmap **)res); +} + +/** + * devm_regmap_init(): Initialise managed register map + * + * @dev: Device that will be interacted with + * @bus: Bus-specific callbacks to use with device + * @config: Configuration for register map + * + * The return value will be an ERR_PTR() on error or a valid pointer + * to a struct regmap. This function should generally not be called + * directly, it should be called by bus-specific init functions. The + * map will be automatically freed by the device management code. + */ +struct regmap *devm_regmap_init(struct device *dev, + const struct regmap_bus *bus, + const struct regmap_config *config) +{ + struct regmap **ptr, *regmap; + + ptr = devres_alloc(devm_regmap_release, sizeof(*ptr), GFP_KERNEL); + if (!ptr) + return ERR_PTR(-ENOMEM); + + regmap = regmap_init(dev, bus, config); + if (!IS_ERR(regmap)) { + *ptr = regmap; + devres_add(dev, ptr); + } else { + devres_free(ptr); + } + + return regmap; +} +EXPORT_SYMBOL_GPL(devm_regmap_init); + /** * regmap_reinit_cache(): Reinitialise the current register cache * diff --git a/include/linux/regmap.h b/include/linux/regmap.h index eb93921cdd3..195db51ec79 100644 --- a/include/linux/regmap.h +++ b/include/linux/regmap.h @@ -127,6 +127,14 @@ struct regmap *regmap_init_i2c(struct i2c_client *i2c, struct regmap *regmap_init_spi(struct spi_device *dev, const struct regmap_config *config); +struct regmap *devm_regmap_init(struct device *dev, + const struct regmap_bus *bus, + const struct regmap_config *config); +struct regmap *devm_regmap_init_i2c(struct i2c_client *i2c, + const struct regmap_config *config); +struct regmap *devm_regmap_init_spi(struct spi_device *dev, + const struct regmap_config *config); + void regmap_exit(struct regmap *map); int regmap_reinit_cache(struct regmap *map, const struct regmap_config *config); -- cgit v1.2.3-70-g09d2 From ff3d9c3c90c6edcb975c390db3671713899c2842 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Wed, 28 Dec 2011 17:37:59 +0000 Subject: staging: sep: SEP update This is basically a rewrite so there isn't a nice easy to present way of providing this as a patch series. This patch is a pull of Mark's new driver into the upstream staging area. On top of that are a series of patches by Andy Shevchenko to make it build on the current tree, fix a few things and even get it passed sparse. The new driver supports the kernel crypto layer, passes the coding style checks, passes human taste checks and has proper kernel-doc formatted comments. I've then folded back in some later fixes it was missing that got applied to to the kernel tree. This should be ready for more serious review with a view to migration from the staging tree shortly. Signed-off-by: Mark Allyn [Forward port and some bug fixing] Signed-off-by: Andy Shevchenko [Fold and tweaks for 3.2] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/Kconfig | 3 +- drivers/staging/sep/Makefile | 5 +- drivers/staging/sep/TODO | 5 +- drivers/staging/sep/sep_crypto.c | 3768 ++++++++++++++++++++++++++ drivers/staging/sep/sep_crypto.h | 348 +++ drivers/staging/sep/sep_dev.h | 99 +- drivers/staging/sep/sep_driver.c | 2932 -------------------- drivers/staging/sep/sep_driver_api.h | 280 +- drivers/staging/sep/sep_driver_config.h | 79 +- drivers/staging/sep/sep_driver_hw_defs.h | 182 +- drivers/staging/sep/sep_main.c | 4286 ++++++++++++++++++++++++++++++ drivers/staging/sep/sep_trace_events.h | 188 ++ 12 files changed, 8960 insertions(+), 3215 deletions(-) create mode 100644 drivers/staging/sep/sep_crypto.c create mode 100644 drivers/staging/sep/sep_crypto.h delete mode 100644 drivers/staging/sep/sep_driver.c create mode 100644 drivers/staging/sep/sep_main.c create mode 100644 drivers/staging/sep/sep_trace_events.h (limited to 'drivers') diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig index 92bf16667d0..185b676d858 100644 --- a/drivers/staging/sep/Kconfig +++ b/drivers/staging/sep/Kconfig @@ -3,7 +3,8 @@ config DX_SEP depends on PCI help Discretix SEP driver; used for the security processor subsystem - on bard the Intel Mobile Internet Device. + on board the Intel Mobile Internet Device and adds SEP availability + to the kernel crypto infrastructure The driver's name is sep_driver. diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile index 628d5f91941..e48a7959289 100644 --- a/drivers/staging/sep/Makefile +++ b/drivers/staging/sep/Makefile @@ -1,2 +1,3 @@ -obj-$(CONFIG_DX_SEP) := sep_driver.o - +ccflags-y += -I$(srctree)/$(src) +obj-$(CONFIG_DX_SEP) += sep_driver.o +sep_driver-objs := sep_crypto.o sep_main.o diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO index 8f3b878ad8a..3524d0cf84b 100644 --- a/drivers/staging/sep/TODO +++ b/drivers/staging/sep/TODO @@ -1,4 +1,3 @@ Todo's so far (from Alan Cox) -- Check whether it can be plugged into any of the kernel crypto API - interfaces - Crypto API 'glue' is still not ready to submit -- Clean up un-needed debug prints - Started to work on this +- Clean up unused ioctls +- Clean up unused fields in ioctl structures diff --git a/drivers/staging/sep/sep_crypto.c b/drivers/staging/sep/sep_crypto.c new file mode 100644 index 00000000000..a6b0f8353bb --- /dev/null +++ b/drivers/staging/sep/sep_crypto.c @@ -0,0 +1,3768 @@ +/* + * + * sep_crypto.c - Crypto interface structures + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2010 Discretix. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2010.09.14 Upgrade to Medfield + * 2011.02.22 Enable Kernel Crypto + * + */ + +/* #define DEBUG */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_dev.h" +#include "sep_crypto.h" + +/* Globals for queuing */ +static spinlock_t queue_lock; +static struct crypto_queue sep_queue; + +/* Declare of dequeuer */ +static void sep_dequeuer(void *data); + +/* TESTING */ +/** + * crypto_sep_dump_message - dump the message that is pending + * @sep: SEP device + * This will only print dump if DEBUG is set; it does + * follow kernel debug print enabling + */ +static void crypto_sep_dump_message(struct sep_system_ctx *sctx) +{ +#if 0 + u32 *p; + u32 *i; + int count; + + p = sctx->sep_used->shared_addr; + i = (u32 *)sctx->msg; + for (count = 0; count < 40 * 4; count += 4) + dev_dbg(&sctx->sep_used->pdev->dev, + "[PID%d] Word %d of the message is %x (local)%x\n", + current->pid, count/4, *p++, *i++); +#endif +} + +/** + * sep_do_callback + * @work: pointer to work_struct + * This is what is called by the queue; it is generic so that it + * can be used by any type of operation as each different callback + * function can use the data parameter in its own way + */ +static void sep_do_callback(struct work_struct *work) +{ + struct sep_work_struct *sep_work = container_of(work, + struct sep_work_struct, work); + if (sep_work != NULL) { + (sep_work->callback)(sep_work->data); + kfree(sep_work); + } else { + pr_debug("sep crypto: do callback - NULL container\n"); + } +} + +/** + * sep_submit_work + * @work_queue: pointer to struct_workqueue + * @funct: pointer to function to execute + * @data: pointer to data; function will know + * how to use it + * This is a generic API to submit something to + * the queue. The callback function will depend + * on what operation is to be done + */ +static int sep_submit_work(struct workqueue_struct *work_queue, + void(*funct)(void *), + void *data) +{ + struct sep_work_struct *sep_work; + int result; + + sep_work = kmalloc(sizeof(struct sep_work_struct), GFP_ATOMIC); + + if (sep_work == NULL) { + pr_debug("sep crypto: cant allocate work structure\n"); + return -ENOMEM; + } + + sep_work->callback = funct; + sep_work->data = data; + INIT_WORK(&sep_work->work, sep_do_callback); + result = queue_work(work_queue, &sep_work->work); + if (!result) { + pr_debug("sep_crypto: queue_work failed\n"); + return -EINVAL; + } + return 0; +} + +/** + * sep_alloc_sg_buf - + * @sep: pointer to struct sep_device + * @size: total size of area + * @block_size: minimum size of chunks + * each page is minimum or modulo this size + * @returns: pointer to struct scatterlist for new + * buffer + **/ +static struct scatterlist *sep_alloc_sg_buf( + struct sep_device *sep, + size_t size, + size_t block_size) +{ + u32 nbr_pages; + u32 ct1; + void *buf; + size_t current_size; + size_t real_page_size; + + struct scatterlist *sg, *sg_temp; + + if (size == 0) + return NULL; + + dev_dbg(&sep->pdev->dev, "sep alloc sg buf\n"); + + current_size = 0; + nbr_pages = 0; + real_page_size = PAGE_SIZE - (PAGE_SIZE % block_size); + /** + * The size of each page must be modulo of the operation + * block size; increment by the modified page size until + * the total size is reached, then you have the number of + * pages + */ + while (current_size < size) { + current_size += real_page_size; + nbr_pages += 1; + } + + sg = kmalloc((sizeof(struct scatterlist) * nbr_pages), GFP_ATOMIC); + if (!sg) { + dev_warn(&sep->pdev->dev, "Cannot allocate page for new sg\n"); + return NULL; + } + + sg_init_table(sg, nbr_pages); + + current_size = 0; + sg_temp = sg; + for (ct1 = 0; ct1 < nbr_pages; ct1 += 1) { + buf = (void *)get_zeroed_page(GFP_ATOMIC); + if (!buf) { + dev_warn(&sep->pdev->dev, + "Cannot allocate page for new buffer\n"); + kfree(sg); + return NULL; + } + + sg_set_buf(sg_temp, buf, real_page_size); + if ((size - current_size) > real_page_size) { + sg_temp->length = real_page_size; + current_size += real_page_size; + } else { + sg_temp->length = (size - current_size); + current_size = size; + } + sg_temp = sg_next(sg); + } + return sg; +} + +/** + * sep_free_sg_buf - + * @sg: pointer to struct scatterlist; points to area to free + */ +static void sep_free_sg_buf(struct scatterlist *sg) +{ + struct scatterlist *sg_temp = sg; + while (sg_temp) { + free_page((unsigned long)sg_virt(sg_temp)); + sg_temp = sg_next(sg_temp); + } + kfree(sg); +} + +/** + * sep_copy_sg - + * @sep: pointer to struct sep_device + * @sg_src: pointer to struct scatterlist for source + * @sg_dst: pointer to struct scatterlist for destination + * @size: size (in bytes) of data to copy + * + * Copy data from one scatterlist to another; both must + * be the same size + */ +static void sep_copy_sg( + struct sep_device *sep, + struct scatterlist *sg_src, + struct scatterlist *sg_dst, + size_t size) +{ + u32 seg_size; + u32 in_offset, out_offset; + + u32 count = 0; + struct scatterlist *sg_src_tmp = sg_src; + struct scatterlist *sg_dst_tmp = sg_dst; + in_offset = 0; + out_offset = 0; + + dev_dbg(&sep->pdev->dev, "sep copy sg\n"); + + if ((sg_src == NULL) || (sg_dst == NULL) || (size == 0)) + return; + + dev_dbg(&sep->pdev->dev, "sep copy sg not null\n"); + + while (count < size) { + if ((sg_src_tmp->length - in_offset) > + (sg_dst_tmp->length - out_offset)) + seg_size = sg_dst_tmp->length - out_offset; + else + seg_size = sg_src_tmp->length - in_offset; + + if (seg_size > (size - count)) + seg_size = (size = count); + + memcpy(sg_virt(sg_dst_tmp) + out_offset, + sg_virt(sg_src_tmp) + in_offset, + seg_size); + + in_offset += seg_size; + out_offset += seg_size; + count += seg_size; + + if (in_offset >= sg_src_tmp->length) { + sg_src_tmp = sg_next(sg_src_tmp); + in_offset = 0; + } + + if (out_offset >= sg_dst_tmp->length) { + sg_dst_tmp = sg_next(sg_dst_tmp); + out_offset = 0; + } + } +} + +/** + * sep_oddball_pages - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist - buffer to check + * @size: total data size + * @blocksize: minimum block size; must be multiples of this size + * @to_copy: 1 means do copy, 0 means do not copy + * @new_sg: pointer to location to put pointer to new sg area + * @returns: 1 if new scatterlist is needed; 0 if not needed; + * error value if operation failed + * + * The SEP device requires all pages to be multiples of the + * minimum block size appropriate for the operation + * This function check all pages; if any are oddball sizes + * (not multiple of block sizes), it creates a new scatterlist. + * If the to_copy parameter is set to 1, then a scatter list + * copy is performed. The pointer to the new scatterlist is + * put into the address supplied by the new_sg parameter; if + * no new scatterlist is needed, then a NULL is put into + * the location at new_sg. + * + */ +static int sep_oddball_pages( + struct sep_device *sep, + struct scatterlist *sg, + size_t data_size, + u32 block_size, + struct scatterlist **new_sg, + u32 do_copy) +{ + struct scatterlist *sg_temp; + u32 flag; + u32 nbr_pages, page_count; + + dev_dbg(&sep->pdev->dev, "sep oddball\n"); + if ((sg == NULL) || (data_size == 0) || (data_size < block_size)) + return 0; + + dev_dbg(&sep->pdev->dev, "sep oddball not null\n"); + flag = 0; + nbr_pages = 0; + page_count = 0; + sg_temp = sg; + + while (sg_temp) { + nbr_pages += 1; + sg_temp = sg_next(sg_temp); + } + + sg_temp = sg; + while ((sg_temp) && (flag == 0)) { + page_count += 1; + if (sg_temp->length % block_size) + flag = 1; + else + sg_temp = sg_next(sg_temp); + } + + /* Do not process if last (or only) page is oddball */ + if (nbr_pages == page_count) + flag = 0; + + if (flag) { + dev_dbg(&sep->pdev->dev, "sep oddball processing\n"); + *new_sg = sep_alloc_sg_buf(sep, data_size, block_size); + if (*new_sg == NULL) { + dev_warn(&sep->pdev->dev, "cannot allocate new sg\n"); + return -ENOMEM; + } + + if (do_copy) + sep_copy_sg(sep, sg, *new_sg, data_size); + + return 1; + } else { + return 0; + } +} + +/** + * sep_copy_offset_sg - + * @sep: pointer to struct sep_device; + * @sg: pointer to struct scatterlist + * @offset: offset into scatterlist memory + * @dst: place to put data + * @len: length of data + * @returns: number of bytes copies + * + * This copies data from scatterlist buffer + * offset from beginning - it is needed for + * handling tail data in hash + */ +static size_t sep_copy_offset_sg( + struct sep_device *sep, + struct scatterlist *sg, + u32 offset, + void *dst, + u32 len) +{ + size_t page_start; + size_t page_end; + size_t offset_within_page; + size_t length_within_page; + size_t length_remaining; + size_t current_offset; + + /* Find which page is beginning of segment */ + page_start = 0; + page_end = sg->length; + while ((sg) && (offset > page_end)) { + page_start += sg->length; + sg = sg_next(sg); + if (sg) + page_end += sg->length; + } + + if (sg == NULL) + return -ENOMEM; + + offset_within_page = offset - page_start; + if ((sg->length - offset_within_page) >= len) { + /* All within this page */ + memcpy(dst, sg_virt(sg) + offset_within_page, len); + return len; + } else { + /* Scattered multiple pages */ + current_offset = 0; + length_remaining = len; + while ((sg) && (current_offset < len)) { + length_within_page = sg->length - offset_within_page; + if (length_within_page >= length_remaining) { + memcpy(dst+current_offset, + sg_virt(sg) + offset_within_page, + length_remaining); + length_remaining = 0; + current_offset = len; + } else { + memcpy(dst+current_offset, + sg_virt(sg) + offset_within_page, + length_within_page); + length_remaining -= length_within_page; + current_offset += length_within_page; + offset_within_page = 0; + sg = sg_next(sg); + } + } + + if (sg == NULL) + return -ENOMEM; + } + return len; +} + +/** + * partial_overlap - + * @src_ptr: source pointer + * @dst_ptr: destination pointer + * @nbytes: number of bytes + * @returns: 0 for success; -1 for failure + * We cannot have any partial overlap. Total overlap + * where src is the same as dst is okay + */ +static int partial_overlap(void *src_ptr, void *dst_ptr, u32 nbytes) +{ + /* Check for partial overlap */ + if (src_ptr != dst_ptr) { + if (src_ptr < dst_ptr) { + if ((src_ptr + nbytes) > dst_ptr) + return -EINVAL; + } else { + if ((dst_ptr + nbytes) > src_ptr) + return -EINVAL; + } + } + + return 0; +} + +/* Debug - prints only if DEBUG is defined; follows kernel debug model */ +static void sep_dump(struct sep_device *sep, char *stg, void *start, int len) +{ +#if 0 + int ct1; + u8 *ptt; + + dev_dbg(&sep->pdev->dev, + "Dump of %s starting at %08lx for %08x bytes\n", + stg, (unsigned long)start, len); + for (ct1 = 0; ct1 < len; ct1 += 1) { + ptt = (u8 *)(start + ct1); + dev_dbg(&sep->pdev->dev, "%02x ", *ptt); + if (ct1 % 16 == 15) + dev_dbg(&sep->pdev->dev, "\n"); + } + dev_dbg(&sep->pdev->dev, "\n"); +#endif +} + +/* Debug - prints only if DEBUG is defined; follows kernel debug model */ +static void sep_dump_sg(struct sep_device *sep, char *stg, + struct scatterlist *sg) +{ +#if 0 + int ct1, ct2; + u8 *ptt; + + dev_dbg(&sep->pdev->dev, "Dump of scatterlist %s\n", stg); + + ct1 = 0; + while (sg) { + dev_dbg(&sep->pdev->dev, "page %x\n size %x", ct1, + sg->length); + dev_dbg(&sep->pdev->dev, "phys addr is %lx", + (unsigned long)sg_phys(sg)); + ptt = sg_virt(sg); + for (ct2 = 0; ct2 < sg->length; ct2 += 1) { + dev_dbg(&sep->pdev->dev, "byte %x is %02x\n", + ct2, (unsigned char)*(ptt + ct2)); + } + + ct1 += 1; + sg = sg_next(sg); + } + dev_dbg(&sep->pdev->dev, "\n"); +#endif +} + +/** + * RFC2451: Weak key check + * Returns: 1 (weak), 0 (not weak) + */ +static int sep_weak_key(const u8 *key, unsigned int keylen) +{ + static const u8 parity[] = { + 8, 1, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 2, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 3, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 0, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 0, 8, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 8, 0, 0, 8, 0, 8, 8, 0, 0, 8, 8, 0, 8, 0, 0, 8, + 0, 8, 8, 0, 8, 0, 0, 8, 8, + 0, 0, 8, 0, 8, 8, 0, + 4, 8, 8, 0, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8, 8, 0, + 8, 5, 0, 8, 0, 8, 8, 0, 0, + 8, 8, 0, 8, 0, 6, 8, + }; + + u32 n, w; + + n = parity[key[0]]; n <<= 4; + n |= parity[key[1]]; n <<= 4; + n |= parity[key[2]]; n <<= 4; + n |= parity[key[3]]; n <<= 4; + n |= parity[key[4]]; n <<= 4; + n |= parity[key[5]]; n <<= 4; + n |= parity[key[6]]; n <<= 4; + n |= parity[key[7]]; + w = 0x88888888L; + + /* 1 in 10^10 keys passes this test */ + if (!((n - (w >> 3)) & w)) { + if (n < 0x41415151) { + if (n < 0x31312121) { + if (n < 0x14141515) { + /* 01 01 01 01 01 01 01 01 */ + if (n == 0x11111111) + goto weak; + /* 01 1F 01 1F 01 0E 01 0E */ + if (n == 0x13131212) + goto weak; + } else { + /* 01 E0 01 E0 01 F1 01 F1 */ + if (n == 0x14141515) + goto weak; + /* 01 FE 01 FE 01 FE 01 FE */ + if (n == 0x16161616) + goto weak; + } + } else { + if (n < 0x34342525) { + /* 1F 01 1F 01 0E 01 0E 01 */ + if (n == 0x31312121) + goto weak; + /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ + if (n == 0x33332222) + goto weak; + } else { + /* 1F E0 1F E0 0E F1 0E F1 */ + if (n == 0x34342525) + goto weak; + /* 1F FE 1F FE 0E FE 0E FE */ + if (n == 0x36362626) + goto weak; + } + } + } else { + if (n < 0x61616161) { + if (n < 0x44445555) { + /* E0 01 E0 01 F1 01 F1 01 */ + if (n == 0x41415151) + goto weak; + /* E0 1F E0 1F F1 0E F1 0E */ + if (n == 0x43435252) + goto weak; + } else { + /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ + if (n == 0x44445555) + goto weak; + /* E0 FE E0 FE F1 FE F1 FE */ + if (n == 0x46465656) + goto weak; + } + } else { + if (n < 0x64646565) { + /* FE 01 FE 01 FE 01 FE 01 */ + if (n == 0x61616161) + goto weak; + /* FE 1F FE 1F FE 0E FE 0E */ + if (n == 0x63636262) + goto weak; + } else { + /* FE E0 FE E0 FE F1 FE F1 */ + if (n == 0x64646565) + goto weak; + /* FE FE FE FE FE FE FE FE */ + if (n == 0x66666666) + goto weak; + } + } + } + } + return 0; +weak: + return 1; +} +/** + * sep_sg_nents + */ +static u32 sep_sg_nents(struct scatterlist *sg) +{ + u32 ct1 = 0; + while (sg) { + ct1 += 1; + sg = sg_next(sg); + } + + return ct1; +} + +/** + * sep_start_msg - + * @sctx: pointer to struct sep_system_ctx + * @returns: offset to place for the next word in the message + * Set up pointer in message pool for new message + */ +static u32 sep_start_msg(struct sep_system_ctx *sctx) +{ + u32 *word_ptr; + sctx->msg_len_words = 2; + sctx->msgptr = sctx->msg; + memset(sctx->msg, 0, SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + sctx->msgptr += sizeof(u32) * 2; + word_ptr = (u32 *)sctx->msgptr; + *word_ptr = SEP_START_MSG_TOKEN; + return sizeof(u32) * 2; +} + +/** + * sep_end_msg - + * @sctx: pointer to struct sep_system_ctx + * @messages_offset: current message offset + * Returns: 0 for success; <0 otherwise + * End message; set length and CRC; and + * send interrupt to the SEP + */ +static void sep_end_msg(struct sep_system_ctx *sctx, u32 msg_offset) +{ + u32 *word_ptr; + /* Msg size goes into msg after token */ + sctx->msg_len_words = msg_offset / sizeof(u32) + 1; + word_ptr = (u32 *)sctx->msgptr; + word_ptr += 1; + *word_ptr = sctx->msg_len_words; + + /* CRC (currently 0) goes at end of msg */ + word_ptr = (u32 *)(sctx->msgptr + msg_offset); + *word_ptr = 0; +} + +/** + * sep_start_inbound_msg - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: offset to place for the next word in the message + * @returns: 0 for success; error value for failure + * Set up pointer in message pool for inbound message + */ +static u32 sep_start_inbound_msg(struct sep_system_ctx *sctx, u32 *msg_offset) +{ + u32 *word_ptr; + u32 token; + u32 error = SEP_OK; + + *msg_offset = sizeof(u32) * 2; + word_ptr = (u32 *)sctx->msgptr; + token = *word_ptr; + sctx->msg_len_words = *(word_ptr + 1); + + if (token != SEP_START_MSG_TOKEN) { + error = SEP_INVALID_START; + goto end_function; + } + +end_function: + + return error; +} + +/** + * sep_write_msg - + * @sctx: pointer to struct sep_system_ctx + * @in_addr: pointer to start of parameter + * @size: size of parameter to copy (in bytes) + * @max_size: size to move up offset; SEP mesg is in word sizes + * @msg_offset: pointer to current offset (is updated) + * @byte_array: flag ti indicate wheter endian must be changed + * Copies data into the message area from caller + */ +static void sep_write_msg(struct sep_system_ctx *sctx, void *in_addr, + u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) +{ + u32 *word_ptr; + void *void_ptr; + void_ptr = sctx->msgptr + *msg_offset; + word_ptr = (u32 *)void_ptr; + memcpy(void_ptr, in_addr, size); + *msg_offset += max_size; + + /* Do we need to manipulate endian? */ + if (byte_array) { + u32 i; + for (i = 0; i < ((size + 3) / 4); i += 1) + *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); + } +} + +/** + * sep_make_header + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: pointer to current offset (is updated) + * @op_code: op code to put into message + * Puts op code into message and updates offset + */ +static void sep_make_header(struct sep_system_ctx *sctx, u32 *msg_offset, + u32 op_code) +{ + u32 *word_ptr; + + *msg_offset = sep_start_msg(sctx); + word_ptr = (u32 *)(sctx->msgptr + *msg_offset); + *word_ptr = op_code; + *msg_offset += sizeof(u32); +} + + + +/** + * sep_read_msg - + * @sctx: pointer to struct sep_system_ctx + * @in_addr: pointer to start of parameter + * @size: size of parameter to copy (in bytes) + * @max_size: size to move up offset; SEP mesg is in word sizes + * @msg_offset: pointer to current offset (is updated) + * @byte_array: flag ti indicate wheter endian must be changed + * Copies data out of the message area to caller + */ +static void sep_read_msg(struct sep_system_ctx *sctx, void *in_addr, + u32 size, u32 max_size, u32 *msg_offset, u32 byte_array) +{ + u32 *word_ptr; + void *void_ptr; + void_ptr = sctx->msgptr + *msg_offset; + word_ptr = (u32 *)void_ptr; + + /* Do we need to manipulate endian? */ + if (byte_array) { + u32 i; + for (i = 0; i < ((size + 3) / 4); i += 1) + *(word_ptr + i) = CHG_ENDIAN(*(word_ptr + i)); + } + + memcpy(in_addr, void_ptr, size); + *msg_offset += max_size; +} + +/** + * sep_verify_op - + * @sctx: pointer to struct sep_system_ctx + * @op_code: expected op_code + * @msg_offset: pointer to current offset (is updated) + * @returns: 0 for success; error for failure + */ +static u32 sep_verify_op(struct sep_system_ctx *sctx, u32 op_code, + u32 *msg_offset) +{ + u32 error; + u32 in_ary[2]; + + struct sep_device *sep = sctx->sep_used; + + dev_dbg(&sep->pdev->dev, "dumping return message\n"); + error = sep_start_inbound_msg(sctx, msg_offset); + if (error) { + dev_warn(&sep->pdev->dev, + "sep_start_inbound_msg error\n"); + return error; + } + + sep_read_msg(sctx, in_ary, sizeof(u32) * 2, sizeof(u32) * 2, + msg_offset, 0); + + if (in_ary[0] != op_code) { + dev_warn(&sep->pdev->dev, + "sep got back wrong opcode\n"); + dev_warn(&sep->pdev->dev, + "got back %x; expected %x\n", + in_ary[0], op_code); + return SEP_WRONG_OPCODE; + } + + if (in_ary[1] != SEP_OK) { + dev_warn(&sep->pdev->dev, + "sep execution error\n"); + dev_warn(&sep->pdev->dev, + "got back %x; expected %x\n", + in_ary[1], SEP_OK); + return in_ary[0]; + } + +return 0; +} + +/** + * sep_read_context - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: point to current place in SEP msg; is updated + * @dst: pointer to place to put the context + * @len: size of the context structure (differs for crypro/hash) + * This function reads the context from the msg area + * There is a special way the vendor needs to have the maximum + * length calculated so that the msg_offset is updated properly; + * it skips over some words in the msg area depending on the size + * of the context + */ +static void sep_read_context(struct sep_system_ctx *sctx, u32 *msg_offset, + void *dst, u32 len) +{ + u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); + sep_read_msg(sctx, dst, len, max_length, msg_offset, 0); +} + +/** + * sep_write_context - + * @sctx: pointer to struct sep_system_ctx + * @msg_offset: point to current place in SEP msg; is updated + * @src: pointer to the current context + * @len: size of the context structure (differs for crypro/hash) + * This function writes the context to the msg area + * There is a special way the vendor needs to have the maximum + * length calculated so that the msg_offset is updated properly; + * it skips over some words in the msg area depending on the size + * of the context + */ +static void sep_write_context(struct sep_system_ctx *sctx, u32 *msg_offset, + void *src, u32 len) +{ + u32 max_length = ((len + 3) / sizeof(u32)) * sizeof(u32); + sep_write_msg(sctx, src, len, max_length, msg_offset, 0); +} + +/** + * sep_clear_out - + * @sctx: pointer to struct sep_system_ctx + * Clear out crypto related values in sep device structure + * to enable device to be used by anyone; either kernel + * crypto or userspace app via middleware + */ +static void sep_clear_out(struct sep_system_ctx *sctx) +{ + if (sctx->src_sg_hold) { + sep_free_sg_buf(sctx->src_sg_hold); + sctx->src_sg_hold = NULL; + } + + if (sctx->dst_sg_hold) { + sep_free_sg_buf(sctx->dst_sg_hold); + sctx->dst_sg_hold = NULL; + } + + sctx->src_sg = NULL; + sctx->dst_sg = NULL; + + sep_free_dma_table_data_handler(sctx->sep_used, &sctx->dma_ctx); + + if (sctx->i_own_sep) { + /** + * The following unlocks the sep and makes it available + * to any other application + * First, null out crypto entries in sep before relesing it + */ + sctx->sep_used->current_hash_req = NULL; + sctx->sep_used->current_cypher_req = NULL; + sctx->sep_used->current_request = 0; + sctx->sep_used->current_hash_stage = 0; + sctx->sep_used->sctx = NULL; + sctx->sep_used->in_kernel = 0; + + sctx->call_status.status = 0; + + /* Remove anything confidentail */ + memset(sctx->sep_used->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + sep_queue_status_remove(sctx->sep_used, &sctx->queue_elem); + +#ifdef SEP_ENABLE_RUNTIME_PM + sctx->sep_used->in_use = 0; + pm_runtime_mark_last_busy(&sctx->sep_used->pdev->dev); + pm_runtime_put_autosuspend(&sctx->sep_used->pdev->dev); +#endif + + clear_bit(SEP_WORKING_LOCK_BIT, &sctx->sep_used->in_use_flags); + sctx->sep_used->pid_doing_transaction = 0; + + dev_dbg(&sctx->sep_used->pdev->dev, + "[PID%d] waking up next transaction\n", + current->pid); + + clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sctx->sep_used->in_use_flags); + wake_up(&sctx->sep_used->event_transactions); + + sctx->i_own_sep = 0; + } +} + +/** + * Release crypto infrastructure from EINPROGRESS and + * clear sep_dev so that SEP is available to anyone + */ +static void sep_crypto_release(struct sep_system_ctx *sctx, u32 error) +{ + struct ahash_request *hash_req = sctx->current_hash_req; + struct ablkcipher_request *cypher_req = + sctx->current_cypher_req; + struct sep_device *sep = sctx->sep_used; + + sep_clear_out(sctx); + + if (cypher_req != NULL) { + if (cypher_req->base.complete == NULL) { + dev_dbg(&sep->pdev->dev, + "release is null for cypher!"); + } else { + cypher_req->base.complete( + &cypher_req->base, error); + } + } + + if (hash_req != NULL) { + if (hash_req->base.complete == NULL) { + dev_dbg(&sep->pdev->dev, + "release is null for hash!"); + } else { + hash_req->base.complete( + &hash_req->base, error); + } + } +} + +/** + * This is where we grab the sep itself and tell it to do something. + * It will sleep if the sep is currently busy + * and it will return 0 if sep is now ours; error value if there + * were problems + */ +static int sep_crypto_take_sep(struct sep_system_ctx *sctx) +{ + struct sep_device *sep = sctx->sep_used; + int result; + struct sep_msgarea_hdr *my_msg_header; + + my_msg_header = (struct sep_msgarea_hdr *)sctx->msg; + + /* add to status queue */ + sctx->queue_elem = sep_queue_status_add(sep, my_msg_header->opcode, + sctx->nbytes, current->pid, + current->comm, sizeof(current->comm)); + + if (!sctx->queue_elem) { + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" + " status error\n", current->pid); + return -EINVAL; + } + + /* get the device; this can sleep */ + result = sep_wait_transaction(sep); + if (result) + return result; + + if (sep_dev->power_save_setup == 1) + pm_runtime_get_sync(&sep_dev->pdev->dev); + + /* Copy in the message */ + memcpy(sep->shared_addr, sctx->msg, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* Copy in the dcb information if there is any */ + if (sctx->dcb_region) { + result = sep_activate_dcb_dmatables_context(sep, + &sctx->dcb_region, &sctx->dmatables_region, + sctx->dma_ctx); + if (result) + return result; + } + + /* Mark the device so we know how to finish the job in the tasklet */ + if (sctx->current_hash_req) + sep->current_hash_req = sctx->current_hash_req; + else + sep->current_cypher_req = sctx->current_cypher_req; + + sep->current_request = sctx->current_request; + sep->current_hash_stage = sctx->current_hash_stage; + sep->sctx = sctx; + sep->in_kernel = 1; + sctx->i_own_sep = 1; + + result = sep_send_command_handler(sep); + + dev_dbg(&sep->pdev->dev, "[PID%d]: sending command to the sep\n", + current->pid); + + if (!result) { + set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &sctx->call_status.status); + dev_dbg(&sep->pdev->dev, "[PID%d]: command sent okay\n", + current->pid); + } + + return result; +} + +/* This needs to be run as a work queue as it can be put asleep */ +static void sep_crypto_block(void *data) +{ + int int_error; + u32 msg_offset; + static u32 msg[10]; + void *src_ptr; + void *dst_ptr; + + static char small_buf[100]; + ssize_t copy_result; + int result; + + u32 max_length; + struct scatterlist *new_sg; + struct ablkcipher_request *req; + struct sep_block_ctx *bctx; + struct crypto_ablkcipher *tfm; + struct sep_system_ctx *sctx; + + req = (struct ablkcipher_request *)data; + bctx = ablkcipher_request_ctx(req); + tfm = crypto_ablkcipher_reqtfm(req); + sctx = crypto_ablkcipher_ctx(tfm); + + /* start the walk on scatterlists */ + ablkcipher_walk_init(&bctx->walk, req->src, req->dst, req->nbytes); + dev_dbg(&sctx->sep_used->pdev->dev, "sep crypto block data size of %x\n", + req->nbytes); + + int_error = ablkcipher_walk_phys(req, &bctx->walk); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + int_error); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + /* check iv */ + if (bctx->des_opmode == SEP_DES_CBC) { + if (!bctx->walk.iv) { + dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + memcpy(bctx->iv, bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_DES_IV_SIZE_BYTES); + } + + if (bctx->aes_opmode == SEP_AES_CBC) { + if (!bctx->walk.iv) { + dev_warn(&sctx->sep_used->pdev->dev, "no iv found\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + memcpy(bctx->iv, bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); + sep_dump(sctx->sep_used, "iv", bctx->iv, SEP_AES_IV_SIZE_BYTES); + } + + dev_dbg(&sctx->sep_used->pdev->dev, + "crypto block: src is %lx dst is %lx\n", + (unsigned long)req->src, (unsigned long)req->dst); + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, bctx->walk.blocksize, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, "oddball page eerror\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + int_error = sep_oddball_pages(sctx->sep_used, req->dst, + req->nbytes, bctx->walk.blocksize, &new_sg, 0); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, "walk phys error %x\n", + int_error); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->dst_sg = new_sg; + sctx->dst_sg_hold = new_sg; + } else { + sctx->dst_sg = req->dst; + sctx->dst_sg_hold = NULL; + } + + /* Do we need to perform init; ie; send key to sep? */ + if (sctx->key_sent == 0) { + + dev_dbg(&sctx->sep_used->pdev->dev, "sending key\n"); + + /* put together message to SEP */ + /* Start with op code */ + sep_make_header(sctx, &msg_offset, bctx->init_opcode); + + /* now deal with IV */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + if (bctx->des_opmode == SEP_DES_CBC) { + sep_write_msg(sctx, bctx->iv, + SEP_DES_IV_SIZE_BYTES, sizeof(u32) * 4, + &msg_offset, 1); + sep_dump(sctx->sep_used, "initial IV", + bctx->walk.iv, SEP_DES_IV_SIZE_BYTES); + } else { + /* Skip if ECB */ + msg_offset += 4 * sizeof(u32); + } + } else { + max_length = ((SEP_AES_IV_SIZE_BYTES + 3) / + sizeof(u32)) * sizeof(u32); + if (bctx->aes_opmode == SEP_AES_CBC) { + sep_write_msg(sctx, bctx->iv, + SEP_AES_IV_SIZE_BYTES, max_length, + &msg_offset, 1); + sep_dump(sctx->sep_used, "initial IV", + bctx->walk.iv, SEP_AES_IV_SIZE_BYTES); + } else { + /* Skip if ECB */ + msg_offset += max_length; + } + } + + /* load the key */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_write_msg(sctx, (void *)&sctx->key.des.key1, + sizeof(u32) * 8, sizeof(u32) * 8, + &msg_offset, 1); + + msg[0] = (u32)sctx->des_nbr_keys; + msg[1] = (u32)bctx->des_encmode; + msg[2] = (u32)bctx->des_opmode; + + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + } else { + sep_write_msg(sctx, (void *)&sctx->key.aes, + sctx->keylen, + SEP_AES_MAX_KEY_SIZE_BYTES, + &msg_offset, 1); + + msg[0] = (u32)sctx->aes_key_size; + msg[1] = (u32)bctx->aes_encmode; + msg[2] = (u32)bctx->aes_opmode; + msg[3] = (u32)0; /* Secret key is not used */ + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 4, sizeof(u32) * 4, + &msg_offset, 0); + } + + } else { + + /* set nbytes for queue status */ + sctx->nbytes = req->nbytes; + + /* Key already done; this is for data */ + dev_dbg(&sctx->sep_used->pdev->dev, "sending data\n"); + + sep_dump_sg(sctx->sep_used, + "block sg in", sctx->src_sg); + + /* check for valid data and proper spacing */ + src_ptr = sg_virt(sctx->src_sg); + dst_ptr = sg_virt(sctx->dst_sg); + + if (!src_ptr || !dst_ptr || + (sctx->current_cypher_req->nbytes % + crypto_ablkcipher_blocksize(tfm))) { + + dev_warn(&sctx->sep_used->pdev->dev, + "cipher block size odd\n"); + dev_warn(&sctx->sep_used->pdev->dev, + "cipher block size is %x\n", + crypto_ablkcipher_blocksize(tfm)); + dev_warn(&sctx->sep_used->pdev->dev, + "cipher data size is %x\n", + sctx->current_cypher_req->nbytes); + sep_crypto_release(sctx, -EINVAL); + return; + } + + if (partial_overlap(src_ptr, dst_ptr, + sctx->current_cypher_req->nbytes)) { + dev_warn(&sctx->sep_used->pdev->dev, + "block partial overlap\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Put together the message */ + sep_make_header(sctx, &msg_offset, bctx->block_opcode); + + /* If des, and size is 1 block, put directly in msg */ + if ((bctx->block_opcode == SEP_DES_BLOCK_OPCODE) && + (req->nbytes == crypto_ablkcipher_blocksize(tfm))) { + + dev_dbg(&sctx->sep_used->pdev->dev, + "writing out one block des\n"); + + copy_result = sg_copy_to_buffer( + sctx->src_sg, sep_sg_nents(sctx->src_sg), + small_buf, crypto_ablkcipher_blocksize(tfm)); + + if (copy_result != crypto_ablkcipher_blocksize(tfm)) { + dev_warn(&sctx->sep_used->pdev->dev, + "des block copy faild\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + /* Put data into message */ + sep_write_msg(sctx, small_buf, + crypto_ablkcipher_blocksize(tfm), + crypto_ablkcipher_blocksize(tfm) * 2, + &msg_offset, 1); + + /* Put size into message */ + sep_write_msg(sctx, &req->nbytes, + sizeof(u32), sizeof(u32), &msg_offset, 0); + } else { + /* Otherwise, fill out dma tables */ + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes; + sctx->dcb_input_data.app_out_address = dst_ptr; + sctx->dcb_input_data.block_size = + crypto_ablkcipher_blocksize(tfm); + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = sctx->dst_sg; + + result = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "crypto dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Portion of msg is nulled (no data) */ + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + msg[3] = (u32)0; + msg[4] = (u32)0; + sep_write_msg(sctx, (void *)msg, + sizeof(u32) * 5, + sizeof(u32) * 5, + &msg_offset, 0); + } + + /* Write context into message */ + if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + sep_write_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + sep_dump(sctx->sep_used, "ctx to block des", + &bctx->des_private_ctx, 40); + } else { + sep_write_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); + sep_dump(sctx->sep_used, "ctx to block aes", + &bctx->aes_private_ctx, 20); + } + } + + /* conclude message and then tell sep to do its thing */ + sctx->done_with_transaction = 0; + + sep_end_msg(sctx, msg_offset); + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_crypto_take_sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_crypto_block never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +/** + * Post operation (after interrupt) for crypto block + */ +static u32 crypto_post_op(struct sep_device *sep) +{ + /* HERE */ + int int_error; + u32 u32_error; + u32 msg_offset; + + ssize_t copy_result; + static char small_buf[100]; + + struct ablkcipher_request *req; + struct sep_block_ctx *bctx; + struct sep_system_ctx *sctx; + struct crypto_ablkcipher *tfm; + + if (!sep->current_cypher_req) + return -EINVAL; + + /* hold req since we need to submit work after clearing sep */ + req = sep->current_cypher_req; + + bctx = ablkcipher_request_ctx(sep->current_cypher_req); + tfm = crypto_ablkcipher_reqtfm(sep->current_cypher_req); + sctx = crypto_ablkcipher_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op\n"); + dev_dbg(&sctx->sep_used->pdev->dev, "crypto post_op message dump\n"); + crypto_sep_dump_message(sctx); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* Is this the result of performing init (key to SEP */ + if (sctx->key_sent == 0) { + + /* Did SEP do it okay */ + u32_error = sep_verify_op(sctx, bctx->init_opcode, + &msg_offset); + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "aes init error %x\n", u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + if (bctx->init_opcode == SEP_DES_INIT_OPCODE) { + sep_read_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + + sep_dump(sctx->sep_used, "ctx init des", + &bctx->des_private_ctx, 40); + } else { + sep_read_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_des_private_context)); + + sep_dump(sctx->sep_used, "ctx init aes", + &bctx->aes_private_ctx, 20); + } + + /* We are done with init. Now send out the data */ + /* first release the sep */ + sctx->key_sent = 1; + sep_crypto_release(sctx, -EINPROGRESS); + + spin_lock_irq(&queue_lock); + int_error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((int_error != 0) && (int_error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "spe cypher post op cant queue\n"); + sep_crypto_release(sctx, int_error); + return int_error; + } + + /* schedule the data send */ + int_error = sep_submit_work(sep->workqueue, sep_dequeuer, + (void *)&sep_queue); + + if (int_error) { + dev_warn(&sep->pdev->dev, + "cant submit work sep_crypto_block\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + + } else { + + /** + * This is the result of a block request + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "crypto_post_op block response\n"); + + u32_error = sep_verify_op(sctx, bctx->block_opcode, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep block error %x\n", u32_error); + sep_crypto_release(sctx, u32_error); + return -EINVAL; + } + + if (bctx->block_opcode == SEP_DES_BLOCK_OPCODE) { + + dev_dbg(&sctx->sep_used->pdev->dev, + "post op for DES\n"); + + /* special case for 1 block des */ + if (sep->current_cypher_req->nbytes == + crypto_ablkcipher_blocksize(tfm)) { + + sep_read_msg(sctx, small_buf, + crypto_ablkcipher_blocksize(tfm), + crypto_ablkcipher_blocksize(tfm) * 2, + &msg_offset, 1); + + dev_dbg(&sctx->sep_used->pdev->dev, + "reading in block des\n"); + + copy_result = sg_copy_from_buffer( + sctx->dst_sg, + sep_sg_nents(sctx->dst_sg), + small_buf, + crypto_ablkcipher_blocksize(tfm)); + + if (copy_result != + crypto_ablkcipher_blocksize(tfm)) { + + dev_warn(&sctx->sep_used->pdev->dev, + "des block copy faild\n"); + sep_crypto_release(sctx, -ENOMEM); + return -ENOMEM; + } + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &bctx->des_private_ctx, + sizeof(struct sep_des_private_context)); + } else { + + dev_dbg(&sctx->sep_used->pdev->dev, + "post op for AES\n"); + + /* Skip the MAC Output */ + msg_offset += (sizeof(u32) * 4); + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &bctx->aes_private_ctx, + sizeof(struct sep_aes_private_context)); + } + + sep_dump_sg(sctx->sep_used, + "block sg out", sctx->dst_sg); + + /* Copy to correct sg if this block had oddball pages */ + if (sctx->dst_sg_hold) + sep_copy_sg(sctx->sep_used, + sctx->dst_sg, + sctx->current_cypher_req->dst, + sctx->current_cypher_req->nbytes); + + /* finished, release everything */ + sep_crypto_release(sctx, 0); + } + return 0; +} + +static u32 hash_init_post_op(struct sep_device *sep) +{ + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash init post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_INIT_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, "hash init post op done\n"); + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_update_post_op(struct sep_device *sep) +{ + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_hash_ctx *ctx = ahash_request_ctx(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash update post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_UPDATE_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash init error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Read Context */ + sep_read_context(sctx, &msg_offset, + &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_final_post_op(struct sep_device *sep) +{ + int max_length; + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash final post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_FINISH_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, "hash finish error %x\n", + u32_error); + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Grab the result */ + if (sctx->current_hash_req->result == NULL) { + /* Oops, null buffer; error out here */ + dev_warn(&sctx->sep_used->pdev->dev, + "hash finish null buffer\n"); + sep_crypto_release(sctx, (u32)-ENOMEM); + return -ENOMEM; + } + + max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / + sizeof(u32)) * sizeof(u32); + + sep_read_msg(sctx, + sctx->current_hash_req->result, + crypto_ahash_digestsize(tfm), max_length, + &msg_offset, 0); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, "hash finish post op done\n"); + sep_crypto_release(sctx, 0); + return 0; +} + +static u32 hash_digest_post_op(struct sep_device *sep) +{ + int max_length; + u32 u32_error; + u32 msg_offset; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(sep->current_hash_req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, + "hash digest post op\n"); + + sctx->done_with_transaction = 1; + + /* first bring msg from shared area to local area */ + memcpy(sctx->msg, sep->shared_addr, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + u32_error = sep_verify_op(sctx, SEP_HASH_SINGLE_OPCODE, + &msg_offset); + + if (u32_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash digest finish error %x\n", u32_error); + + sep_crypto_release(sctx, u32_error); + return u32_error; + } + + /* Grab the result */ + if (sctx->current_hash_req->result == NULL) { + /* Oops, null buffer; error out here */ + dev_warn(&sctx->sep_used->pdev->dev, + "hash digest finish null buffer\n"); + sep_crypto_release(sctx, (u32)-ENOMEM); + return -ENOMEM; + } + + max_length = (((SEP_HASH_RESULT_SIZE_WORDS * sizeof(u32)) + 3) / + sizeof(u32)) * sizeof(u32); + + sep_read_msg(sctx, + sctx->current_hash_req->result, + crypto_ahash_digestsize(tfm), max_length, + &msg_offset, 0); + + /* Signal to crypto infrastructure and clear out */ + dev_dbg(&sctx->sep_used->pdev->dev, + "hash digest finish post op done\n"); + + sep_crypto_release(sctx, 0); + return 0; +} + +/** + * The sep_finish function is the function that is schedule (via tasket) + * by the interrupt service routine when the SEP sends and interrupt + * This is only called by the interrupt handler as a tasklet. + */ +static void sep_finish(unsigned long data) +{ + unsigned long flags; + struct sep_device *sep_dev; + int res; + + res = 0; + + if (data == 0) { + pr_debug("sep_finish called with null data\n"); + return; + } + + sep_dev = (struct sep_device *)data; + if (sep_dev == NULL) { + pr_debug("sep_finish; sep_dev is NULL\n"); + return; + } + + spin_lock_irqsave(&sep_dev->busy_lock, flags); + if (sep_dev->in_kernel == (u32)0) { + spin_unlock_irqrestore(&sep_dev->busy_lock, flags); + dev_warn(&sep_dev->pdev->dev, + "sep_finish; not in kernel operation\n"); + return; + } + spin_unlock_irqrestore(&sep_dev->busy_lock, flags); + + /* Did we really do a sep command prior to this? */ + if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &sep_dev->sctx->call_status.status)) { + + dev_warn(&sep_dev->pdev->dev, "[PID%d] sendmsg not called\n", + current->pid); + return; + } + + if (sep_dev->send_ct != sep_dev->reply_ct) { + dev_warn(&sep_dev->pdev->dev, + "[PID%d] poll; no message came back\n", + current->pid); + return; + } + + /* Check for error (In case time ran out) */ + if ((res != 0x0) && (res != 0x8)) { + dev_warn(&sep_dev->pdev->dev, + "[PID%d] poll; poll error GPR3 is %x\n", + current->pid, res); + return; + } + + /* What kind of interrupt from sep was this? */ + res = sep_read_reg(sep_dev, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] GPR2 at crypto finish is %x\n", + current->pid, res); + + /* Print request? */ + if ((res >> 30) & 0x1) { + dev_dbg(&sep_dev->pdev->dev, "[PID%d] sep print req\n", + current->pid); + dev_dbg(&sep_dev->pdev->dev, "[PID%d] contents: %s\n", + current->pid, + (char *)(sep_dev->shared_addr + + SEP_DRIVER_PRINTF_OFFSET_IN_BYTES)); + return; + } + + /* Request for daemon (not currently in POR)? */ + if (res >> 31) { + dev_dbg(&sep_dev->pdev->dev, + "[PID%d] sep request; ignoring\n", + current->pid); + return; + } + + /* If we got here, then we have a replay to a sep command */ + + dev_dbg(&sep_dev->pdev->dev, + "[PID%d] sep reply to command; processing request: %x\n", + current->pid, sep_dev->current_request); + + switch (sep_dev->current_request) { + case AES_CBC: + case AES_ECB: + case DES_CBC: + case DES_ECB: + res = crypto_post_op(sep_dev); + break; + case SHA1: + case MD5: + case SHA224: + case SHA256: + switch (sep_dev->current_hash_stage) { + case HASH_INIT: + res = hash_init_post_op(sep_dev); + break; + case HASH_UPDATE: + res = hash_update_post_op(sep_dev); + break; + case HASH_FINISH: + res = hash_final_post_op(sep_dev); + break; + case HASH_DIGEST: + res = hash_digest_post_op(sep_dev); + break; + default: + dev_warn(&sep_dev->pdev->dev, + "invalid stage for hash finish\n"); + } + break; + default: + dev_warn(&sep_dev->pdev->dev, + "invalid request for finish\n"); + } + + if (res) { + dev_warn(&sep_dev->pdev->dev, + "finish returned error %x\n", res); + } +} + +static int sep_hash_cra_init(struct crypto_tfm *tfm) + { + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(tfm); + + sctx->sep_used = sep_dev; + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_cra_init name is %s\n", alg_name); + + crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), + sizeof(struct sep_hash_ctx)); + return 0; + } + +static void sep_hash_cra_exit(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_cra_exit\n"); + sctx->sep_used = NULL; +} + +static void sep_hash_init(void *data) +{ + u32 msg_offset; + int result; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_init\n"); + sctx->current_hash_stage = HASH_INIT; + /* opcode and mode */ + sep_make_header(sctx, &msg_offset, SEP_HASH_INIT_OPCODE); + sep_write_msg(sctx, &ctx->hash_opmode, + sizeof(u32), sizeof(u32), &msg_offset, 0); + sep_end_msg(sctx, msg_offset); + + sctx->done_with_transaction = 0; + + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_init take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_init never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_update(void *data) +{ + int int_error; + u32 msg_offset; + u32 len; + struct sep_hash_internal_context *int_ctx; + u32 block_size; + u32 head_len; + u32 tail_len; + static u32 msg[10]; + static char small_buf[100]; + void *src_ptr; + struct scatterlist *new_sg; + ssize_t copy_result; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + /* length for queue status */ + sctx->nbytes = req->nbytes; + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_update\n"); + sctx->current_hash_stage = HASH_UPDATE; + len = req->nbytes; + + block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + tail_len = req->nbytes % block_size; + dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", len); + dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + + /* Compute header/tail sizes */ + int_ctx = (struct sep_hash_internal_context *)&ctx-> + hash_private_ctx.internal_context; + head_len = (block_size - int_ctx->prev_update_bytes) % block_size; + tail_len = (req->nbytes - head_len) % block_size; + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, + block_size, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, + "oddball pages error in crash update\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + src_ptr = sg_virt(sctx->src_sg); + + if ((!req->nbytes) || (!ctx->sg)) { + /* null data */ + src_ptr = NULL; + } + + sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes - (head_len + tail_len); + sctx->dcb_input_data.app_out_address = NULL; + sctx->dcb_input_data.block_size = block_size; + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = NULL; + + int_error = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash update dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Construct message to SEP */ + sep_make_header(sctx, &msg_offset, SEP_HASH_UPDATE_OPCODE); + + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + + sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + + /* Handle remainders */ + + /* Head */ + sep_write_msg(sctx, &head_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (head_len) { + copy_result = sg_copy_to_buffer( + req->src, + sep_sg_nents(sctx->src_sg), + small_buf, head_len); + + if (copy_result != head_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg head copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, head_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + /* Tail */ + sep_write_msg(sctx, &tail_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (tail_len) { + copy_result = sep_copy_offset_sg( + sctx->sep_used, + sctx->src_sg, + req->nbytes - tail_len, + small_buf, tail_len); + + if (copy_result != tail_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg tail copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, tail_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + /* Context */ + sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_end_msg(sctx, msg_offset); + sctx->done_with_transaction = 0; + int_error = sep_crypto_take_sep(sctx); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_update take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_update never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_final(void *data) +{ + u32 msg_offset; + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + int result; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_final\n"); + sctx->current_hash_stage = HASH_FINISH; + + /* opcode and mode */ + sep_make_header(sctx, &msg_offset, SEP_HASH_FINISH_OPCODE); + + /* Context */ + sep_write_context(sctx, &msg_offset, &ctx->hash_private_ctx, + sizeof(struct sep_hash_private_context)); + + sep_end_msg(sctx, msg_offset); + sctx->done_with_transaction = 0; + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_final take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_final never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +static void sep_hash_digest(void *data) +{ + int int_error; + u32 msg_offset; + u32 block_size; + u32 msg[10]; + size_t copy_result; + int result; + u32 tail_len; + static char small_buf[100]; + struct scatterlist *new_sg; + void *src_ptr; + + struct ahash_request *req; + struct crypto_ahash *tfm; + struct sep_hash_ctx *ctx; + struct sep_system_ctx *sctx; + + req = (struct ahash_request *)data; + tfm = crypto_ahash_reqtfm(req); + ctx = ahash_request_ctx(req); + sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, + "sep_hash_digest\n"); + sctx->current_hash_stage = HASH_DIGEST; + + /* length for queue status */ + sctx->nbytes = req->nbytes; + + block_size = crypto_tfm_alg_blocksize(crypto_ahash_tfm(tfm)); + tail_len = req->nbytes % block_size; + dev_dbg(&sctx->sep_used->pdev->dev, "length is %x\n", req->nbytes); + dev_dbg(&sctx->sep_used->pdev->dev, "block_size is %x\n", block_size); + dev_dbg(&sctx->sep_used->pdev->dev, "tail len is %x\n", tail_len); + + /* Make sure all pages are even block */ + int_error = sep_oddball_pages(sctx->sep_used, req->src, + req->nbytes, + block_size, &new_sg, 1); + + if (int_error < 0) { + dev_warn(&sctx->sep_used->pdev->dev, + "oddball pages error in crash update\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } else if (int_error == 1) { + sctx->src_sg = new_sg; + sctx->src_sg_hold = new_sg; + } else { + sctx->src_sg = req->src; + sctx->src_sg_hold = NULL; + } + + src_ptr = sg_virt(sctx->src_sg); + + if ((!req->nbytes) || (!ctx->sg)) { + /* null data */ + src_ptr = NULL; + } + + sep_dump_sg(sctx->sep_used, "hash block sg in", sctx->src_sg); + + sctx->dcb_input_data.app_in_address = src_ptr; + sctx->dcb_input_data.data_in_size = req->nbytes - tail_len; + sctx->dcb_input_data.app_out_address = NULL; + sctx->dcb_input_data.block_size = block_size; + sctx->dcb_input_data.tail_block_size = 0; + sctx->dcb_input_data.is_applet = 0; + sctx->dcb_input_data.src_sg = sctx->src_sg; + sctx->dcb_input_data.dst_sg = NULL; + + int_error = sep_create_dcb_dmatables_context_kernel( + sctx->sep_used, + &sctx->dcb_region, + &sctx->dmatables_region, + &sctx->dma_ctx, + &sctx->dcb_input_data, + 1); + if (int_error) { + dev_warn(&sctx->sep_used->pdev->dev, + "hash update dma table create failed\n"); + sep_crypto_release(sctx, -EINVAL); + return; + } + + /* Construct message to SEP */ + sep_make_header(sctx, &msg_offset, SEP_HASH_SINGLE_OPCODE); + sep_write_msg(sctx, &ctx->hash_opmode, + sizeof(u32), sizeof(u32), &msg_offset, 0); + + msg[0] = (u32)0; + msg[1] = (u32)0; + msg[2] = (u32)0; + + sep_write_msg(sctx, msg, sizeof(u32) * 3, sizeof(u32) * 3, + &msg_offset, 0); + + /* Tail */ + sep_write_msg(sctx, &tail_len, sizeof(u32), + sizeof(u32), &msg_offset, 0); + + if (tail_len) { + copy_result = sep_copy_offset_sg( + sctx->sep_used, + sctx->src_sg, + req->nbytes - tail_len, + small_buf, tail_len); + + if (copy_result != tail_len) { + dev_warn(&sctx->sep_used->pdev->dev, + "sg tail copy failure in hash block\n"); + sep_crypto_release(sctx, -ENOMEM); + return; + } + + sep_write_msg(sctx, small_buf, tail_len, + sizeof(u32) * 32, &msg_offset, 1); + } else { + msg_offset += sizeof(u32) * 32; + } + + sep_end_msg(sctx, msg_offset); + + sctx->done_with_transaction = 0; + + result = sep_crypto_take_sep(sctx); + if (result) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_hash_digest take sep failed\n"); + sep_crypto_release(sctx, -EINVAL); + } + + /** + * Sep is now working. Lets wait up to 5 seconds + * for completion. If it does not complete, we will do + * a crypto release with -EINVAL to release the + * kernel crypto infrastructure and let the system + * continue to boot up + * We have to wait this long because some crypto + * operations can take a while + */ + dev_dbg(&sctx->sep_used->pdev->dev, + "waiting for done with transaction\n"); + + sctx->end_time = jiffies + (SEP_TRANSACTION_WAIT_TIME * HZ); + while ((time_before(jiffies, sctx->end_time)) && + (!sctx->done_with_transaction)) + schedule(); + + dev_dbg(&sctx->sep_used->pdev->dev, + "done waiting for done with transaction\n"); + + /* are we done? */ + if (!sctx->done_with_transaction) { + /* Nope, lets release and tell crypto no */ + dev_warn(&sctx->sep_used->pdev->dev, + "[PID%d] sep_hash_digest never finished\n", + current->pid); + sep_crypto_release(sctx, -EINVAL); + } +} + +/** + * This is what is called by each of the API's provided + * in the kernel crypto descriptors. It is run in a process + * context using the kernel workqueues. Therefore it can + * be put to sleep. + */ +static void sep_dequeuer(void *data) +{ + struct crypto_queue *this_queue; + struct crypto_async_request *async_req; + struct crypto_async_request *backlog; + struct ablkcipher_request *cypher_req; + struct ahash_request *hash_req; + struct sep_system_ctx *sctx; + struct crypto_ahash *hash_tfm; + + + this_queue = (struct crypto_queue *)data; + + spin_lock_irq(&queue_lock); + backlog = crypto_get_backlog(this_queue); + async_req = crypto_dequeue_request(this_queue); + spin_unlock_irq(&queue_lock); + + if (!async_req) { + pr_debug("sep crypto queue is empty\n"); + return; + } + + if (backlog) { + pr_debug("sep crypto backlog set\n"); + if (backlog->complete) + backlog->complete(backlog, -EINPROGRESS); + backlog = NULL; + } + + if (!async_req->tfm) { + pr_debug("sep crypto queue null tfm\n"); + return; + } + + if (!async_req->tfm->__crt_alg) { + pr_debug("sep crypto queue null __crt_alg\n"); + return; + } + + if (!async_req->tfm->__crt_alg->cra_type) { + pr_debug("sep crypto queue null cra_type\n"); + return; + } + + /* we have stuff in the queue */ + if (async_req->tfm->__crt_alg->cra_type != + &crypto_ahash_type) { + /* This is for a cypher */ + pr_debug("sep crypto queue doing cipher\n"); + cypher_req = container_of(async_req, + struct ablkcipher_request, + base); + if (!cypher_req) { + pr_debug("sep crypto queue null cypher_req\n"); + return; + } + + sep_crypto_block((void *)cypher_req); + return; + } else { + /* This is a hash */ + pr_debug("sep crypto queue doing hash\n"); + /** + * This is a bit more complex than cipher; we + * need to figure out what type of operation + */ + hash_req = ahash_request_cast(async_req); + if (!hash_req) { + pr_debug("sep crypto queue null hash_req\n"); + return; + } + + hash_tfm = crypto_ahash_reqtfm(hash_req); + if (!hash_tfm) { + pr_debug("sep crypto queue null hash_tfm\n"); + return; + } + + + sctx = crypto_ahash_ctx(hash_tfm); + if (!sctx) { + pr_debug("sep crypto queue null sctx\n"); + return; + } + + if (sctx->current_hash_stage == HASH_INIT) { + pr_debug("sep crypto queue hash init\n"); + sep_hash_init((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_UPDATE) { + pr_debug("sep crypto queue hash update\n"); + sep_hash_update((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_FINISH) { + pr_debug("sep crypto queue hash final\n"); + sep_hash_final((void *)hash_req); + return; + } else if (sctx->current_hash_stage == HASH_DIGEST) { + pr_debug("sep crypto queue hash digest\n"); + sep_hash_digest((void *)hash_req); + return; + } else { + pr_debug("sep crypto queue hash oops nothing\n"); + return; + } + } +} + +static int sep_sha1_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 init\n"); + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha1_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 update\n"); + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha1_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 final\n"); + + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_sha1_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha1 digest\n"); + + sctx->current_request = SHA1; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA1; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha1 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha1 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 init\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 update\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_md5_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 final\n"); + + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; + +} + +static int sep_md5_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing md5 digest\n"); + sctx->current_request = MD5; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_MD5; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep md5 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "md5 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 init\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 update\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha224 final\n"); + + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha224 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha224_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing 224 digest\n"); + sctx->current_request = SHA224; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA224; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha224 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_init(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 init\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_INIT; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 init cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 init cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_update(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 update\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_UPDATE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 update cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 update cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_final(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 final\n"); + + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_FINISH; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 final cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 final cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_sha256_digest(struct ahash_request *req) +{ + int error; + struct crypto_ahash *tfm = crypto_ahash_reqtfm(req); + struct sep_hash_ctx *ctx = ahash_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ahash_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "doing sha256 digest\n"); + sctx->current_request = SHA256; + sctx->current_hash_req = req; + sctx->current_cypher_req = NULL; + ctx->hash_opmode = SEP_HASH_SHA256; + sctx->current_hash_stage = HASH_DIGEST; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep sha256 digest cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sha256 digest cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_crypto_init(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + const char *alg_name = crypto_tfm_alg_name(tfm); + + sctx->sep_used = sep_dev; + + if (alg_name == NULL) + dev_dbg(&sctx->sep_used->pdev->dev, "alg is NULL\n"); + else + dev_dbg(&sctx->sep_used->pdev->dev, "alg is %s\n", alg_name); + + tfm->crt_ablkcipher.reqsize = sizeof(struct sep_block_ctx); + dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_init\n"); + return 0; +} + +static void sep_crypto_exit(struct crypto_tfm *tfm) +{ + struct sep_system_ctx *sctx = crypto_tfm_ctx(tfm); + dev_dbg(&sctx->sep_used->pdev->dev, "sep_crypto_exit\n"); + sctx->sep_used = NULL; +} + +static int sep_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes setkey\n"); + + switch (keylen) { + case SEP_AES_KEY_128_SIZE: + sctx->aes_key_size = AES_128; + break; + case SEP_AES_KEY_192_SIZE: + sctx->aes_key_size = AES_192; + break; + case SEP_AES_KEY_256_SIZE: + sctx->aes_key_size = AES_256; + break; + case SEP_AES_KEY_512_SIZE: + sctx->aes_key_size = AES_512; + break; + default: + dev_warn(&sctx->sep_used->pdev->dev, "sep aes key size %x\n", + keylen); + return -EINVAL; + } + + memset(&sctx->key.aes, 0, sizeof(u32) * + SEP_AES_MAX_KEY_SIZE_WORDS); + memcpy(&sctx->key.aes, key, keylen); + sctx->keylen = keylen; + /* Indicate to encrypt/decrypt function to send key to SEP */ + sctx->key_sent = 0; + sctx->last_block = 0; + + return 0; +} + +static int sep_aes_ecb_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb encrypt\n"); + sctx->current_request = AES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_ENCRYPT; + bctx->aes_opmode = SEP_AES_ECB; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_ecb_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes ecb decrypt\n"); + sctx->current_request = AES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_DECRYPT; + bctx->aes_opmode = SEP_AES_ECB; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_ecb_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_cbc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc encrypt\n"); + sctx->current_request = AES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_ENCRYPT; + bctx->aes_opmode = SEP_AES_CBC; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_aes_cbc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep aes cbc decrypt\n"); + sctx->current_request = AES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->aes_encmode = SEP_AES_DECRYPT; + bctx->aes_opmode = SEP_AES_CBC; + bctx->init_opcode = SEP_AES_INIT_OPCODE; + bctx->block_opcode = SEP_AES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_aes_cbc_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_setkey(struct crypto_ablkcipher *tfm, const u8 *key, + unsigned int keylen) +{ + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx(tfm); + struct crypto_tfm *ctfm = crypto_ablkcipher_tfm(tfm); + u32 *flags = &ctfm->crt_flags; + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des setkey\n"); + + switch (keylen) { + case DES_KEY_SIZE: + sctx->des_nbr_keys = DES_KEY_1; + break; + case DES_KEY_SIZE * 2: + sctx->des_nbr_keys = DES_KEY_2; + break; + case DES_KEY_SIZE * 3: + sctx->des_nbr_keys = DES_KEY_3; + break; + default: + dev_dbg(&sctx->sep_used->pdev->dev, "invalid key size %x\n", + keylen); + return -EINVAL; + } + + if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) && + (sep_weak_key(key, keylen))) { + + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + dev_warn(&sctx->sep_used->pdev->dev, "weak key\n"); + return -EINVAL; + } + + memset(&sctx->key.des, 0, sizeof(struct sep_des_key)); + memcpy(&sctx->key.des.key1, key, keylen); + sctx->keylen = keylen; + /* Indicate to encrypt/decrypt function to send key to SEP */ + sctx->key_sent = 0; + sctx->last_block = 0; + + return 0; +} + +static int sep_des_ebc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb encrypt\n"); + sctx->current_request = DES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_ENCRYPT; + bctx->des_opmode = SEP_DES_ECB; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_ebc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des ecb decrypt\n"); + sctx->current_request = DES_ECB; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_DECRYPT; + bctx->des_opmode = SEP_DES_ECB; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_ecb_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_cbc_encrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc encrypt\n"); + sctx->current_request = DES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_ENCRYPT; + bctx->des_opmode = SEP_DES_CBC; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_encrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_encrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static int sep_des_cbc_decrypt(struct ablkcipher_request *req) +{ + int error; + struct sep_block_ctx *bctx = ablkcipher_request_ctx(req); + struct sep_system_ctx *sctx = crypto_ablkcipher_ctx( + crypto_ablkcipher_reqtfm(req)); + + dev_dbg(&sctx->sep_used->pdev->dev, "sep des cbc decrypt\n"); + sctx->current_request = DES_CBC; + sctx->current_hash_req = NULL; + sctx->current_cypher_req = req; + bctx->des_encmode = SEP_DES_DECRYPT; + bctx->des_opmode = SEP_DES_CBC; + bctx->init_opcode = SEP_DES_INIT_OPCODE; + bctx->block_opcode = SEP_DES_BLOCK_OPCODE; + + spin_lock_irq(&queue_lock); + error = crypto_enqueue_request(&sep_queue, &req->base); + spin_unlock_irq(&queue_lock); + + if ((error != 0) && (error != -EINPROGRESS)) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_decrypt cant enqueue\n"); + sep_crypto_release(sctx, error); + return error; + } + + error = sep_submit_work(sctx->sep_used->workqueue, sep_dequeuer, + (void *)&sep_queue); + if (error) { + dev_warn(&sctx->sep_used->pdev->dev, + "sep_des_cbc_decrypt cannot submit queue\n"); + sep_crypto_release(sctx, -EINVAL); + return -EINVAL; + } + return -EINPROGRESS; +} + +static struct ahash_alg hash_algs[] = { +{ + .init = sep_sha1_init, + .update = sep_sha1_update, + .final = sep_sha1_final, + .digest = sep_sha1_digest, + .halg = { + .digestsize = SHA1_DIGEST_SIZE, + .base = { + .cra_name = "sha1", + .cra_driver_name = "sha1-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_md5_init, + .update = sep_md5_update, + .final = sep_md5_final, + .digest = sep_md5_digest, + .halg = { + .digestsize = MD5_DIGEST_SIZE, + .base = { + .cra_name = "md5", + .cra_driver_name = "md5-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA1_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_sha224_init, + .update = sep_sha224_update, + .final = sep_sha224_final, + .digest = sep_sha224_digest, + .halg = { + .digestsize = SHA224_DIGEST_SIZE, + .base = { + .cra_name = "sha224", + .cra_driver_name = "sha224-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA224_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +}, +{ + .init = sep_sha256_init, + .update = sep_sha256_update, + .final = sep_sha256_final, + .digest = sep_sha256_digest, + .halg = { + .digestsize = SHA256_DIGEST_SIZE, + .base = { + .cra_name = "sha256", + .cra_driver_name = "sha256-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_AHASH | + CRYPTO_ALG_ASYNC, + .cra_blocksize = SHA256_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_module = THIS_MODULE, + .cra_init = sep_hash_cra_init, + .cra_exit = sep_hash_cra_exit, + } + } +} +}; + +static struct crypto_alg crypto_algs[] = { +{ + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = sep_aes_setkey, + .encrypt = sep_aes_ecb_encrypt, + .decrypt = sep_aes_ecb_decrypt, + } +}, +{ + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = AES_MIN_KEY_SIZE, + .max_keysize = AES_MAX_KEY_SIZE, + .setkey = sep_aes_setkey, + .encrypt = sep_aes_cbc_encrypt, + .decrypt = sep_aes_cbc_decrypt, + } +}, +{ + .cra_name = "ebc(des)", + .cra_driver_name = "ebc-des-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_ebc_encrypt, + .decrypt = sep_des_ebc_decrypt, + } +}, +{ + .cra_name = "cbc(des)", + .cra_driver_name = "cbc-des-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES_KEY_SIZE, + .max_keysize = DES_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_cbc_encrypt, + .decrypt = sep_des_cbc_decrypt, + } +}, +{ + .cra_name = "ebc(des3-ede)", + .cra_driver_name = "ebc-des3-ede-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_ebc_encrypt, + .decrypt = sep_des_ebc_decrypt, + } +}, +{ + .cra_name = "cbc(des3-ede)", + .cra_driver_name = "cbc-des3--ede-sep", + .cra_priority = 100, + .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, + .cra_blocksize = DES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct sep_system_ctx), + .cra_alignmask = 0, + .cra_type = &crypto_ablkcipher_type, + .cra_module = THIS_MODULE, + .cra_init = sep_crypto_init, + .cra_exit = sep_crypto_exit, + .cra_u.ablkcipher = { + .min_keysize = DES3_EDE_KEY_SIZE, + .max_keysize = DES3_EDE_KEY_SIZE, + .setkey = sep_des_setkey, + .encrypt = sep_des_cbc_encrypt, + .decrypt = sep_des_cbc_decrypt, + } +} +}; + +int sep_crypto_setup(void) +{ + int err, i, j, k; + tasklet_init(&sep_dev->finish_tasklet, sep_finish, + (unsigned long)sep_dev); + + crypto_init_queue(&sep_queue, SEP_QUEUE_LENGTH); + + sep_dev->workqueue = create_workqueue("sep_crypto_workqueue"); + if (!sep_dev->workqueue) { + dev_warn(&sep_dev->pdev->dev, "cant create workqueue\n"); + return -ENOMEM; + } + + i = 0; + j = 0; + + spin_lock_init(&sep_dev->busy_lock); + spin_lock_init(&queue_lock); + + err = 0; + + for (i = 0; i < ARRAY_SIZE(hash_algs); i++) { + err = crypto_register_ahash(&hash_algs[i]); + if (err) + goto err_algs; + } + + err = 0; + for (j = 0; j < ARRAY_SIZE(crypto_algs); j++) { + err = crypto_register_alg(&crypto_algs[j]); + if (err) + goto err_crypto_algs; + } + + return err; + +err_algs: + for (k = 0; k < i; k++) + crypto_unregister_ahash(&hash_algs[k]); + return err; + +err_crypto_algs: + for (k = 0; k < j; k++) + crypto_unregister_alg(&crypto_algs[k]); + goto err_algs; +} + +void sep_crypto_takedown(void) +{ + + int i; + + for (i = 0; i < ARRAY_SIZE(hash_algs); i++) + crypto_unregister_ahash(&hash_algs[i]); + for (i = 0; i < ARRAY_SIZE(crypto_algs); i++) + crypto_unregister_alg(&crypto_algs[i]); + + tasklet_kill(&sep_dev->finish_tasklet); +} diff --git a/drivers/staging/sep/sep_crypto.h b/drivers/staging/sep/sep_crypto.h new file mode 100644 index 00000000000..52c58c483c5 --- /dev/null +++ b/drivers/staging/sep/sep_crypto.h @@ -0,0 +1,348 @@ +/* + * + * sep_crypto.h - Crypto interface structures + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2010 Discretix. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2011.02.22 Enable Kernel Crypto + * + */ + +/* Constants for SEP (from vendor) */ +#define SEP_START_MSG_TOKEN 0x02558808 + +#define SEP_DES_IV_SIZE_WORDS 2 +#define SEP_DES_IV_SIZE_BYTES (SEP_DES_IV_SIZE_WORDS * \ + sizeof(u32)) +#define SEP_DES_KEY_SIZE_WORDS 2 +#define SEP_DES_KEY_SIZE_BYTES (SEP_DES_KEY_SIZE_WORDS * \ + sizeof(u32)) +#define SEP_DES_BLOCK_SIZE 8 +#define SEP_DES_DUMMY_SIZE 16 + +#define SEP_DES_INIT_OPCODE 0x10 +#define SEP_DES_BLOCK_OPCODE 0x11 + +#define SEP_AES_BLOCK_SIZE_WORDS 4 +#define SEP_AES_BLOCK_SIZE_BYTES \ + (SEP_AES_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_DUMMY_BLOCK_SIZE 16 +#define SEP_AES_IV_SIZE_WORDS SEP_AES_BLOCK_SIZE_WORDS +#define SEP_AES_IV_SIZE_BYTES \ + (SEP_AES_IV_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_KEY_128_SIZE 16 +#define SEP_AES_KEY_192_SIZE 24 +#define SEP_AES_KEY_256_SIZE 32 +#define SEP_AES_KEY_512_SIZE 64 +#define SEP_AES_MAX_KEY_SIZE_WORDS 16 +#define SEP_AES_MAX_KEY_SIZE_BYTES \ + (SEP_AES_MAX_KEY_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_WRAP_MIN_SIZE 8 +#define SEP_AES_WRAP_MAX_SIZE 0x10000000 + +#define SEP_AES_WRAP_BLOCK_SIZE_WORDS 2 +#define SEP_AES_WRAP_BLOCK_SIZE_BYTES \ + (SEP_AES_WRAP_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_AES_SECRET_RKEK1 0x1 +#define SEP_AES_SECRET_RKEK2 0x2 + +#define SEP_AES_INIT_OPCODE 0x2 +#define SEP_AES_BLOCK_OPCODE 0x3 +#define SEP_AES_FINISH_OPCODE 0x4 +#define SEP_AES_WRAP_OPCODE 0x6 +#define SEP_AES_UNWRAP_OPCODE 0x7 +#define SEP_AES_XTS_FINISH_OPCODE 0x8 + +#define SEP_HASH_RESULT_SIZE_WORDS 16 +#define SEP_MD5_DIGEST_SIZE_WORDS 4 +#define SEP_MD5_DIGEST_SIZE_BYTES \ + (SEP_MD5_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA1_DIGEST_SIZE_WORDS 5 +#define SEP_SHA1_DIGEST_SIZE_BYTES \ + (SEP_SHA1_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA224_DIGEST_SIZE_WORDS 7 +#define SEP_SHA224_DIGEST_SIZE_BYTES \ + (SEP_SHA224_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA256_DIGEST_SIZE_WORDS 8 +#define SEP_SHA256_DIGEST_SIZE_BYTES \ + (SEP_SHA256_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA384_DIGEST_SIZE_WORDS 12 +#define SEP_SHA384_DIGEST_SIZE_BYTES \ + (SEP_SHA384_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA512_DIGEST_SIZE_WORDS 16 +#define SEP_SHA512_DIGEST_SIZE_BYTES \ + (SEP_SHA512_DIGEST_SIZE_WORDS * sizeof(u32)) +#define SEP_HASH_BLOCK_SIZE_WORDS 16 +#define SEP_HASH_BLOCK_SIZE_BYTES \ + (SEP_HASH_BLOCK_SIZE_WORDS * sizeof(u32)) +#define SEP_SHA2_BLOCK_SIZE_WORDS 32 +#define SEP_SHA2_BLOCK_SIZE_BYTES \ + (SEP_SHA2_BLOCK_SIZE_WORDS * sizeof(u32)) + +#define SEP_HASH_INIT_OPCODE 0x20 +#define SEP_HASH_UPDATE_OPCODE 0x21 +#define SEP_HASH_FINISH_OPCODE 0x22 +#define SEP_HASH_SINGLE_OPCODE 0x23 + +#define SEP_HOST_ERROR 0x0b000000 +#define SEP_OK 0x0 +#define SEP_INVALID_START (SEP_HOST_ERROR + 0x3) +#define SEP_WRONG_OPCODE (SEP_HOST_ERROR + 0x1) + +#define SEP_TRANSACTION_WAIT_TIME 5 + +#define SEP_QUEUE_LENGTH 10 +/* Macros */ +#ifndef __LITTLE_ENDIAN +#define CHG_ENDIAN(val) \ + (((val) >> 24) | \ + (((val) & 0x00FF0000) >> 8) | \ + (((val) & 0x0000FF00) << 8) | \ + (((val) & 0x000000FF) << 24)) +#else +#define CHG_ENDIAN(val) val +#endif +/* Enums for SEP (from vendor) */ +enum des_numkey { + DES_KEY_1 = 1, + DES_KEY_2 = 2, + DES_KEY_3 = 3, + SEP_NUMKEY_OPTIONS, + SEP_NUMKEY_LAST = 0x7fffffff, +}; + +enum des_enc_mode { + SEP_DES_ENCRYPT = 0, + SEP_DES_DECRYPT = 1, + SEP_DES_ENC_OPTIONS, + SEP_DES_ENC_LAST = 0x7fffffff, +}; + +enum des_op_mode { + SEP_DES_ECB = 0, + SEP_DES_CBC = 1, + SEP_OP_OPTIONS, + SEP_OP_LAST = 0x7fffffff, +}; + +enum aes_keysize { + AES_128 = 0, + AES_192 = 1, + AES_256 = 2, + AES_512 = 3, + AES_SIZE_OPTIONS, + AEA_SIZE_LAST = 0x7FFFFFFF, +}; + +enum aes_enc_mode { + SEP_AES_ENCRYPT = 0, + SEP_AES_DECRYPT = 1, + SEP_AES_ENC_OPTIONS, + SEP_AES_ENC_LAST = 0x7FFFFFFF, +}; + +enum aes_op_mode { + SEP_AES_ECB = 0, + SEP_AES_CBC = 1, + SEP_AES_MAC = 2, + SEP_AES_CTR = 3, + SEP_AES_XCBC = 4, + SEP_AES_CMAC = 5, + SEP_AES_XTS = 6, + SEP_AES_OP_OPTIONS, + SEP_AES_OP_LAST = 0x7FFFFFFF, +}; + +enum hash_op_mode { + SEP_HASH_SHA1 = 0, + SEP_HASH_SHA224 = 1, + SEP_HASH_SHA256 = 2, + SEP_HASH_SHA384 = 3, + SEP_HASH_SHA512 = 4, + SEP_HASH_MD5 = 5, + SEP_HASH_OPTIONS, + SEP_HASH_LAST_MODE = 0x7FFFFFFF, +}; + +/* Structures for SEP (from vendor) */ +struct sep_des_internal_key { + u32 key1[SEP_DES_KEY_SIZE_WORDS]; + u32 key2[SEP_DES_KEY_SIZE_WORDS]; + u32 key3[SEP_DES_KEY_SIZE_WORDS]; +}; + +struct sep_des_internal_context { + u32 iv_context[SEP_DES_IV_SIZE_WORDS]; + struct sep_des_internal_key context_key; + enum des_numkey nbr_keys; + enum des_enc_mode encryption; + enum des_op_mode operation; + u8 dummy_block[SEP_DES_DUMMY_SIZE]; +}; + +struct sep_des_private_context { + u32 valid_tag; + u32 iv; + u8 ctx_buf[sizeof(struct sep_des_internal_context)]; +}; + +/* This is the structure passed to SEP via msg area */ +struct sep_des_key { + u32 key1[SEP_DES_KEY_SIZE_WORDS]; + u32 key2[SEP_DES_KEY_SIZE_WORDS]; + u32 key3[SEP_DES_KEY_SIZE_WORDS]; + u32 pad[SEP_DES_KEY_SIZE_WORDS]; +}; + +struct sep_aes_internal_context { + u32 aes_ctx_iv[SEP_AES_IV_SIZE_WORDS]; + u32 aes_ctx_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2]; + enum aes_keysize keysize; + enum aes_enc_mode encmode; + enum aes_op_mode opmode; + u8 secret_key; + u32 no_add_blocks; + u32 last_block_size; + u32 last_block[SEP_AES_BLOCK_SIZE_WORDS]; + u32 prev_iv[SEP_AES_BLOCK_SIZE_WORDS]; + u32 remaining_size; + union { + struct { + u32 dkey1[SEP_AES_BLOCK_SIZE_WORDS]; + u32 dkey2[SEP_AES_BLOCK_SIZE_WORDS]; + u32 dkey3[SEP_AES_BLOCK_SIZE_WORDS]; + } cmac_data; + struct { + u32 xts_key[SEP_AES_MAX_KEY_SIZE_WORDS / 2]; + u32 temp1[SEP_AES_BLOCK_SIZE_WORDS]; + u32 temp2[SEP_AES_BLOCK_SIZE_WORDS]; + } xtx_data; + } s_data; + u8 dummy_block[SEP_AES_DUMMY_BLOCK_SIZE]; +}; + +struct sep_aes_private_context { + u32 valid_tag; + u32 aes_iv; + u32 op_mode; + u8 cbuff[sizeof(struct sep_aes_internal_context)]; +}; + +struct sep_hash_internal_context { + u32 hash_result[SEP_HASH_RESULT_SIZE_WORDS]; + enum hash_op_mode hash_opmode; + u32 previous_data[SEP_SHA2_BLOCK_SIZE_WORDS]; + u16 prev_update_bytes; + u32 total_proc_128bit[4]; + u16 op_mode_block_size; + u8 dummy_aes_block[SEP_AES_DUMMY_BLOCK_SIZE]; +}; + +struct sep_hash_private_context { + u32 valid_tag; + u32 iv; + u8 internal_context[sizeof(struct sep_hash_internal_context)]; +}; + +/* Context structures for crypto API */ +struct sep_block_ctx { + struct sep_device *sep; + u32 done; + unsigned char iv[100]; + enum des_enc_mode des_encmode; + enum des_op_mode des_opmode; + enum aes_enc_mode aes_encmode; + enum aes_op_mode aes_opmode; + u32 init_opcode; + u32 block_opcode; + size_t data_length; + size_t ivlen; + struct ablkcipher_walk walk; + struct sep_des_private_context des_private_ctx; + struct sep_aes_private_context aes_private_ctx; + }; + +struct sep_hash_ctx { + u32 done; + unsigned char *buf; + size_t buflen; + unsigned char *dgst; + int digest_size_words; + int digest_size_bytes; + int block_size_words; + int block_size_bytes; + struct scatterlist *sg; + enum hash_op_mode hash_opmode; + struct sep_hash_private_context hash_private_ctx; + }; + +struct sep_system_ctx { + struct sep_device *sep_used; + union key_t { + struct sep_des_key des; + u32 aes[SEP_AES_MAX_KEY_SIZE_WORDS]; + } key; + int i_own_sep; /* Do I have custody of the sep? */ + size_t keylen; + enum des_numkey des_nbr_keys; + enum aes_keysize aes_key_size; + u32 key_sent; /* Indicate if key is sent to sep */ + u32 last_block; /* Indicate that this is the final block */ + struct sep_call_status call_status; + struct build_dcb_struct_kernel dcb_input_data; + struct sep_dma_context *dma_ctx; + void *dmatables_region; + size_t nbytes; + struct sep_dcblock *dcb_region; + struct sep_queue_info *queue_elem; + int msg_len_words; + unsigned char msg[SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES]; + void *msgptr; + struct scatterlist *src_sg; + struct scatterlist *dst_sg; + struct scatterlist *src_sg_hold; + struct scatterlist *dst_sg_hold; + struct ahash_request *current_hash_req; + struct ablkcipher_request *current_cypher_req; + enum type_of_request current_request; + enum hash_stage current_hash_stage; + int done_with_transaction; + unsigned long end_time; + }; + +/* work queue structures */ +struct sep_work_struct { + struct work_struct work; + void (*callback)(void *); + void *data; + }; + +/* Functions */ +int sep_crypto_setup(void); +void sep_crypto_takedown(void); diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index 696ab0dd2b7..66d8e95523b 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -5,8 +5,8 @@ * * sep_dev.h - Security Processor Device Structures * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -28,6 +28,7 @@ * * CHANGES * 2010.09.14 upgrade to Medfield + * 2011.02.22 enable kernel crypto */ struct sep_device { @@ -36,33 +37,21 @@ struct sep_device { /* character device file */ struct cdev sep_cdev; - struct cdev sep_daemon_cdev; - struct cdev sep_singleton_cdev; /* devices (using misc dev) */ struct miscdevice miscdev_sep; - struct miscdevice miscdev_singleton; - struct miscdevice miscdev_daemon; /* major / minor numbers of device */ dev_t sep_devno; - dev_t sep_daemon_devno; - dev_t sep_singleton_devno; - - struct mutex sep_mutex; - struct mutex ioctl_mutex; + /* guards command sent counter */ spinlock_t snd_rply_lck; + /* guards driver memory usage in fastcall if */ + struct semaphore sep_doublebuf; /* flags to indicate use and lock status of sep */ u32 pid_doing_transaction; unsigned long in_use_flags; - /* request daemon alread open */ - unsigned long request_daemon_open; - - /* 1 = Moorestown; 0 = Medfield */ - int mrst; - /* address of the shared memory allocated during init for SEP driver (coherent alloc) */ dma_addr_t shared_bus; @@ -74,36 +63,78 @@ struct sep_device { dma_addr_t reg_physical_end; void __iomem *reg_addr; - /* wait queue head (event) of the driver */ - wait_queue_head_t event; - wait_queue_head_t event_request_daemon; - wait_queue_head_t event_mmap; + /* wait queue heads of the driver */ + wait_queue_head_t event_interrupt; + wait_queue_head_t event_transactions; - struct sep_caller_id_entry - caller_id_table[SEP_CALLER_ID_TABLE_NUM_ENTRIES]; + struct list_head sep_queue_status; + u32 sep_queue_num; + spinlock_t sep_queue_lock; - /* access flag for singleton device */ - unsigned long singleton_access_flag; + /* Is this in use? */ + u32 in_use; + + /* indicates whether power save is set up */ + u32 power_save_setup; + + /* Power state */ + u32 power_state; /* transaction counter that coordinates the transactions between SEP and HOST */ unsigned long send_ct; /* counter for the messages from sep */ unsigned long reply_ct; - /* counter for the number of bytes allocated in the pool for the - current transaction */ - long data_pool_bytes_allocated; - u32 num_of_data_allocations; + /* The following are used for kernel crypto client requests */ + u32 in_kernel; /* Set for kernel client request */ + struct tasklet_struct finish_tasklet; + enum type_of_request current_request; + enum hash_stage current_hash_stage; + struct ahash_request *current_hash_req; + struct ablkcipher_request *current_cypher_req; + struct sep_system_ctx *sctx; + spinlock_t busy_lock; + struct workqueue_struct *workqueue; +}; - /* number of the lli tables created in the current transaction */ - u32 num_lli_tables_created; +extern struct sep_device *sep_dev; - /* number of data control blocks */ - u32 nr_dcb_creat; +/** + * SEP message header for a transaction + * @reserved: reserved memory (two words) + * @token: SEP message token + * @msg_len: message length + * @opcpde: message opcode + */ +struct sep_msgarea_hdr { + u32 reserved[2]; + u32 token; + u32 msg_len; + u32 opcode; +}; - struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; +/** + * sep_queue_data - data to be maintained in status queue for a transaction + * @opcode : transaction opcode + * @size : message size + * @pid: owner process + * @name: owner process name + */ +struct sep_queue_data { + u32 opcode; + u32 size; + s32 pid; + u8 name[TASK_COMM_LEN]; +}; +/** sep_queue_info - maintains status info of all transactions + * @list: head of list + * @sep_queue_data : data for transaction + */ +struct sep_queue_info { + struct list_head list; + struct sep_queue_data data; }; static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c deleted file mode 100644 index 6b3d156d414..00000000000 --- a/drivers/staging/sep/sep_driver.c +++ /dev/null @@ -1,2932 +0,0 @@ -/* - * - * sep_driver.c - Security Processor Driver main group of functions - * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 - * Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * CONTACTS: - * - * Mark Allyn mark.a.allyn@intel.com - * Jayant Mangalampalli jayant.mangalampalli@intel.com - * - * CHANGES: - * - * 2009.06.26 Initial publish - * 2010.09.14 Upgrade to Medfield - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sep_driver_hw_defs.h" -#include "sep_driver_config.h" -#include "sep_driver_api.h" -#include "sep_dev.h" - -/*---------------------------------------- - DEFINES ------------------------------------------*/ - -#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 - -/*-------------------------------------------- - GLOBAL variables ---------------------------------------------*/ - -/* Keep this a single static object for now to keep the conversion easy */ - -static struct sep_device *sep_dev; - -/** - * sep_dump_message - dump the message that is pending - * @sep: SEP device - */ -static void sep_dump_message(struct sep_device *sep) -{ - int count; - u32 *p = sep->shared_addr; - for (count = 0; count < 12 * 4; count += 4) - dev_dbg(&sep->pdev->dev, "Word %d of the message is %x\n", - count, *p++); -} - -/** - * sep_map_and_alloc_shared_area - allocate shared block - * @sep: security processor - * @size: size of shared area - */ -static int sep_map_and_alloc_shared_area(struct sep_device *sep) -{ - sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, - sep->shared_size, - &sep->shared_bus, GFP_KERNEL); - - if (!sep->shared_addr) { - dev_warn(&sep->pdev->dev, - "shared memory dma_alloc_coherent failed\n"); - return -ENOMEM; - } - dev_dbg(&sep->pdev->dev, - "shared_addr %zx bytes @%p (bus %llx)\n", - sep->shared_size, sep->shared_addr, - (unsigned long long)sep->shared_bus); - return 0; -} - -/** - * sep_unmap_and_free_shared_area - free shared block - * @sep: security processor - */ -static void sep_unmap_and_free_shared_area(struct sep_device *sep) -{ - dma_free_coherent(&sep->pdev->dev, sep->shared_size, - sep->shared_addr, sep->shared_bus); -} - -/** - * sep_shared_bus_to_virt - convert bus/virt addresses - * @sep: pointer to struct sep_device - * @bus_address: address to convert - * - * Returns virtual address inside the shared area according - * to the bus address. - */ -static void *sep_shared_bus_to_virt(struct sep_device *sep, - dma_addr_t bus_address) -{ - return sep->shared_addr + (bus_address - sep->shared_bus); -} - -/** - * open function for the singleton driver - * @inode_ptr struct inode * - * @file_ptr struct file * - * - * Called when the user opens the singleton device interface - */ -static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) -{ - struct sep_device *sep; - - /* - * Get the SEP device structure and use it for the - * private_data field in filp for other methods - */ - sep = sep_dev; - - file_ptr->private_data = sep; - - if (test_and_set_bit(0, &sep->singleton_access_flag)) - return -EBUSY; - return 0; -} - -/** - * sep_open - device open method - * @inode: inode of SEP device - * @filp: file handle to SEP device - * - * Open method for the SEP device. Called when userspace opens - * the SEP device node. - * - * Returns zero on success otherwise an error code. - */ -static int sep_open(struct inode *inode, struct file *filp) -{ - struct sep_device *sep; - - /* - * Get the SEP device structure and use it for the - * private_data field in filp for other methods - */ - sep = sep_dev; - filp->private_data = sep; - - /* Anyone can open; locking takes place at transaction level */ - return 0; -} - -/** - * sep_singleton_release - close a SEP singleton device - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP device. As the open protects against - * multiple simultaenous opens that means this method is called when the - * final reference to the open handle is dropped. - */ -static int sep_singleton_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - clear_bit(0, &sep->singleton_access_flag); - return 0; -} - -/** - * sep_request_daemon_open - request daemon open method - * @inode: inode of SEP device - * @filp: file handle to SEP device - * - * Open method for the SEP request daemon. Called when - * request daemon in userspace opens the SEP device node. - * - * Returns zero on success otherwise an error code. - */ -static int sep_request_daemon_open(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = sep_dev; - int error = 0; - - filp->private_data = sep; - - /* There is supposed to be only one request daemon */ - if (test_and_set_bit(0, &sep->request_daemon_open)) - error = -EBUSY; - return error; -} - -/** - * sep_request_daemon_release - close a SEP daemon - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP daemon. - */ -static int sep_request_daemon_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - dev_dbg(&sep->pdev->dev, "Request daemon release for pid %d\n", - current->pid); - - /* Clear the request_daemon_open flag */ - clear_bit(0, &sep->request_daemon_open); - return 0; -} - -/** - * sep_req_daemon_send_reply_command_handler - poke the SEP - * @sep: struct sep_device * - * - * This function raises interrupt to SEPm that signals that is has a - * new command from HOST - */ -static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) -{ - unsigned long lck_flags; - - sep_dump_message(sep); - - /* Counters are lockable region */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->send_ct++; - sep->reply_ct++; - - /* Send the interrupt to SEP */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); - sep->send_ct++; - - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, - "sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - return 0; -} - - -/** - * sep_free_dma_table_data_handler - free DMA table - * @sep: pointere to struct sep_device - * - * Handles the request to free DMA table for synchronic actions - */ -static int sep_free_dma_table_data_handler(struct sep_device *sep) -{ - int count; - int dcb_counter; - /* Pointer to the current dma_resource struct */ - struct sep_dma_resource *dma; - - for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) { - dma = &sep->dma_res_arr[dcb_counter]; - - /* Unmap and free input map array */ - if (dma->in_map_array) { - for (count = 0; count < dma->in_num_pages; count++) { - dma_unmap_page(&sep->pdev->dev, - dma->in_map_array[count].dma_addr, - dma->in_map_array[count].size, - DMA_TO_DEVICE); - } - kfree(dma->in_map_array); - } - - /* Unmap output map array, DON'T free it yet */ - if (dma->out_map_array) { - for (count = 0; count < dma->out_num_pages; count++) { - dma_unmap_page(&sep->pdev->dev, - dma->out_map_array[count].dma_addr, - dma->out_map_array[count].size, - DMA_FROM_DEVICE); - } - kfree(dma->out_map_array); - } - - /* Free page cache for output */ - if (dma->in_page_array) { - for (count = 0; count < dma->in_num_pages; count++) { - flush_dcache_page(dma->in_page_array[count]); - page_cache_release(dma->in_page_array[count]); - } - kfree(dma->in_page_array); - } - - if (dma->out_page_array) { - for (count = 0; count < dma->out_num_pages; count++) { - if (!PageReserved(dma->out_page_array[count])) - SetPageDirty(dma->out_page_array[count]); - flush_dcache_page(dma->out_page_array[count]); - page_cache_release(dma->out_page_array[count]); - } - kfree(dma->out_page_array); - } - - /* Reset all the values */ - dma->in_page_array = NULL; - dma->out_page_array = NULL; - dma->in_num_pages = 0; - dma->out_num_pages = 0; - dma->in_map_array = NULL; - dma->out_map_array = NULL; - dma->in_map_num_entries = 0; - dma->out_map_num_entries = 0; - } - - sep->nr_dcb_creat = 0; - sep->num_lli_tables_created = 0; - - return 0; -} - -/** - * sep_request_daemon_mmap - maps the shared area to user space - * @filp: pointer to struct file - * @vma: pointer to vm_area_struct - * - * Called by the kernel when the daemon attempts an mmap() syscall - * using our handle. - */ -static int sep_request_daemon_mmap(struct file *filp, - struct vm_area_struct *vma) -{ - struct sep_device *sep = filp->private_data; - dma_addr_t bus_address; - int error = 0; - - if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { - error = -EINVAL; - goto end_function; - } - - /* Get physical address */ - bus_address = sep->shared_bus; - - if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - - dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); - error = -EAGAIN; - goto end_function; - } - -end_function: - return error; -} - -/** - * sep_request_daemon_poll - poll implementation - * @sep: struct sep_device * for current SEP device - * @filp: struct file * for open file - * @wait: poll_table * for poll - * - * Called when our device is part of a poll() or select() syscall - */ -static unsigned int sep_request_daemon_poll(struct file *filp, - poll_table *wait) -{ - u32 mask = 0; - /* GPR2 register */ - u32 retval2; - unsigned long lck_flags; - struct sep_device *sep = filp->private_data; - - poll_wait(filp, &sep->event_request_daemon, wait); - - dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n", - sep->send_ct, sep->reply_ct); - - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - /* Check if the data is ready */ - if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, - "daemon poll: data check (GPR2) is %x\n", retval2); - - /* Check if PRINT request */ - if ((retval2 >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n"); - mask |= POLLIN; - goto end_function; - } - /* Check if NVS request */ - if (retval2 >> 31) { - dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n"); - mask |= POLLPRI | POLLWRNORM; - } - } else { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, - "daemon poll: no reply received; returning 0\n"); - mask = 0; - } -end_function: - return mask; -} - -/** - * sep_release - close a SEP device - * @inode: inode of SEP device - * @filp: file handle being closed - * - * Called on the final close of a SEP device. - */ -static int sep_release(struct inode *inode, struct file *filp) -{ - struct sep_device *sep = filp->private_data; - - dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid); - - mutex_lock(&sep->sep_mutex); - /* Is this the process that has a transaction open? - * If so, lets reset pid_doing_transaction to 0 and - * clear the in use flags, and then wake up sep_event - * so that other processes can do transactions - */ - if (sep->pid_doing_transaction == current->pid) { - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); - sep_free_dma_table_data_handler(sep); - wake_up(&sep->event); - sep->pid_doing_transaction = 0; - } - - mutex_unlock(&sep->sep_mutex); - return 0; -} - -/** - * sep_mmap - maps the shared area to user space - * @filp: pointer to struct file - * @vma: pointer to vm_area_struct - * - * Called on an mmap of our space via the normal SEP device - */ -static int sep_mmap(struct file *filp, struct vm_area_struct *vma) -{ - dma_addr_t bus_addr; - struct sep_device *sep = filp->private_data; - unsigned long error = 0; - - /* Set the transaction busy (own the device) */ - wait_event_interruptible(sep->event, - test_and_set_bit(SEP_MMAP_LOCK_BIT, - &sep->in_use_flags) == 0); - - if (signal_pending(current)) { - error = -EINTR; - goto end_function_with_error; - } - /* - * The pid_doing_transaction indicates that this process - * now owns the facilities to performa a transaction with - * the SEP. While this process is performing a transaction, - * no other process who has the SEP device open can perform - * any transactions. This method allows more than one process - * to have the device open at any given time, which provides - * finer granularity for device utilization by multiple - * processes. - */ - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = current->pid; - mutex_unlock(&sep->sep_mutex); - - /* Zero the pools and the number of data pool alocation pointers */ - sep->data_pool_bytes_allocated = 0; - sep->num_of_data_allocations = 0; - - /* - * Check that the size of the mapped range is as the size of the message - * shared area - */ - if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { - error = -EINVAL; - goto end_function_with_error; - } - - dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr); - - /* Get bus address */ - bus_addr = sep->shared_bus; - - if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, - vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); - error = -EAGAIN; - goto end_function_with_error; - } - goto end_function; - -end_function_with_error: - /* Clear the bit */ - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = 0; - mutex_unlock(&sep->sep_mutex); - - /* Raise event for stuck contextes */ - - wake_up(&sep->event); - -end_function: - return error; -} - -/** - * sep_poll - poll handler - * @filp: pointer to struct file - * @wait: pointer to poll_table - * - * Called by the OS when the kernel is asked to do a poll on - * a SEP file handle. - */ -static unsigned int sep_poll(struct file *filp, poll_table *wait) -{ - u32 mask = 0; - u32 retval = 0; - u32 retval2 = 0; - unsigned long lck_flags; - - struct sep_device *sep = filp->private_data; - - /* Am I the process that owns the transaction? */ - mutex_lock(&sep->sep_mutex); - if (current->pid != sep->pid_doing_transaction) { - dev_dbg(&sep->pdev->dev, "poll; wrong pid\n"); - mask = POLLERR; - mutex_unlock(&sep->sep_mutex); - goto end_function; - } - mutex_unlock(&sep->sep_mutex); - - /* Check if send command or send_reply were activated previously */ - if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { - mask = POLLERR; - goto end_function; - } - - /* Add the event to the polling wait table */ - dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n"); - - poll_wait(filp, &sep->event, wait); - - dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", - sep->send_ct, sep->reply_ct); - - /* Check if error occurred during poll */ - retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - if (retval2 != 0x0) { - dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2); - mask |= POLLERR; - goto end_function; - } - - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - - if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2) %x\n", - retval); - - /* Check if printf request */ - if ((retval >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "poll: SEP printf request\n"); - wake_up(&sep->event_request_daemon); - goto end_function; - } - - /* Check if the this is SEP reply or request */ - if (retval >> 31) { - dev_dbg(&sep->pdev->dev, "poll: SEP request\n"); - wake_up(&sep->event_request_daemon); - } else { - dev_dbg(&sep->pdev->dev, "poll: normal return\n"); - /* In case it is again by send_reply_comand */ - clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); - sep_dump_message(sep); - dev_dbg(&sep->pdev->dev, - "poll; SEP reply POLLIN | POLLRDNORM\n"); - mask |= POLLIN | POLLRDNORM; - } - } else { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, - "poll; no reply received; returning mask of 0\n"); - mask = 0; - } - -end_function: - return mask; -} - -/** - * sep_time_address - address in SEP memory of time - * @sep: SEP device we want the address from - * - * Return the address of the two dwords in memory used for time - * setting. - */ -static u32 *sep_time_address(struct sep_device *sep) -{ - return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; -} - -/** - * sep_set_time - set the SEP time - * @sep: the SEP we are setting the time for - * - * Calculates time and sets it at the predefined address. - * Called with the SEP mutex held. - */ -static unsigned long sep_set_time(struct sep_device *sep) -{ - struct timeval time; - u32 *time_addr; /* Address of time as seen by the kernel */ - - - do_gettimeofday(&time); - - /* Set value in the SYSTEM MEMORY offset */ - time_addr = sep_time_address(sep); - - time_addr[0] = SEP_TIME_VAL_TOKEN; - time_addr[1] = time.tv_sec; - - dev_dbg(&sep->pdev->dev, "time.tv_sec is %lu\n", time.tv_sec); - dev_dbg(&sep->pdev->dev, "time_addr is %p\n", time_addr); - dev_dbg(&sep->pdev->dev, "sep->shared_addr is %p\n", sep->shared_addr); - - return time.tv_sec; -} - -/** - * sep_set_caller_id_handler - insert caller id entry - * @sep: SEP device - * @arg: pointer to struct caller_id_struct - * - * Inserts the data into the caller id table. Note that this function - * falls under the ioctl lock - */ -static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) -{ - void __user *hash; - int error = 0; - int i; - struct caller_id_struct command_args; - - for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { - if (sep->caller_id_table[i].pid == 0) - break; - } - - if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) { - dev_dbg(&sep->pdev->dev, "no more caller id entries left\n"); - dev_dbg(&sep->pdev->dev, "maximum number is %d\n", - SEP_CALLER_ID_TABLE_NUM_ENTRIES); - error = -EUSERS; - goto end_function; - } - - /* Copy the data */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(command_args))) { - error = -EFAULT; - goto end_function; - } - - hash = (void __user *)(unsigned long)command_args.callerIdAddress; - - if (!command_args.pid || !command_args.callerIdSizeInBytes) { - error = -EINVAL; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, "pid is %x\n", command_args.pid); - dev_dbg(&sep->pdev->dev, "callerIdSizeInBytes is %x\n", - command_args.callerIdSizeInBytes); - - if (command_args.callerIdSizeInBytes > - SEP_CALLER_ID_HASH_SIZE_IN_BYTES) { - error = -EMSGSIZE; - goto end_function; - } - - sep->caller_id_table[i].pid = command_args.pid; - - if (copy_from_user(sep->caller_id_table[i].callerIdHash, - hash, command_args.callerIdSizeInBytes)) - error = -EFAULT; -end_function: - return error; -} - -/** - * sep_set_current_caller_id - set the caller id - * @sep: pointer to struct_sep_device - * - * Set the caller ID (if it exists) to the SEP. Note that this - * function falls under the ioctl lock - */ -static int sep_set_current_caller_id(struct sep_device *sep) -{ - int i; - u32 *hash_buf_ptr; - - /* Zero the previous value */ - memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, - 0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES); - - for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { - if (sep->caller_id_table[i].pid == current->pid) { - dev_dbg(&sep->pdev->dev, "Caller Id found\n"); - - memcpy(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, - (void *)(sep->caller_id_table[i].callerIdHash), - SEP_CALLER_ID_HASH_SIZE_IN_BYTES); - break; - } - } - /* Ensure data is in little endian */ - hash_buf_ptr = (u32 *)sep->shared_addr + - SEP_CALLER_ID_OFFSET_BYTES; - - for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++) - hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]); - - return 0; -} - -/** - * sep_send_command_handler - kick off a command - * @sep: SEP being signalled - * - * This function raises interrupt to SEP that signals that is has a new - * command from the host - * - * Note that this function does fall under the ioctl lock - */ -static int sep_send_command_handler(struct sep_device *sep) -{ - unsigned long lck_flags; - int error = 0; - - if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { - error = -EPROTO; - goto end_function; - } - sep_set_time(sep); - - sep_set_current_caller_id(sep); - - sep_dump_message(sep); - - /* Update counter */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->send_ct++; - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, - "sep_send_command_handler send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - /* Send interrupt to SEP */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); - -end_function: - return error; -} - -/** - * sep_allocate_data_pool_memory_handler -allocate pool memory - * @sep: pointer to struct sep_device - * @arg: pointer to struct alloc_struct - * - * This function handles the allocate data pool memory request - * This function returns calculates the bus address of the - * allocated memory, and the offset of this area from the mapped address. - * Therefore, the FVOs in user space can calculate the exact virtual - * address of this allocated memory - */ -static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, - unsigned long arg) -{ - int error = 0; - struct alloc_struct command_args; - - /* Holds the allocated buffer address in the system memory pool */ - u32 *token_addr; - - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct alloc_struct))) { - error = -EFAULT; - goto end_function; - } - - /* Allocate memory */ - if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > - SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { - error = -ENOMEM; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, - "data pool bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); - dev_dbg(&sep->pdev->dev, - "offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES); - /* Set the virtual and bus address */ - command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + - sep->data_pool_bytes_allocated; - - /* Place in the shared area that is known by the SEP */ - token_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + - (sep->num_of_data_allocations)*2*sizeof(u32)); - - token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN; - token_addr[1] = (u32)sep->shared_bus + - SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + - sep->data_pool_bytes_allocated; - - /* Write the memory back to the user space */ - error = copy_to_user((void *)arg, (void *)&command_args, - sizeof(struct alloc_struct)); - if (error) { - error = -EFAULT; - goto end_function; - } - - /* Update the allocation */ - sep->data_pool_bytes_allocated += command_args.num_bytes; - sep->num_of_data_allocations += 1; - -end_function: - return error; -} - -/** - * sep_lock_kernel_pages - map kernel pages for DMA - * @sep: pointer to struct sep_device - * @kernel_virt_addr: address of data buffer in kernel - * @data_size: size of data - * @lli_array_ptr: lli array - * @in_out_flag: input into device or output from device - * - * This function locks all the physical pages of the kernel virtual buffer - * and construct a basic lli array, where each entry holds the physical - * page address and the size that application data holds in this page - * This function is used only during kernel crypto mod calls from within - * the kernel (when ioctl is not used) - */ -static int sep_lock_kernel_pages(struct sep_device *sep, - unsigned long kernel_virt_addr, - u32 data_size, - struct sep_lli_entry **lli_array_ptr, - int in_out_flag) - -{ - int error = 0; - /* Array of lli */ - struct sep_lli_entry *lli_array; - /* Map array */ - struct sep_dma_map *map_array; - - dev_dbg(&sep->pdev->dev, "lock kernel pages kernel_virt_addr is %08lx\n", - (unsigned long)kernel_virt_addr); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); - - lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); - if (!lli_array) { - error = -ENOMEM; - goto end_function; - } - map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC); - if (!map_array) { - error = -ENOMEM; - goto end_function_with_error; - } - - map_array[0].dma_addr = - dma_map_single(&sep->pdev->dev, (void *)kernel_virt_addr, - data_size, DMA_BIDIRECTIONAL); - map_array[0].size = data_size; - - - /* - * Set the start address of the first page - app data may start not at - * the beginning of the page - */ - lli_array[0].bus_address = (u32)map_array[0].dma_addr; - lli_array[0].block_size = map_array[0].size; - - dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", - (unsigned long)lli_array[0].bus_address, - lli_array[0].block_size); - - /* Set the output parameters */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1; - } else { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1; - } - goto end_function; - -end_function_with_error: - kfree(lli_array); - -end_function: - return error; -} - -/** - * sep_lock_user_pages - lock and map user pages for DMA - * @sep: pointer to struct sep_device - * @app_virt_addr: user memory data buffer - * @data_size: size of data buffer - * @lli_array_ptr: lli array - * @in_out_flag: input or output to device - * - * This function locks all the physical pages of the application - * virtual buffer and construct a basic lli array, where each entry - * holds the physical page address and the size that application - * data holds in this physical pages - */ -static int sep_lock_user_pages(struct sep_device *sep, - u32 app_virt_addr, - u32 data_size, - struct sep_lli_entry **lli_array_ptr, - int in_out_flag) - -{ - int error = 0; - u32 count; - int result; - /* The the page of the end address of the user space buffer */ - u32 end_page; - /* The page of the start address of the user space buffer */ - u32 start_page; - /* The range in pages */ - u32 num_pages; - /* Array of pointers to page */ - struct page **page_array; - /* Array of lli */ - struct sep_lli_entry *lli_array; - /* Map array */ - struct sep_dma_map *map_array; - /* Direction of the DMA mapping for locked pages */ - enum dma_data_direction dir; - - /* Set start and end pages and num pages */ - end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; - start_page = app_virt_addr >> PAGE_SHIFT; - num_pages = end_page - start_page + 1; - - dev_dbg(&sep->pdev->dev, "lock user pages app_virt_addr is %x\n", app_virt_addr); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page); - dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page); - dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages); - - /* Allocate array of pages structure pointers */ - page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); - if (!page_array) { - error = -ENOMEM; - goto end_function; - } - map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); - if (!map_array) { - dev_warn(&sep->pdev->dev, "kmalloc for map_array failed\n"); - error = -ENOMEM; - goto end_function_with_error1; - } - - lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, - GFP_ATOMIC); - - if (!lli_array) { - dev_warn(&sep->pdev->dev, "kmalloc for lli_array failed\n"); - error = -ENOMEM; - goto end_function_with_error2; - } - - /* Convert the application virtual address into a set of physical */ - down_read(¤t->mm->mmap_sem); - result = get_user_pages(current, current->mm, app_virt_addr, - num_pages, - ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), - 0, page_array, NULL); - - up_read(¤t->mm->mmap_sem); - - /* Check the number of pages locked - if not all then exit with error */ - if (result != num_pages) { - dev_warn(&sep->pdev->dev, - "not all pages locked by get_user_pages\n"); - error = -ENOMEM; - goto end_function_with_error3; - } - - dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n"); - - /* Set direction */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) - dir = DMA_TO_DEVICE; - else - dir = DMA_FROM_DEVICE; - - /* - * Fill the array using page array data and - * map the pages - this action will also flush the cache as needed - */ - for (count = 0; count < num_pages; count++) { - /* Fill the map array */ - map_array[count].dma_addr = - dma_map_page(&sep->pdev->dev, page_array[count], - 0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL); - - map_array[count].size = PAGE_SIZE; - - /* Fill the lli array entry */ - lli_array[count].bus_address = (u32)map_array[count].dma_addr; - lli_array[count].block_size = PAGE_SIZE; - - dev_warn(&sep->pdev->dev, "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n", - count, (unsigned long)lli_array[count].bus_address, - count, lli_array[count].block_size); - } - - /* Check the offset for the first page */ - lli_array[0].bus_address = - lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); - - /* Check that not all the data is in the first page only */ - if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) - lli_array[0].block_size = data_size; - else - lli_array[0].block_size = - PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); - - dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", - (unsigned long)lli_array[count].bus_address, - lli_array[count].block_size); - - /* Check the size of the last page */ - if (num_pages > 1) { - lli_array[num_pages - 1].block_size = - (app_virt_addr + data_size) & (~PAGE_MASK); - if (lli_array[num_pages - 1].block_size == 0) - lli_array[num_pages - 1].block_size = PAGE_SIZE; - - dev_warn(&sep->pdev->dev, - "lli_array[%x].bus_address is " - "%08lx, lli_array[%x].block_size is %x\n", - num_pages - 1, - (unsigned long)lli_array[num_pages - 1].bus_address, - num_pages - 1, - lli_array[num_pages - 1].block_size); - } - - /* Set output params according to the in_out flag */ - if (in_out_flag == SEP_DRIVER_IN_FLAG) { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = page_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = - num_pages; - } else { - *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = num_pages; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = - page_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = - num_pages; - } - goto end_function; - -end_function_with_error3: - /* Free lli array */ - kfree(lli_array); - -end_function_with_error2: - kfree(map_array); - -end_function_with_error1: - /* Free page array */ - kfree(page_array); - -end_function: - return error; -} - -/** - * u32 sep_calculate_lli_table_max_size - size the LLI table - * @sep: pointer to struct sep_device - * @lli_in_array_ptr - * @num_array_entries - * @last_table_flag - * - * This function calculates the size of data that can be inserted into - * the lli table from this array, such that either the table is full - * (all entries are entered), or there are no more entries in the - * lli array - */ -static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, - struct sep_lli_entry *lli_in_array_ptr, - u32 num_array_entries, - u32 *last_table_flag) -{ - u32 counter; - /* Table data size */ - u32 table_data_size = 0; - /* Data size for the next table */ - u32 next_table_data_size; - - *last_table_flag = 0; - - /* - * Calculate the data in the out lli table till we fill the whole - * table or till the data has ended - */ - for (counter = 0; - (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && - (counter < num_array_entries); counter++) - table_data_size += lli_in_array_ptr[counter].block_size; - - /* - * Check if we reached the last entry, - * meaning this ia the last table to build, - * and no need to check the block alignment - */ - if (counter == num_array_entries) { - /* Set the last table flag */ - *last_table_flag = 1; - goto end_function; - } - - /* - * Calculate the data size of the next table. - * Stop if no entries left or if data size is more the DMA restriction - */ - next_table_data_size = 0; - for (; counter < num_array_entries; counter++) { - next_table_data_size += lli_in_array_ptr[counter].block_size; - if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) - break; - } - - /* - * Check if the next table data size is less then DMA rstriction. - * if it is - recalculate the current table size, so that the next - * table data size will be adaquete for DMA - */ - if (next_table_data_size && - next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) - - table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - - next_table_data_size); - -end_function: - return table_data_size; -} - -/** - * sep_build_lli_table - build an lli array for the given table - * @sep: pointer to struct sep_device - * @lli_array_ptr: pointer to lli array - * @lli_table_ptr: pointer to lli table - * @num_processed_entries_ptr: pointer to number of entries - * @num_table_entries_ptr: pointer to number of tables - * @table_data_size: total data size - * - * Builds ant lli table from the lli_array according to - * the given size of data - */ -static void sep_build_lli_table(struct sep_device *sep, - struct sep_lli_entry *lli_array_ptr, - struct sep_lli_entry *lli_table_ptr, - u32 *num_processed_entries_ptr, - u32 *num_table_entries_ptr, - u32 table_data_size) -{ - /* Current table data size */ - u32 curr_table_data_size; - /* Counter of lli array entry */ - u32 array_counter; - - /* Init current table data size and lli array entry counter */ - curr_table_data_size = 0; - array_counter = 0; - *num_table_entries_ptr = 1; - - dev_dbg(&sep->pdev->dev, "build lli table table_data_size is %x\n", table_data_size); - - /* Fill the table till table size reaches the needed amount */ - while (curr_table_data_size < table_data_size) { - /* Update the number of entries in table */ - (*num_table_entries_ptr)++; - - lli_table_ptr->bus_address = - cpu_to_le32(lli_array_ptr[array_counter].bus_address); - - lli_table_ptr->block_size = - cpu_to_le32(lli_array_ptr[array_counter].block_size); - - curr_table_data_size += lli_array_ptr[array_counter].block_size; - - dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n", - lli_table_ptr); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - /* Check for overflow of the table data */ - if (curr_table_data_size > table_data_size) { - dev_dbg(&sep->pdev->dev, - "curr_table_data_size too large\n"); - - /* Update the size of block in the table */ - lli_table_ptr->block_size -= - cpu_to_le32((curr_table_data_size - table_data_size)); - - /* Update the physical address in the lli array */ - lli_array_ptr[array_counter].bus_address += - cpu_to_le32(lli_table_ptr->block_size); - - /* Update the block size left in the lli array */ - lli_array_ptr[array_counter].block_size = - (curr_table_data_size - table_data_size); - } else - /* Advance to the next entry in the lli_array */ - array_counter++; - - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - /* Move to the next entry in table */ - lli_table_ptr++; - } - - /* Set the info entry to default */ - lli_table_ptr->bus_address = 0xffffffff; - lli_table_ptr->block_size = 0; - - /* Set the output parameter */ - *num_processed_entries_ptr += array_counter; - -} - -/** - * sep_shared_area_virt_to_bus - map shared area to bus address - * @sep: pointer to struct sep_device - * @virt_address: virtual address to convert - * - * This functions returns the physical address inside shared area according - * to the virtual address. It can be either on the externa RAM device - * (ioremapped), or on the system RAM - * This implementation is for the external RAM - */ -static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, - void *virt_address) -{ - dev_dbg(&sep->pdev->dev, "sh virt to phys v %p\n", virt_address); - dev_dbg(&sep->pdev->dev, "sh virt to phys p %08lx\n", - (unsigned long) - sep->shared_bus + (virt_address - sep->shared_addr)); - - return sep->shared_bus + (size_t)(virt_address - sep->shared_addr); -} - -/** - * sep_shared_area_bus_to_virt - map shared area bus address to kernel - * @sep: pointer to struct sep_device - * @bus_address: bus address to convert - * - * This functions returns the virtual address inside shared area - * according to the physical address. It can be either on the - * externa RAM device (ioremapped), or on the system RAM - * This implementation is for the external RAM - */ -static void *sep_shared_area_bus_to_virt(struct sep_device *sep, - dma_addr_t bus_address) -{ - dev_dbg(&sep->pdev->dev, "shared bus to virt b=%lx v=%lx\n", - (unsigned long)bus_address, (unsigned long)(sep->shared_addr + - (size_t)(bus_address - sep->shared_bus))); - - return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); -} - -/** - * sep_debug_print_lli_tables - dump LLI table - * @sep: pointer to struct sep_device - * @lli_table_ptr: pointer to sep_lli_entry - * @num_table_entries: number of entries - * @table_data_size: total data size - * - * Walk the the list of the print created tables and print all the data - */ -static void sep_debug_print_lli_tables(struct sep_device *sep, - struct sep_lli_entry *lli_table_ptr, - unsigned long num_table_entries, - unsigned long table_data_size) -{ - unsigned long table_count = 1; - unsigned long entries_count = 0; - - dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n"); - - while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) { - dev_dbg(&sep->pdev->dev, - "lli table %08lx, table_data_size is %lu\n", - table_count, table_data_size); - dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n", - num_table_entries); - - /* Print entries of the table (without info entry) */ - for (entries_count = 0; entries_count < num_table_entries; - entries_count++, lli_table_ptr++) { - - dev_dbg(&sep->pdev->dev, - "lli_table_ptr address is %08lx\n", - (unsigned long) lli_table_ptr); - - dev_dbg(&sep->pdev->dev, - "phys address is %08lx block size is %x\n", - (unsigned long)lli_table_ptr->bus_address, - lli_table_ptr->block_size); - } - /* Point to the info entry */ - lli_table_ptr--; - - dev_dbg(&sep->pdev->dev, - "phys lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); - - dev_dbg(&sep->pdev->dev, - "phys lli_table_ptr->physical_address is %08lu\n", - (unsigned long)lli_table_ptr->bus_address); - - - table_data_size = lli_table_ptr->block_size & 0xffffff; - num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; - - dev_dbg(&sep->pdev->dev, - "phys table_data_size is %lu num_table_entries is" - " %lu bus_address is%lu\n", table_data_size, - num_table_entries, (unsigned long)lli_table_ptr->bus_address); - - if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff) - lli_table_ptr = (struct sep_lli_entry *) - sep_shared_bus_to_virt(sep, - (unsigned long)lli_table_ptr->bus_address); - - table_count++; - } - dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables end\n"); -} - - -/** - * sep_prepare_empty_lli_table - create a blank LLI table - * @sep: pointer to struct sep_device - * @lli_table_addr_ptr: pointer to lli table - * @num_entries_ptr: pointer to number of entries - * @table_data_size_ptr: point to table data size - * - * This function creates empty lli tables when there is no data - */ -static void sep_prepare_empty_lli_table(struct sep_device *sep, - dma_addr_t *lli_table_addr_ptr, - u32 *num_entries_ptr, - u32 *table_data_size_ptr) -{ - struct sep_lli_entry *lli_table_ptr; - - /* Find the area for new table */ - lli_table_ptr = - (struct sep_lli_entry *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - lli_table_ptr->bus_address = 0; - lli_table_ptr->block_size = 0; - - lli_table_ptr++; - lli_table_ptr->bus_address = 0xFFFFFFFF; - lli_table_ptr->block_size = 0; - - /* Set the output parameter value */ - *lli_table_addr_ptr = sep->shared_bus + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * - sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Set the num of entries and table data size for empty table */ - *num_entries_ptr = 2; - *table_data_size_ptr = 0; - - /* Update the number of created tables */ - sep->num_lli_tables_created++; -} - -/** - * sep_prepare_input_dma_table - prepare input DMA mappings - * @sep: pointer to struct sep_device - * @data_size: - * @block_size: - * @lli_table_ptr: - * @num_entries_ptr: - * @table_data_size_ptr: - * @is_kva: set for kernel data (kernel cryptio call) - * - * This function prepares only input DMA table for synhronic symmetric - * operations (HASH) - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_dma_table(struct sep_device *sep, - unsigned long app_virt_addr, - u32 data_size, - u32 block_size, - dma_addr_t *lli_table_ptr, - u32 *num_entries_ptr, - u32 *table_data_size_ptr, - bool is_kva) -{ - int error = 0; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_entry_ptr; - /* Array of pointers to page */ - struct sep_lli_entry *lli_array_ptr; - /* Points to the first entry to be processed in the lli_in_array */ - u32 current_entry = 0; - /* Num entries in the virtual buffer */ - u32 sep_lli_entries = 0; - /* Lli table pointer */ - struct sep_lli_entry *in_lli_table_ptr; - /* The total data in one table */ - u32 table_data_size = 0; - /* Flag for last table */ - u32 last_table_flag = 0; - /* Number of entries in lli table */ - u32 num_entries_in_table = 0; - /* Next table address */ - void *lli_table_alloc_addr = 0; - - dev_dbg(&sep->pdev->dev, "prepare intput dma table data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); - - /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; - - /* Set the kernel address for first table to be allocated */ - lli_table_alloc_addr = (void *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - if (data_size == 0) { - /* Special case - create meptu table - 2 entries, zero data */ - sep_prepare_empty_lli_table(sep, lli_table_ptr, - num_entries_ptr, table_data_size_ptr); - goto update_dcb_counter; - } - - /* Check if the pages are in Kernel Virtual Address layout */ - if (is_kva == true) - /* Lock the pages in the kernel */ - error = sep_lock_kernel_pages(sep, app_virt_addr, - data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); - else - /* - * Lock the pages of the user buffer - * and translate them to pages - */ - error = sep_lock_user_pages(sep, app_virt_addr, - data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); - - if (error) - goto end_function; - - dev_dbg(&sep->pdev->dev, "output sep_in_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); - - current_entry = 0; - info_entry_ptr = NULL; - - sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; - - /* Loop till all the entries in in array are not processed */ - while (current_entry < sep_lli_entries) { - - /* Set the new input and output tables */ - in_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - if (lli_table_alloc_addr > - ((void *)sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { - - error = -ENOMEM; - goto end_function_error; - - } - - /* Update the number of created tables */ - sep->num_lli_tables_created++; - - /* Calculate the maximum size of data for input table */ - table_data_size = sep_calculate_lli_table_max_size(sep, - &lli_array_ptr[current_entry], - (sep_lli_entries - current_entry), - &last_table_flag); - - /* - * If this is not the last table - - * then align it to the block size - */ - if (!last_table_flag) - table_data_size = - (table_data_size / block_size) * block_size; - - dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n", - table_data_size); - - /* Construct input lli table */ - sep_build_lli_table(sep, &lli_array_ptr[current_entry], - in_lli_table_ptr, - ¤t_entry, &num_entries_in_table, table_data_size); - - if (info_entry_ptr == NULL) { - - /* Set the output parameters to physical addresses */ - *lli_table_ptr = sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - *num_entries_ptr = num_entries_in_table; - *table_data_size_ptr = table_data_size; - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr is %08lx\n", - (unsigned long)*lli_table_ptr); - - } else { - /* Update the info entry of the previous in table */ - info_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - info_entry_ptr->block_size = - ((num_entries_in_table) << 24) | - (table_data_size); - } - /* Save the pointer to the info entry of the current tables */ - info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; - } - /* Print input tables */ - sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_ptr), - *num_entries_ptr, *table_data_size_ptr); - /* The array of the pages */ - kfree(lli_array_ptr); - -update_dcb_counter: - /* Update DCB counter */ - sep->nr_dcb_creat++; - goto end_function; - -end_function_error: - /* Free all the allocated resources */ - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); - kfree(lli_array_ptr); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); - -end_function: - return error; - -} -/** - * sep_construct_dma_tables_from_lli - prepare AES/DES mappings - * @sep: pointer to struct sep_device - * @lli_in_array: - * @sep_in_lli_entries: - * @lli_out_array: - * @sep_out_lli_entries - * @block_size - * @lli_table_in_ptr - * @lli_table_out_ptr - * @in_num_entries_ptr - * @out_num_entries_ptr - * @table_data_size_ptr - * - * This function creates the input and output DMA tables for - * symmetric operations (AES/DES) according to the block - * size from LLI arays - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_construct_dma_tables_from_lli( - struct sep_device *sep, - struct sep_lli_entry *lli_in_array, - u32 sep_in_lli_entries, - struct sep_lli_entry *lli_out_array, - u32 sep_out_lli_entries, - u32 block_size, - dma_addr_t *lli_table_in_ptr, - dma_addr_t *lli_table_out_ptr, - u32 *in_num_entries_ptr, - u32 *out_num_entries_ptr, - u32 *table_data_size_ptr) -{ - /* Points to the area where next lli table can be allocated */ - void *lli_table_alloc_addr = 0; - /* Input lli table */ - struct sep_lli_entry *in_lli_table_ptr = NULL; - /* Output lli table */ - struct sep_lli_entry *out_lli_table_ptr = NULL; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_in_entry_ptr = NULL; - /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_out_entry_ptr = NULL; - /* Points to the first entry to be processed in the lli_in_array */ - u32 current_in_entry = 0; - /* Points to the first entry to be processed in the lli_out_array */ - u32 current_out_entry = 0; - /* Max size of the input table */ - u32 in_table_data_size = 0; - /* Max size of the output table */ - u32 out_table_data_size = 0; - /* Flag te signifies if this is the last tables build */ - u32 last_table_flag = 0; - /* The data size that should be in table */ - u32 table_data_size = 0; - /* Number of etnries in the input table */ - u32 num_entries_in_table = 0; - /* Number of etnries in the output table */ - u32 num_entries_out_table = 0; - - /* Initiate to point after the message area */ - lli_table_alloc_addr = (void *)(sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - (sep->num_lli_tables_created * - (sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); - - /* Loop till all the entries in in array are not processed */ - while (current_in_entry < sep_in_lli_entries) { - /* Set the new input and output tables */ - in_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Set the first output tables */ - out_lli_table_ptr = - (struct sep_lli_entry *)lli_table_alloc_addr; - - /* Check if the DMA table area limit was overrun */ - if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > - ((void *)sep->shared_addr + - SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { - - dev_warn(&sep->pdev->dev, "dma table limit overrun\n"); - return -ENOMEM; - } - - /* Update the number of the lli tables created */ - sep->num_lli_tables_created += 2; - - lli_table_alloc_addr += sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - - /* Calculate the maximum size of data for input table */ - in_table_data_size = - sep_calculate_lli_table_max_size(sep, - &lli_in_array[current_in_entry], - (sep_in_lli_entries - current_in_entry), - &last_table_flag); - - /* Calculate the maximum size of data for output table */ - out_table_data_size = - sep_calculate_lli_table_max_size(sep, - &lli_out_array[current_out_entry], - (sep_out_lli_entries - current_out_entry), - &last_table_flag); - - dev_dbg(&sep->pdev->dev, - "construct tables from lli in_table_data_size is %x\n", - in_table_data_size); - - dev_dbg(&sep->pdev->dev, - "construct tables from lli out_table_data_size is %x\n", - out_table_data_size); - - table_data_size = in_table_data_size; - - if (!last_table_flag) { - /* - * If this is not the last table, - * then must check where the data is smallest - * and then align it to the block size - */ - if (table_data_size > out_table_data_size) - table_data_size = out_table_data_size; - - /* - * Now calculate the table size so that - * it will be module block size - */ - table_data_size = (table_data_size / block_size) * - block_size; - } - - /* Construct input lli table */ - sep_build_lli_table(sep, &lli_in_array[current_in_entry], - in_lli_table_ptr, - ¤t_in_entry, - &num_entries_in_table, - table_data_size); - - /* Construct output lli table */ - sep_build_lli_table(sep, &lli_out_array[current_out_entry], - out_lli_table_ptr, - ¤t_out_entry, - &num_entries_out_table, - table_data_size); - - /* If info entry is null - this is the first table built */ - if (info_in_entry_ptr == NULL) { - /* Set the output parameters to physical addresses */ - *lli_table_in_ptr = - sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); - - *in_num_entries_ptr = num_entries_in_table; - - *lli_table_out_ptr = - sep_shared_area_virt_to_bus(sep, - out_lli_table_ptr); - - *out_num_entries_ptr = num_entries_out_table; - *table_data_size_ptr = table_data_size; - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr is %08lx\n", - (unsigned long)*lli_table_in_ptr); - dev_dbg(&sep->pdev->dev, - "output lli_table_out_ptr is %08lx\n", - (unsigned long)*lli_table_out_ptr); - } else { - /* Update the info entry of the previous in table */ - info_in_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - - info_in_entry_ptr->block_size = - ((num_entries_in_table) << 24) | - (table_data_size); - - /* Update the info entry of the previous in table */ - info_out_entry_ptr->bus_address = - sep_shared_area_virt_to_bus(sep, - out_lli_table_ptr); - - info_out_entry_ptr->block_size = - ((num_entries_out_table) << 24) | - (table_data_size); - - dev_dbg(&sep->pdev->dev, - "output lli_table_in_ptr:%08lx %08x\n", - (unsigned long)info_in_entry_ptr->bus_address, - info_in_entry_ptr->block_size); - - dev_dbg(&sep->pdev->dev, - "output lli_table_out_ptr:%08lx %08x\n", - (unsigned long)info_out_entry_ptr->bus_address, - info_out_entry_ptr->block_size); - } - - /* Save the pointer to the info entry of the current tables */ - info_in_entry_ptr = in_lli_table_ptr + - num_entries_in_table - 1; - info_out_entry_ptr = out_lli_table_ptr + - num_entries_out_table - 1; - - dev_dbg(&sep->pdev->dev, - "output num_entries_out_table is %x\n", - (u32)num_entries_out_table); - dev_dbg(&sep->pdev->dev, - "output info_in_entry_ptr is %lx\n", - (unsigned long)info_in_entry_ptr); - dev_dbg(&sep->pdev->dev, - "output info_out_entry_ptr is %lx\n", - (unsigned long)info_out_entry_ptr); - } - - /* Print input tables */ - sep_debug_print_lli_tables(sep, - (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), - *in_num_entries_ptr, - *table_data_size_ptr); - - /* Print output tables */ - sep_debug_print_lli_tables(sep, - (struct sep_lli_entry *) - sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), - *out_num_entries_ptr, - *table_data_size_ptr); - - return 0; -} - -/** - * sep_prepare_input_output_dma_table - prepare DMA I/O table - * @app_virt_in_addr: - * @app_virt_out_addr: - * @data_size: - * @block_size: - * @lli_table_in_ptr: - * @lli_table_out_ptr: - * @in_num_entries_ptr: - * @out_num_entries_ptr: - * @table_data_size_ptr: - * @is_kva: set for kernel data; used only for kernel crypto module - * - * This function builds input and output DMA tables for synhronic - * symmetric operations (AES, DES, HASH). It also checks that each table - * is of the modular block size - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_output_dma_table(struct sep_device *sep, - unsigned long app_virt_in_addr, - unsigned long app_virt_out_addr, - u32 data_size, - u32 block_size, - dma_addr_t *lli_table_in_ptr, - dma_addr_t *lli_table_out_ptr, - u32 *in_num_entries_ptr, - u32 *out_num_entries_ptr, - u32 *table_data_size_ptr, - bool is_kva) - -{ - int error = 0; - /* Array of pointers of page */ - struct sep_lli_entry *lli_in_array; - /* Array of pointers of page */ - struct sep_lli_entry *lli_out_array; - - if (data_size == 0) { - /* Prepare empty table for input and output */ - sep_prepare_empty_lli_table(sep, lli_table_in_ptr, - in_num_entries_ptr, table_data_size_ptr); - - sep_prepare_empty_lli_table(sep, lli_table_out_ptr, - out_num_entries_ptr, table_data_size_ptr); - - goto update_dcb_counter; - } - - /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; - - /* Lock the pages of the buffer and translate them to pages */ - if (is_kva == true) { - error = sep_lock_kernel_pages(sep, app_virt_in_addr, - data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "lock kernel for in failed\n"); - goto end_function; - } - - error = sep_lock_kernel_pages(sep, app_virt_out_addr, - data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "lock kernel for out failed\n"); - goto end_function; - } - } - - else { - error = sep_lock_user_pages(sep, app_virt_in_addr, - data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); - if (error) { - dev_warn(&sep->pdev->dev, - "sep_lock_user_pages for input virtual buffer failed\n"); - goto end_function; - } - - error = sep_lock_user_pages(sep, app_virt_out_addr, - data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); - - if (error) { - dev_warn(&sep->pdev->dev, - "sep_lock_user_pages for output virtual buffer failed\n"); - goto end_function_free_lli_in; - } - } - - dev_dbg(&sep->pdev->dev, "prep input output dma table sep_in_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); - dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n", - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages); - dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - - /* Call the function that creates table from the lli arrays */ - error = sep_construct_dma_tables_from_lli(sep, lli_in_array, - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages, - lli_out_array, - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages, - block_size, lli_table_in_ptr, lli_table_out_ptr, - in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); - - if (error) { - dev_warn(&sep->pdev->dev, - "sep_construct_dma_tables_from_lli failed\n"); - goto end_function_with_error; - } - - kfree(lli_out_array); - kfree(lli_in_array); - -update_dcb_counter: - /* Update DCB counter */ - sep->nr_dcb_creat++; - - goto end_function; - -end_function_with_error: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array); - kfree(lli_out_array); - - -end_function_free_lli_in: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); - kfree(lli_in_array); - -end_function: - - return error; - -} - -/** - * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks - * @app_in_address: unsigned long; for data buffer in (user space) - * @app_out_address: unsigned long; for data buffer out (user space) - * @data_in_size: u32; for size of data - * @block_size: u32; for block size - * @tail_block_size: u32; for size of tail block - * @isapplet: bool; to indicate external app - * @is_kva: bool; kernel buffer; only used for kernel crypto module - * - * This function prepares the linked DMA tables and puts the - * address for the linked list of tables inta a DCB (data control - * block) the address of which is known by the SEP hardware - * Note that all bus addresses that are passed to the SEP - * are in 32 bit format; the SEP is a 32 bit device - */ -static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, - unsigned long app_in_address, - unsigned long app_out_address, - u32 data_in_size, - u32 block_size, - u32 tail_block_size, - bool isapplet, - bool is_kva) -{ - int error = 0; - /* Size of tail */ - u32 tail_size = 0; - /* Address of the created DCB table */ - struct sep_dcblock *dcb_table_ptr = NULL; - /* The physical address of the first input DMA table */ - dma_addr_t in_first_mlli_address = 0; - /* Number of entries in the first input DMA table */ - u32 in_first_num_entries = 0; - /* The physical address of the first output DMA table */ - dma_addr_t out_first_mlli_address = 0; - /* Number of entries in the first output DMA table */ - u32 out_first_num_entries = 0; - /* Data in the first input/output table */ - u32 first_data_size = 0; - - if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { - /* No more DCBs to allocate */ - dev_warn(&sep->pdev->dev, "no more DCBs available\n"); - error = -ENOSPC; - goto end_function; - } - - /* Allocate new DCB */ - dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + - (sep->nr_dcb_creat * sizeof(struct sep_dcblock))); - - /* Set the default values in the DCB */ - dcb_table_ptr->input_mlli_address = 0; - dcb_table_ptr->input_mlli_num_entries = 0; - dcb_table_ptr->input_mlli_data_size = 0; - dcb_table_ptr->output_mlli_address = 0; - dcb_table_ptr->output_mlli_num_entries = 0; - dcb_table_ptr->output_mlli_data_size = 0; - dcb_table_ptr->tail_data_size = 0; - dcb_table_ptr->out_vr_tail_pt = 0; - - if (isapplet == true) { - - /* Check if there is enough data for DMA operation */ - if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { - if (is_kva == true) { - memcpy(dcb_table_ptr->tail_data, - (void *)app_in_address, data_in_size); - } else { - if (copy_from_user(dcb_table_ptr->tail_data, - (void __user *)app_in_address, - data_in_size)) { - error = -EFAULT; - goto end_function; - } - } - - dcb_table_ptr->tail_data_size = data_in_size; - - /* Set the output user-space address for mem2mem op */ - if (app_out_address) - dcb_table_ptr->out_vr_tail_pt = - (aligned_u64)app_out_address; - - /* - * Update both data length parameters in order to avoid - * second data copy and allow building of empty mlli - * tables - */ - tail_size = 0x0; - data_in_size = 0x0; - - } else { - if (!app_out_address) { - tail_size = data_in_size % block_size; - if (!tail_size) { - if (tail_block_size == block_size) - tail_size = block_size; - } - } else { - tail_size = 0; - } - } - if (tail_size) { - if (tail_size > sizeof(dcb_table_ptr->tail_data)) - return -EINVAL; - if (is_kva == true) { - memcpy(dcb_table_ptr->tail_data, - (void *)(app_in_address + data_in_size - - tail_size), tail_size); - } else { - /* We have tail data - copy it to DCB */ - if (copy_from_user(dcb_table_ptr->tail_data, - (void *)(app_in_address + - data_in_size - tail_size), tail_size)) { - error = -EFAULT; - goto end_function; - } - } - if (app_out_address) - /* - * Calculate the output address - * according to tail data size - */ - dcb_table_ptr->out_vr_tail_pt = - (aligned_u64)app_out_address + data_in_size - - tail_size; - - /* Save the real tail data size */ - dcb_table_ptr->tail_data_size = tail_size; - /* - * Update the data size without the tail - * data size AKA data for the dma - */ - data_in_size = (data_in_size - tail_size); - } - } - /* Check if we need to build only input table or input/output */ - if (app_out_address) { - /* Prepare input/output tables */ - error = sep_prepare_input_output_dma_table(sep, - app_in_address, - app_out_address, - data_in_size, - block_size, - &in_first_mlli_address, - &out_first_mlli_address, - &in_first_num_entries, - &out_first_num_entries, - &first_data_size, - is_kva); - } else { - /* Prepare input tables */ - error = sep_prepare_input_dma_table(sep, - app_in_address, - data_in_size, - block_size, - &in_first_mlli_address, - &in_first_num_entries, - &first_data_size, - is_kva); - } - - if (error) { - dev_warn(&sep->pdev->dev, "prepare DMA table call failed from prepare DCB call\n"); - goto end_function; - } - - /* Set the DCB values */ - dcb_table_ptr->input_mlli_address = in_first_mlli_address; - dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; - dcb_table_ptr->input_mlli_data_size = first_data_size; - dcb_table_ptr->output_mlli_address = out_first_mlli_address; - dcb_table_ptr->output_mlli_num_entries = out_first_num_entries; - dcb_table_ptr->output_mlli_data_size = first_data_size; - -end_function: - return error; - -} - -/** - * sep_free_dma_tables_and_dcb - free DMA tables and DCBs - * @sep: pointer to struct sep_device - * @isapplet: indicates external application (used for kernel access) - * @is_kva: indicates kernel addresses (only used for kernel crypto) - * - * This function frees the DMA tables and DCB - */ -static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, - bool is_kva) -{ - int i = 0; - int error = 0; - int error_temp = 0; - struct sep_dcblock *dcb_table_ptr; - unsigned long pt_hold; - void *tail_pt; - - if (isapplet == true) { - /* Set pointer to first DCB table */ - dcb_table_ptr = (struct sep_dcblock *) - (sep->shared_addr + - SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); - - /* Go over each DCB and see if tail pointer must be updated */ - for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) { - if (dcb_table_ptr->out_vr_tail_pt) { - pt_hold = (unsigned long)dcb_table_ptr->out_vr_tail_pt; - tail_pt = (void *)pt_hold; - if (is_kva == true) { - memcpy(tail_pt, - dcb_table_ptr->tail_data, - dcb_table_ptr->tail_data_size); - } else { - error_temp = copy_to_user( - tail_pt, - dcb_table_ptr->tail_data, - dcb_table_ptr->tail_data_size); - } - if (error_temp) { - /* Release the DMA resource */ - error = -EFAULT; - break; - } - } - } - } - /* Free the output pages, if any */ - sep_free_dma_table_data_handler(sep); - - return error; -} - -/** - * sep_get_static_pool_addr_handler - get static pool address - * @sep: pointer to struct sep_device - * - * This function sets the bus and virtual addresses of the static pool - */ -static int sep_get_static_pool_addr_handler(struct sep_device *sep) -{ - u32 *static_pool_addr = NULL; - - static_pool_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); - - static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN; - static_pool_addr[1] = (u32)sep->shared_bus + - SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; - - dev_dbg(&sep->pdev->dev, "static pool segment: physical %x\n", - (u32)static_pool_addr[1]); - - return 0; -} - -/** - * sep_end_transaction_handler - end transaction - * @sep: pointer to struct sep_device - * - * This API handles the end transaction request - */ -static int sep_end_transaction_handler(struct sep_device *sep) -{ - /* Clear the data pool pointers Token */ - memset((void *)(sep->shared_addr + - SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES), - 0, sep->num_of_data_allocations*2*sizeof(u32)); - - /* Check that all the DMA resources were freed */ - sep_free_dma_table_data_handler(sep); - - clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); - - /* - * We are now through with the transaction. Let's - * allow other processes who have the device open - * to perform transactions - */ - mutex_lock(&sep->sep_mutex); - sep->pid_doing_transaction = 0; - mutex_unlock(&sep->sep_mutex); - /* Raise event for stuck contextes */ - wake_up(&sep->event); - - return 0; -} - -/** - * sep_prepare_dcb_handler - prepare a control block - * @sep: pointer to struct sep_device - * @arg: pointer to user parameters - * - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. - */ -static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) -{ - int error; - /* Command arguments */ - struct build_dcb_struct command_args; - - /* Get the command arguments */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct build_dcb_struct))) { - error = -EFAULT; - goto end_function; - } - - dev_dbg(&sep->pdev->dev, "prep dcb handler app_in_address is %08llx\n", - command_args.app_in_address); - dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", - command_args.app_out_address); - dev_dbg(&sep->pdev->dev, "data_size is %x\n", - command_args.data_in_size); - dev_dbg(&sep->pdev->dev, "block_size is %x\n", - command_args.block_size); - dev_dbg(&sep->pdev->dev, "tail block_size is %x\n", - command_args.tail_block_size); - - error = sep_prepare_input_output_dma_table_in_dcb(sep, - (unsigned long)command_args.app_in_address, - (unsigned long)command_args.app_out_address, - command_args.data_in_size, command_args.block_size, - command_args.tail_block_size, true, false); - -end_function: - return error; - -} - -/** - * sep_free_dcb_handler - free control block resources - * @sep: pointer to struct sep_device - * - * This function frees the DCB resources and updates the needed - * user-space buffers. - */ -static int sep_free_dcb_handler(struct sep_device *sep) -{ - return sep_free_dma_tables_and_dcb(sep, false, false); -} - -/** - * sep_rar_prepare_output_msg_handler - prepare an output message - * @sep: pointer to struct sep_device - * @arg: pointer to user parameters - * - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. - */ -static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, - unsigned long arg) -{ - int error = 0; - /* Command args */ - struct rar_hndl_to_bus_struct command_args; - /* Bus address */ - dma_addr_t rar_bus = 0; - /* Holds the RAR address in the system memory offset */ - u32 *rar_addr; - - /* Copy the data */ - if (copy_from_user(&command_args, (void __user *)arg, - sizeof(command_args))) { - error = -EFAULT; - goto end_function; - } - - /* Call to translation function only if user handle is not NULL */ - if (command_args.rar_handle) - return -EOPNOTSUPP; - dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus); - - /* Set value in the SYSTEM MEMORY offset */ - rar_addr = (u32 *)(sep->shared_addr + - SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); - - /* Copy the physical address to the System Area for the SEP */ - rar_addr[0] = SEP_RAR_VAL_TOKEN; - rar_addr[1] = rar_bus; - -end_function: - return error; -} - -/** - * sep_ioctl - ioctl api - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Implement the ioctl methods available on the SEP device. - */ -static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int error = 0; - struct sep_device *sep = filp->private_data; - - /* Make sure we own this device */ - mutex_lock(&sep->sep_mutex); - if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); - error = -EACCES; - } - mutex_unlock(&sep->sep_mutex); - - if (error) - return error; - - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Lock to prevent the daemon to interfere with operation */ - mutex_lock(&sep->ioctl_mutex); - - switch (cmd) { - case SEP_IOCSENDSEPCOMMAND: - /* Send command to SEP */ - error = sep_send_command_handler(sep); - break; - case SEP_IOCALLOCDATAPOLL: - /* Allocate data pool */ - error = sep_allocate_data_pool_memory_handler(sep, arg); - break; - case SEP_IOCGETSTATICPOOLADDR: - /* Inform the SEP the bus address of the static pool */ - error = sep_get_static_pool_addr_handler(sep); - break; - case SEP_IOCENDTRANSACTION: - error = sep_end_transaction_handler(sep); - break; - case SEP_IOCRARPREPAREMESSAGE: - error = sep_rar_prepare_output_msg_handler(sep, arg); - break; - case SEP_IOCPREPAREDCB: - error = sep_prepare_dcb_handler(sep, arg); - break; - case SEP_IOCFREEDCB: - error = sep_free_dcb_handler(sep); - break; - default: - error = -ENOTTY; - break; - } - - mutex_unlock(&sep->ioctl_mutex); - return error; -} - -/** - * sep_singleton_ioctl - ioctl api for singleton interface - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Implement the additional ioctls for the singleton device - */ -static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) -{ - long error = 0; - struct sep_device *sep = filp->private_data; - - /* Check that the command is for the SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Make sure we own this device */ - mutex_lock(&sep->sep_mutex); - if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); - mutex_unlock(&sep->sep_mutex); - return -EACCES; - } - - mutex_unlock(&sep->sep_mutex); - - switch (cmd) { - case SEP_IOCTLSETCALLERID: - mutex_lock(&sep->ioctl_mutex); - error = sep_set_caller_id_handler(sep, arg); - mutex_unlock(&sep->ioctl_mutex); - break; - default: - error = sep_ioctl(filp, cmd, arg); - break; - } - return error; -} - -/** - * sep_request_daemon_ioctl - ioctl for daemon - * @filp: pointer to struct file - * @cmd: command - * @arg: pointer to argument structure - * - * Called by the request daemon to perform ioctls on the daemon device - */ -static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, - unsigned long arg) -{ - - long error; - struct sep_device *sep = filp->private_data; - - /* Check that the command is for SEP device */ - if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) - return -ENOTTY; - - /* Only one process can access ioctl at any given time */ - mutex_lock(&sep->ioctl_mutex); - - switch (cmd) { - case SEP_IOCSENDSEPRPLYCOMMAND: - /* Send reply command to SEP */ - error = sep_req_daemon_send_reply_command_handler(sep); - break; - case SEP_IOCENDTRANSACTION: - /* - * End req daemon transaction, do nothing - * will be removed upon update in middleware - * API library - */ - error = 0; - break; - default: - error = -ENOTTY; - } - mutex_unlock(&sep->ioctl_mutex); - return error; -} - -/** - * sep_inthandler - interrupt handler - * @irq: interrupt - * @dev_id: device id - */ -static irqreturn_t sep_inthandler(int irq, void *dev_id) -{ - irqreturn_t int_error = IRQ_HANDLED; - unsigned long lck_flags; - u32 reg_val, reg_val2 = 0; - struct sep_device *sep = dev_id; - - /* Read the IRR register to check if this is SEP interrupt */ - reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); - - if (reg_val & (0x1 << 13)) { - /* Lock and update the counter of reply messages */ - spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - sep->reply_ct++; - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - - dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); - - /* Is this printf or daemon request? */ - reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, - "SEP Interrupt - reg2 is %08x\n", reg_val2); - - if ((reg_val2 >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "int: printf request\n"); - wake_up(&sep->event_request_daemon); - } else if (reg_val2 >> 31) { - dev_dbg(&sep->pdev->dev, "int: daemon request\n"); - wake_up(&sep->event_request_daemon); - } else { - dev_dbg(&sep->pdev->dev, "int: SEP reply\n"); - wake_up(&sep->event); - } - } else { - dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n"); - int_error = IRQ_NONE; - } - if (int_error == IRQ_HANDLED) - sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); - - return int_error; -} - -/** - * sep_reconfig_shared_area - reconfigure shared area - * @sep: pointer to struct sep_device - * - * Reconfig the shared area between HOST and SEP - needed in case - * the DX_CC_Init function was called before OS loading. - */ -static int sep_reconfig_shared_area(struct sep_device *sep) -{ - int ret_val; - - /* use to limit waiting for SEP */ - unsigned long end_time; - - /* Send the new SHARED MESSAGE AREA to the SEP */ - dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n", - (unsigned long long)sep->shared_bus); - - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); - - /* Poll for SEP response */ - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - end_time = jiffies + (WAIT_TIME * HZ); - - while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) && - (ret_val != sep->shared_bus)) - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - /* Check the return value (register) */ - if (ret_val != sep->shared_bus) { - dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); - dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); - ret_val = -ENOMEM; - } else - ret_val = 0; - - dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); - return ret_val; -} - -/* File operation for singleton SEP operations */ -static const struct file_operations singleton_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_singleton_ioctl, - .poll = sep_poll, - .open = sep_singleton_open, - .release = sep_singleton_release, - .mmap = sep_mmap, -}; - -/* File operation for daemon operations */ -static const struct file_operations daemon_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_request_daemon_ioctl, - .poll = sep_request_daemon_poll, - .open = sep_request_daemon_open, - .release = sep_request_daemon_release, - .mmap = sep_request_daemon_mmap, -}; - -/* The files operations structure of the driver */ -static const struct file_operations sep_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_ioctl, - .poll = sep_poll, - .open = sep_open, - .release = sep_release, - .mmap = sep_mmap, -}; - -/** - * sep_register_driver_with_fs - register misc devices - * @sep: pointer to struct sep_device - * - * This function registers the driver with the file system - */ -static int sep_register_driver_with_fs(struct sep_device *sep) -{ - int ret_val; - - sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_sep.name = SEP_DEV_NAME; - sep->miscdev_sep.fops = &sep_file_operations; - - sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_singleton.name = SEP_DEV_SINGLETON; - sep->miscdev_singleton.fops = &singleton_file_operations; - - sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_daemon.name = SEP_DEV_DAEMON; - sep->miscdev_daemon.fops = &daemon_file_operations; - - ret_val = misc_register(&sep->miscdev_sep); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", - ret_val); - return ret_val; - } - - ret_val = misc_register(&sep->miscdev_singleton); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - return ret_val; - } - - ret_val = misc_register(&sep->miscdev_daemon); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - - return ret_val; - } - return ret_val; -} - - -/** - * sep_probe - probe a matching PCI device - * @pdev: pci_device - * @end: pci_device_id - * - * Attempt to set up and configure a SEP device that has been - * discovered by the PCI layer. - */ -static int __devinit sep_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - int error = 0; - struct sep_device *sep; - - if (sep_dev != NULL) { - dev_warn(&pdev->dev, "only one SEP supported.\n"); - return -EBUSY; - } - - /* Enable the device */ - error = pci_enable_device(pdev); - if (error) { - dev_warn(&pdev->dev, "error enabling pci device\n"); - goto end_function; - } - - /* Allocate the sep_device structure for this device */ - sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); - if (sep_dev == NULL) { - dev_warn(&pdev->dev, - "can't kmalloc the sep_device structure\n"); - error = -ENOMEM; - goto end_function_disable_device; - } - - /* - * We're going to use another variable for actually - * working with the device; this way, if we have - * multiple devices in the future, it would be easier - * to make appropriate changes - */ - sep = sep_dev; - - sep->pdev = pci_dev_get(pdev); - - init_waitqueue_head(&sep->event); - init_waitqueue_head(&sep->event_request_daemon); - spin_lock_init(&sep->snd_rply_lck); - mutex_init(&sep->sep_mutex); - mutex_init(&sep->ioctl_mutex); - - dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, device being prepared\n"); - dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); - - /* Set up our register area */ - sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); - if (!sep->reg_physical_addr) { - dev_warn(&sep->pdev->dev, "Error getting register start\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - sep->reg_physical_end = pci_resource_end(sep->pdev, 0); - if (!sep->reg_physical_end) { - dev_warn(&sep->pdev->dev, "Error getting register end\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, - (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); - if (!sep->reg_addr) { - dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); - error = -ENODEV; - goto end_function_free_sep_dev; - } - - dev_dbg(&sep->pdev->dev, - "Register area start %llx end %llx virtual %p\n", - (unsigned long long)sep->reg_physical_addr, - (unsigned long long)sep->reg_physical_end, - sep->reg_addr); - - /* Allocate the shared area */ - sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + - SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + - SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + - SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + - SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; - - if (sep_map_and_alloc_shared_area(sep)) { - error = -ENOMEM; - /* Allocation failed */ - goto end_function_error; - } - - /* Clear ICR register */ - sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); - - /* Set the IMR register - open only GPR 2 */ - sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); - - /* Read send/receive counters from SEP */ - sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - sep->reply_ct &= 0x3FFFFFFF; - sep->send_ct = sep->reply_ct; - - /* Get the interrupt line */ - error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, - "sep_driver", sep); - - if (error) - goto end_function_deallocate_sep_shared_area; - - /* The new chip requires a shared area reconfigure */ - if (sep->pdev->revision == 4) { /* Only for new chip */ - error = sep_reconfig_shared_area(sep); - if (error) - goto end_function_free_irq; - } - /* Finally magic up the device nodes */ - /* Register driver with the fs */ - error = sep_register_driver_with_fs(sep); - if (error == 0) - /* Success */ - return 0; - -end_function_free_irq: - free_irq(pdev->irq, sep); - -end_function_deallocate_sep_shared_area: - /* De-allocate shared area */ - sep_unmap_and_free_shared_area(sep); - -end_function_error: - iounmap(sep->reg_addr); - -end_function_free_sep_dev: - pci_dev_put(sep_dev->pdev); - kfree(sep_dev); - sep_dev = NULL; - -end_function_disable_device: - pci_disable_device(pdev); - -end_function: - return error; -} - -static void sep_remove(struct pci_dev *pdev) -{ - struct sep_device *sep = sep_dev; - - /* Unregister from fs */ - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - misc_deregister(&sep->miscdev_daemon); - - /* Free the irq */ - free_irq(sep->pdev->irq, sep); - - /* Free the shared area */ - sep_unmap_and_free_shared_area(sep_dev); - iounmap((void *) sep_dev->reg_addr); -} - -static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, - {0} -}; - -MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); - -/* Field for registering driver to PCI device */ -static struct pci_driver sep_pci_driver = { - .name = "sep_sec_driver", - .id_table = sep_pci_id_tbl, - .probe = sep_probe, - .remove = sep_remove -}; - - -/** - * sep_init - init function - * - * Module load time. Register the PCI device driver. - */ -static int __init sep_init(void) -{ - return pci_register_driver(&sep_pci_driver); -} - - -/** - * sep_exit - called to unload driver - * - * Drop the misc devices then remove and unmap the various resources - * that are not released by the driver remove method. - */ -static void __exit sep_exit(void) -{ - pci_unregister_driver(&sep_pci_driver); -} - - -module_init(sep_init); -module_exit(sep_exit); - -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index c3aacfcc8ac..78a4b69d3fd 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -2,8 +2,8 @@ * * sep_driver_api.h - Security Processor Driver api definitions * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,6 +26,7 @@ * CHANGES: * * 2010.09.14 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -37,26 +38,30 @@ #define SEP_DRIVER_SRC_REQ 2 #define SEP_DRIVER_SRC_PRINTF 3 - -/*------------------------------------------- - TYPEDEFS -----------------------------------------------*/ - -struct alloc_struct { - /* offset from start of shared pool area */ - u32 offset; - /* number of bytes to allocate */ - u32 num_bytes; -}; - -/* command struct for getting caller id value and address */ -struct caller_id_struct { - /* pid of the process */ - u32 pid; - /* virtual address of the caller id hash */ - aligned_u64 callerIdAddress; - /* caller id hash size in bytes */ - u32 callerIdSizeInBytes; +/* Power state */ +#define SEP_DRIVER_POWERON 1 +#define SEP_DRIVER_POWEROFF 2 + +/* Following enums are used only for kernel crypto api */ +enum type_of_request { + NO_REQUEST, + AES_CBC, + AES_ECB, + DES_CBC, + DES_ECB, + DES3_ECB, + DES3_CBC, + SHA1, + MD5, + SHA224, + SHA256 + }; + +enum hash_stage { + HASH_INIT, + HASH_UPDATE, + HASH_FINISH, + HASH_DIGEST }; /* @@ -83,11 +88,6 @@ struct sep_dcblock { u8 tail_data[68]; }; -struct sep_caller_id_entry { - int pid; - unsigned char callerIdHash[SEP_CALLER_ID_HASH_SIZE_IN_BYTES]; -}; - /* command structure for building dcb block (currently for ext app only */ @@ -104,6 +104,33 @@ struct build_dcb_struct { /* the size of the block of the operation - if needed, every table will be modulo this parameter */ u32 tail_block_size; + + /* which application calls the driver DX or applet */ + u32 is_applet; +}; + +/* + command structure for building dcb block for kernel crypto +*/ +struct build_dcb_struct_kernel { + /* address value of the data in */ + void *app_in_address; + /* size of data in */ + ssize_t data_in_size; + /* address of the data out */ + void *app_out_address; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 block_size; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 tail_block_size; + + /* which application calls the driver DX or applet */ + u32 is_applet; + + struct scatterlist *src_sg; + struct scatterlist *dst_sg; }; /** @@ -147,6 +174,10 @@ struct sep_dma_resource { /* number of entries of the output mapp array */ u32 out_map_num_entries; + + /* Scatter list for kernel operations */ + struct scatterlist *src_sg; + struct scatterlist *dst_sg; }; @@ -169,47 +200,190 @@ struct sep_lli_entry { u32 block_size; }; -/*---------------------------------------------------------------- - IOCTL command defines - -----------------------------------------------------------------*/ +/* + * header format for each fastcall write operation + */ +struct sep_fastcall_hdr { + u32 magic; + u32 msg_len; + u32 num_dcbs; +}; -/* magic number 1 of the sep IOCTL command */ -#define SEP_IOC_MAGIC_NUMBER 's' +/* + * structure used in file pointer's private data field + * to track the status of the calls to the various + * driver interface + */ +struct sep_call_status { + unsigned long status; +}; -/* sends interrupt to sep that message is ready */ -#define SEP_IOCSENDSEPCOMMAND \ - _IO(SEP_IOC_MAGIC_NUMBER, 0) +/* + * format of dma context buffer used to store all DMA-related + * context information of a particular transaction + */ +struct sep_dma_context { + /* number of data control blocks */ + u32 nr_dcb_creat; + /* number of the lli tables created in the current transaction */ + u32 num_lli_tables_created; + /* size of currently allocated dma tables region */ + u32 dmatables_len; + /* size of input data */ + u32 input_data_len; + struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; + /* Scatter gather for kernel crypto */ + struct scatterlist *src_sg; + struct scatterlist *dst_sg; +}; -/* sends interrupt to sep that message is ready */ -#define SEP_IOCSENDSEPRPLYCOMMAND \ - _IO(SEP_IOC_MAGIC_NUMBER, 1) +/* + * format for file pointer's private_data field + */ +struct sep_private_data { + struct sep_queue_info *my_queue_elem; + struct sep_device *device; + struct sep_call_status call_status; + struct sep_dma_context *dma_ctx; +}; + + +/* Functions used by sep_crypto */ + +/** + * sep_queue_status_remove - Removes transaction from status queue + * @sep: SEP device + * @sep_queue_info: pointer to status queue + * + * This function will removes information about transaction from the queue. + */ +void sep_queue_status_remove(struct sep_device *sep, + struct sep_queue_info **queue_elem); +/** + * sep_queue_status_add - Adds transaction to status queue + * @sep: SEP device + * @opcode: transaction opcode + * @size: input data size + * @pid: pid of current process + * @name: current process name + * @name_len: length of name (current process) + * + * This function adds information about about transaction started to the status + * queue. + */ +struct sep_queue_info *sep_queue_status_add( + struct sep_device *sep, + u32 opcode, + u32 size, + u32 pid, + u8 *name, size_t name_len); -/* allocate memory in data pool */ -#define SEP_IOCALLOCDATAPOLL \ - _IOW(SEP_IOC_MAGIC_NUMBER, 2, struct alloc_struct) +/** + * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context + * for kernel crypto + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + */ +int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct_kernel *dcb_data, + const u32 num_dcbs); -/* free dynamic data aalocated during table creation */ -#define SEP_IOCFREEDMATABLEDATA \ - _IO(SEP_IOC_MAGIC_NUMBER, 7) +/** + * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables + * contexts into use + * @sep: SEP device + * @dcb_region: DCB region copy + * @dmatables_region: MLLI/DMA tables copy + * @dma_ctx: DMA context for current transaction + */ +ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context *dma_ctx); -/* get the static pool area addersses (physical and virtual) */ -#define SEP_IOCGETSTATICPOOLADDR \ - _IO(SEP_IOC_MAGIC_NUMBER, 8) +/** + * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks + * @app_in_address: unsigned long; for data buffer in (user space) + * @app_out_address: unsigned long; for data buffer out (user space) + * @data_in_size: u32; for size of data + * @block_size: u32; for block size + * @tail_block_size: u32; for size of tail block + * @isapplet: bool; to indicate external app + * @is_kva: bool; kernel buffer; only used for kernel crypto module + * + * This function prepares the linked DMA tables and puts the + * address for the linked list of tables inta a DCB (data control + * block) the address of which is known by the SEP hardware + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, + unsigned long app_in_address, + unsigned long app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva, + struct sep_dcblock *dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + struct scatterlist *src_sg, + struct scatterlist *dst_sg); + +/** + * sep_free_dma_table_data_handler - free DMA table + * @sep: pointere to struct sep_device + * @dma_ctx: dma context + * + * Handles the request to free DMA table for synchronic actions + */ +int sep_free_dma_table_data_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx); +/** + * sep_send_command_handler - kick off a command + * @sep: SEP being signalled + * + * This function raises interrupt to SEP that signals that is has a new + * command from the host + * + * Note that this function does fall under the ioctl lock + */ +int sep_send_command_handler(struct sep_device *sep); + +/** + * sep_wait_transaction - Used for synchronizing transactions + * @sep: SEP device + */ +int sep_wait_transaction(struct sep_device *sep); + +/** + * IOCTL command defines + */ +/* magic number 1 of the sep IOCTL command */ +#define SEP_IOC_MAGIC_NUMBER 's' + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPCOMMAND \ + _IO(SEP_IOC_MAGIC_NUMBER, 0) /* end transaction command */ #define SEP_IOCENDTRANSACTION \ _IO(SEP_IOC_MAGIC_NUMBER, 15) -#define SEP_IOCRARPREPAREMESSAGE \ - _IOW(SEP_IOC_MAGIC_NUMBER, 20, struct rar_hndl_to_bus_struct) - -#define SEP_IOCTLSETCALLERID \ - _IOW(SEP_IOC_MAGIC_NUMBER, 34, struct caller_id_struct) - #define SEP_IOCPREPAREDCB \ _IOW(SEP_IOC_MAGIC_NUMBER, 35, struct build_dcb_struct) #define SEP_IOCFREEDCB \ _IO(SEP_IOC_MAGIC_NUMBER, 36) +struct sep_device; + #endif diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index d6bfd245522..fa7c0d09bfa 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -2,8 +2,8 @@ * * sep_driver_config.h - Security Processor Driver configuration * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,6 +26,7 @@ * CHANGES: * * 2010.06.26 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -48,6 +49,8 @@ /* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ #define SEP_DRIVER_ARM_DEBUG_MODE 0 +/* Critical message area contents for sanity checking */ +#define SEP_START_MSG_TOKEN 0x02558808 /*------------------------------------------- INTERNAL DATA CONFIGURATION -------------------------------------------*/ @@ -65,21 +68,17 @@ #define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 /* flag that signifies tah the lock is -currently held by the process (struct file) */ +currently held by the proccess (struct file) */ #define SEP_DRIVER_OWN_LOCK_FLAG 1 /* flag that signifies tah the lock is currently NOT -held by the process (struct file) */ +held by the proccess (struct file) */ #define SEP_DRIVER_DISOWN_LOCK_FLAG 0 /* indicates whether driver has mapped/unmapped shared area */ #define SEP_REQUEST_DAEMON_MAPPED 1 #define SEP_REQUEST_DAEMON_UNMAPPED 0 -#define SEP_DEV_NAME "sep_sec_driver" -#define SEP_DEV_SINGLETON "sep_sec_singleton_driver" -#define SEP_DEV_DAEMON "sep_req_daemon_driver" - /*-------------------------------------------------------- SHARED AREA memory total size is 36K it is divided is following: @@ -90,7 +89,7 @@ held by the process (struct file) */ } DATA_POOL_AREA 12K } - SYNCHRONIC_DMA_TABLES_AREA 5K + SYNCHRONIC_DMA_TABLES_AREA 29K placeholder until drver changes FLOW_DMA_TABLES_AREA 4K @@ -108,6 +107,12 @@ held by the process (struct file) */ #define SEP_DEV_DAEMON "sep_req_daemon_driver" +/* + the minimum length of the message - includes 2 reserved fields + at the start, then token, message size and opcode fields. all dwords +*/ +#define SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES (5*sizeof(u32)) + /* the maximum length of the message - the rest of the message shared area will be dedicated to the dma lli tables @@ -124,7 +129,7 @@ held by the process (struct file) */ #define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (16 * 1024) /* the size of the message shared area in pages */ -#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 5) +#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 29) /* Placeholder until driver changes */ #define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) @@ -132,6 +137,9 @@ held by the process (struct file) */ /* system data (time, caller id etc') pool */ #define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES (1024 * 3) +/* Offset of the sep printf buffer in the message area */ +#define SEP_DRIVER_PRINTF_OFFSET_IN_BYTES (5888) + /* the size in bytes of the time memory */ #define SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES 8 @@ -223,10 +231,10 @@ held by the process (struct file) */ #define SEP_ALREADY_INITIALIZED_ERR 12 /* bit that locks access to the shared area */ -#define SEP_MMAP_LOCK_BIT 0 +#define SEP_TRANSACTION_STARTED_LOCK_BIT 0 /* bit that lock access to the poll - after send_command */ -#define SEP_SEND_MSG_LOCK_BIT 1 +#define SEP_WORKING_LOCK_BIT 1 /* the token that defines the static pool address address */ #define SEP_STATIC_POOL_VAL_TOKEN 0xABBAABBA @@ -240,4 +248,51 @@ held by the process (struct file) */ /* Time limit for SEP to finish */ #define WAIT_TIME 10 +/* Delay for pm runtime suspend (reduces pm thrashing with bursty traffic */ +#define SUSPEND_DELAY 10 + +/* Number of delays to wait until scu boots after runtime resume */ +#define SCU_DELAY_MAX 50 + +/* Delay for each iteration (usec) wait for scu boots after runtime resume */ +#define SCU_DELAY_ITERATION 10 + + +/* + * Bits used in struct sep_call_status to check that + * driver's APIs are called in valid order + */ + +/* Bit offset which indicates status of sep_write() */ +#define SEP_FASTCALL_WRITE_DONE_OFFSET 0 + +/* Bit offset which indicates status of sep_mmap() */ +#define SEP_LEGACY_MMAP_DONE_OFFSET 1 + +/* Bit offset which indicates status of the SEP_IOCSENDSEPCOMMAND ioctl */ +#define SEP_LEGACY_SENDMSG_DONE_OFFSET 2 + +/* Bit offset which indicates status of sep_poll() */ +#define SEP_LEGACY_POLL_DONE_OFFSET 3 + +/* Bit offset which indicates status of the SEP_IOCENDTRANSACTION ioctl */ +#define SEP_LEGACY_ENDTRANSACTION_DONE_OFFSET 4 + +/* + * Used to limit number of concurrent processes + * allowed to allocte dynamic buffers in fastcall + * interface. + */ +#define SEP_DOUBLEBUF_USERS_LIMIT 3 + +/* Identifier for valid fastcall header */ +#define SEP_FC_MAGIC 0xFFAACCAA + +/* + * Used for enabling driver runtime power management. + * Useful for enabling/disabling it during performance + * testing + */ +#define SEP_ENABLE_RUNTIME_PM + #endif /* SEP DRIVER CONFIG */ diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h index 300f90963de..c48e49a741b 100644 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -2,8 +2,8 @@ * * sep_driver_hw_defs.h - Security Processor Driver hardware definitions * - * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. - * Contributions(c) 2009,2010 Discretix. All rights reserved. + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -26,6 +26,7 @@ * CHANGES: * * 2010.09.20 Upgrade to Medfield + * 2011.02.22 Enable kernel crypto * */ @@ -42,181 +43,9 @@ /* cf registers */ -#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL -#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL -#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL -#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL -#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL -#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL -#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL -#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL -#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL -#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL -#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL -#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL -#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL -#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL -#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL -#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL -#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL -#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL -#define HW_R3B_REG_ADDR 0x00C0UL -#define HW_R4B_REG_ADDR 0x0100UL -#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL -#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL -#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL -#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL -#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL -#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL -#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL -#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL -#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL -#define HW_CSA_REG_ADDR 0x0140UL -#define HW_SINB_REG_ADDR 0x0180UL -#define HW_SOUTB_REG_ADDR 0x0184UL -#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL -#define HW_PKI_STATUS_REG_ADDR 0x01C4UL -#define HW_PKI_BUSY_REG_ADDR 0x01C8UL -#define HW_PKI_A_1025_REG_ADDR 0x01CCUL -#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL -#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL -#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL -#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL -#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL -#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL -#define HW_PKI_CLR_REG_ADDR 0x01E8UL -#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL -#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL -#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL -#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL -#define HW_DES_KEY_0_REG_ADDR 0x0208UL -#define HW_DES_KEY_1_REG_ADDR 0x020CUL -#define HW_DES_KEY_2_REG_ADDR 0x0210UL -#define HW_DES_KEY_3_REG_ADDR 0x0214UL -#define HW_DES_KEY_4_REG_ADDR 0x0218UL -#define HW_DES_KEY_5_REG_ADDR 0x021CUL -#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL -#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL -#define HW_DES_IV_0_REG_ADDR 0x0228UL -#define HW_DES_IV_1_REG_ADDR 0x022CUL -#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL -#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL -#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL -#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL -#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL -#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL -#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL -#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL -#define HW_AES_KEY_0_REG_ADDR 0x0400UL -#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL -#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL -#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL -#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL -#define HW_AES_IV_0_REG_ADDR 0x0440UL -#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL -#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL -#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL -#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL -#define HW_AES_CTR1_REG_ADDR 0x0460UL -#define HW_AES_SK_REG_ADDR 0x0478UL -#define HW_AES_MAC_OK_REG_ADDR 0x0480UL -#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL -#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL -#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL -#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL -#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL -#define HW_AES_CONTROL_REG_ADDR 0x04C0UL -#define HW_HASH_H0_REG_ADDR 0x0640UL -#define HW_HASH_H1_REG_ADDR 0x0644UL -#define HW_HASH_H2_REG_ADDR 0x0648UL -#define HW_HASH_H3_REG_ADDR 0x064CUL -#define HW_HASH_H4_REG_ADDR 0x0650UL -#define HW_HASH_H5_REG_ADDR 0x0654UL -#define HW_HASH_H6_REG_ADDR 0x0658UL -#define HW_HASH_H7_REG_ADDR 0x065CUL -#define HW_HASH_H8_REG_ADDR 0x0660UL -#define HW_HASH_H9_REG_ADDR 0x0664UL -#define HW_HASH_H10_REG_ADDR 0x0668UL -#define HW_HASH_H11_REG_ADDR 0x066CUL -#define HW_HASH_H12_REG_ADDR 0x0670UL -#define HW_HASH_H13_REG_ADDR 0x0674UL -#define HW_HASH_H14_REG_ADDR 0x0678UL -#define HW_HASH_H15_REG_ADDR 0x067CUL -#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL -#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL -#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL -#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL -#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL -#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL -#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL -#define HW_HASH_PARAM_REG_ADDR 0x07DCUL -#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL -#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL -#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL -#define HW_HASH_DATA_REG_ADDR 0x07ECUL -#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL -#define HW_DRNG_VALID_REG_ADDR 0x0804UL -#define HW_DRNG_DATA_REG_ADDR 0x0808UL -#define HW_RND_SRC_EN_REG_ADDR 0x080CUL -#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL -#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL -#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL -#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL -#define HW_CLK_STATUS_REG_ADDR 0x0824UL -#define HW_CLK_ENABLE_REG_ADDR 0x0828UL -#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL -#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL -#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL -#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL -#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL -#define HW_AES_BUSY_REG_ADDR 0x0914UL -#define HW_DES_BUSY_REG_ADDR 0x0918UL -#define HW_HASH_BUSY_REG_ADDR 0x091CUL -#define HW_CONTENT_REG_ADDR 0x0924UL -#define HW_VERSION_REG_ADDR 0x0928UL -#define HW_CONTEXT_ID_REG_ADDR 0x0930UL -#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL -#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL -#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL -#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL -#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL -#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL -#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL -#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL -#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL -#define HW_OLD_DATA_REG_ADDR 0x0C48UL -#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL -#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL -#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL -#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL -#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL -#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL -#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL -#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL -#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL -#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL -#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL -#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL -#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL -#define HW_SRAM_DATA_REG_ADDR 0x0F00UL -#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL -#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL #define HW_HOST_IRR_REG_ADDR 0x0A00UL #define HW_HOST_IMR_REG_ADDR 0x0A04UL #define HW_HOST_ICR_REG_ADDR 0x0A08UL -#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL -#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL -#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL -#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL -#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL -#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL -#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL -#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL -#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL -#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL -#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL -#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL -#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL #define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL #define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL #define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL @@ -225,9 +54,6 @@ #define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL #define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL #define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL -#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL -#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL -#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL -#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL +#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL #endif /* ifndef HW_DEFS */ diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c new file mode 100644 index 00000000000..0defb0ad4c8 --- /dev/null +++ b/drivers/staging/sep/sep_main.c @@ -0,0 +1,4286 @@ +/* + * + * sep_main.c - Security Processor Driver main group of functions + * + * Copyright(c) 2009-2011 Intel Corporation. All rights reserved. + * Contributions(c) 2009-2011 Discretix. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2010.09.14 Upgrade to Medfield + * 2011.01.21 Move to sep_main.c to allow for sep_crypto.c + * 2011.02.22 Enable kernel crypto operation + * + * Please note that this driver is based on information in the Discretix + * CryptoCell 5.2 Driver Implementation Guide; the Discretix CryptoCell 5.2 + * Integration Intel Medfield appendix; the Discretix CryptoCell 5.2 + * Linux Driver Integration Guide; and the Discretix CryptoCell 5.2 System + * Overview and Integration Guide. + */ +/* #define DEBUG */ +/* #define SEP_PERF_DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_dev.h" +#include "sep_crypto.h" + +#define CREATE_TRACE_POINTS +#include "sep_trace_events.h" + +/* + * Let's not spend cycles iterating over message + * area contents if debugging not enabled + */ +#ifdef DEBUG +#define sep_dump_message(sep) _sep_dump_message(sep) +#else +#define sep_dump_message(sep) +#endif + +/** + * Currenlty, there is only one SEP device per platform; + * In event platforms in the future have more than one SEP + * device, this will be a linked list + */ + +struct sep_device *sep_dev; + +/** + * sep_queue_status_remove - Removes transaction from status queue + * @sep: SEP device + * @sep_queue_info: pointer to status queue + * + * This function will removes information about transaction from the queue. + */ +void sep_queue_status_remove(struct sep_device *sep, + struct sep_queue_info **queue_elem) +{ + unsigned long lck_flags; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove\n", + current->pid); + + if (!queue_elem || !(*queue_elem)) { + dev_dbg(&sep->pdev->dev, "PID%d %s null\n", + current->pid, __func__); + return; + } + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + list_del(&(*queue_elem)->list); + sep->sep_queue_num--; + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + kfree(*queue_elem); + *queue_elem = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_queue_status_remove return\n", + current->pid); + return; +} + +/** + * sep_queue_status_add - Adds transaction to status queue + * @sep: SEP device + * @opcode: transaction opcode + * @size: input data size + * @pid: pid of current process + * @name: current process name + * @name_len: length of name (current process) + * + * This function adds information about about transaction started to the status + * queue. + */ +struct sep_queue_info *sep_queue_status_add( + struct sep_device *sep, + u32 opcode, + u32 size, + u32 pid, + u8 *name, size_t name_len) +{ + unsigned long lck_flags; + struct sep_queue_info *my_elem = NULL; + + my_elem = kzalloc(sizeof(struct sep_queue_info), GFP_KERNEL); + + if (!my_elem) + return NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] kzalloc ok\n", current->pid); + + my_elem->data.opcode = opcode; + my_elem->data.size = size; + my_elem->data.pid = pid; + + if (name_len > TASK_COMM_LEN) + name_len = TASK_COMM_LEN; + + memcpy(&my_elem->data.name, name, name_len); + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + + list_add_tail(&my_elem->list, &sep->sep_queue_status); + sep->sep_queue_num++; + + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + return my_elem; +} + +/** + * sep_allocate_dmatables_region - Allocates buf for the MLLI/DMA tables + * @sep: SEP device + * @dmatables_region: Destination pointer for the buffer + * @dma_ctx: DMA context for the transaction + * @table_count: Number of MLLI/DMA tables to create + * The buffer created will not work as-is for DMA operations, + * it needs to be copied over to the appropriate place in the + * shared area. + */ +static int sep_allocate_dmatables_region(struct sep_device *sep, + void **dmatables_region, + struct sep_dma_context *dma_ctx, + const u32 table_count) +{ + const size_t new_len = table_count * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + void *tmp_region = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] dma_ctx = 0x%p\n", + current->pid, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] dmatables_region = 0x%p\n", + current->pid, dmatables_region); + + if (!dma_ctx || !dmatables_region) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma context/region uninitialized\n", + current->pid); + return -EINVAL; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08X\n", + current->pid, new_len); + dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid, + dma_ctx->dmatables_len); + tmp_region = kzalloc(new_len + dma_ctx->dmatables_len, GFP_KERNEL); + if (!tmp_region) { + dev_warn(&sep->pdev->dev, + "[PID%d] no mem for dma tables region\n", + current->pid); + return -ENOMEM; + } + + /* Were there any previous tables that need to be preserved ? */ + if (*dmatables_region) { + memcpy(tmp_region, *dmatables_region, dma_ctx->dmatables_len); + kfree(*dmatables_region); + } + + *dmatables_region = tmp_region; + + dma_ctx->dmatables_len += new_len; + + return 0; +} + +/** + * sep_wait_transaction - Used for synchronizing transactions + * @sep: SEP device + */ +int sep_wait_transaction(struct sep_device *sep) +{ + int error = 0; + DEFINE_WAIT(wait); + + if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sep->in_use_flags)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] no transactions, returning\n", + current->pid); + goto end_function_setpid; + } + + /* + * Looping needed even for exclusive waitq entries + * due to process wakeup latencies, previous process + * might have already created another transaction. + */ + for (;;) { + /* + * Exclusive waitq entry, so that only one process is + * woken up from the queue at a time. + */ + prepare_to_wait_exclusive(&sep->event_transactions, + &wait, + TASK_INTERRUPTIBLE); + if (0 == test_and_set_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, + &sep->in_use_flags)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] no transactions, breaking\n", + current->pid); + break; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] transactions ongoing, sleeping\n", + current->pid); + schedule(); + dev_dbg(&sep->pdev->dev, "[PID%d] woken up\n", current->pid); + + if (signal_pending(current)) { + dev_dbg(&sep->pdev->dev, "[PID%d] received signal\n", + current->pid); + error = -EINTR; + goto end_function; + } + } +end_function_setpid: + /* + * The pid_doing_transaction indicates that this process + * now owns the facilities to performa a transaction with + * the SEP. While this process is performing a transaction, + * no other process who has the SEP device open can perform + * any transactions. This method allows more than one process + * to have the device open at any given time, which provides + * finer granularity for device utilization by multiple + * processes. + */ + /* Only one process is able to progress here at a time */ + sep->pid_doing_transaction = current->pid; + +end_function: + finish_wait(&sep->event_transactions, &wait); + + return error; +} + +/** + * sep_check_transaction_owner - Checks if current process owns transaction + * @sep: SEP device + */ +static inline int sep_check_transaction_owner(struct sep_device *sep) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] transaction pid = %d\n", + current->pid, + sep->pid_doing_transaction); + + if ((sep->pid_doing_transaction == 0) || + (current->pid != sep->pid_doing_transaction)) { + return -EACCES; + } + + /* We own the transaction */ + return 0; +} + +#ifdef DEBUG + +/** + * sep_dump_message - dump the message that is pending + * @sep: SEP device + * This will only print dump if DEBUG is set; it does + * follow kernel debug print enabling + */ +static void _sep_dump_message(struct sep_device *sep) +{ + int count; + + u32 *p = sep->shared_addr; + + for (count = 0; count < 40 * 4; count += 4) + dev_dbg(&sep->pdev->dev, + "[PID%d] Word %d of the message is %x\n", + current->pid, count/4, *p++); +} +#endif + +/** + * sep_map_and_alloc_shared_area -allocate shared block + * @sep: security processor + * @size: size of shared area + */ +static int sep_map_and_alloc_shared_area(struct sep_device *sep) +{ + sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, + sep->shared_size, + &sep->shared_bus, GFP_KERNEL); + + if (!sep->shared_addr) { + dev_dbg(&sep->pdev->dev, + "[PID%d] shared memory dma_alloc_coherent failed\n", + current->pid); + return -ENOMEM; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] shared_addr %zx bytes @%p (bus %llx)\n", + current->pid, + sep->shared_size, sep->shared_addr, + (unsigned long long)sep->shared_bus); + return 0; +} + +/** + * sep_unmap_and_free_shared_area - free shared block + * @sep: security processor + */ +static void sep_unmap_and_free_shared_area(struct sep_device *sep) +{ + dma_free_coherent(&sep->pdev->dev, sep->shared_size, + sep->shared_addr, sep->shared_bus); +} + +/** + * sep_shared_bus_to_virt - convert bus/virt addresses + * @sep: pointer to struct sep_device + * @bus_address: address to convert + * + * Returns virtual address inside the shared area according + * to the bus address. + */ +static void *sep_shared_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + return sep->shared_addr + (bus_address - sep->shared_bus); +} + +/** + * sep_open - device open method + * @inode: inode of SEP device + * @filp: file handle to SEP device + * + * Open method for the SEP device. Called when userspace opens + * the SEP device node. + * + * Returns zero on success otherwise an error code. + */ +static int sep_open(struct inode *inode, struct file *filp) +{ + struct sep_device *sep; + struct sep_private_data *priv; + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] open\n", current->pid); + + if (filp->f_flags & O_NONBLOCK) + return -ENOTSUPP; + + /* + * Get the SEP device structure and use it for the + * private_data field in filp for other methods + */ + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sep = sep_dev; + priv->device = sep; + filp->private_data = priv; + + dev_dbg(&sep_dev->pdev->dev, "[PID%d] priv is 0x%p\n", + current->pid, priv); + + /* Anyone can open; locking takes place at transaction level */ + return 0; +} + +/** + * sep_free_dma_table_data_handler - free DMA table + * @sep: pointere to struct sep_device + * @dma_ctx: dma context + * + * Handles the request to free DMA table for synchronic actions + */ +int sep_free_dma_table_data_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx) +{ + int count; + int dcb_counter; + /* Pointer to the current dma_resource struct */ + struct sep_dma_resource *dma; + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_free_dma_table_data_handler\n", + current->pid); + + if (!dma_ctx || !(*dma_ctx)) { + /* No context or context already freed */ + dev_dbg(&sep->pdev->dev, + "[PID%d] no DMA context or context already freed\n", + current->pid); + + return 0; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] (*dma_ctx)->nr_dcb_creat 0x%x\n", + current->pid, + (*dma_ctx)->nr_dcb_creat); + + for (dcb_counter = 0; + dcb_counter < (*dma_ctx)->nr_dcb_creat; dcb_counter++) { + dma = &(*dma_ctx)->dma_res_arr[dcb_counter]; + + /* Unmap and free input map array */ + if (dma->in_map_array) { + for (count = 0; count < dma->in_num_pages; count++) { + dma_unmap_page(&sep->pdev->dev, + dma->in_map_array[count].dma_addr, + dma->in_map_array[count].size, + DMA_TO_DEVICE); + } + kfree(dma->in_map_array); + } + + /* Unmap output map array, DON'T free it yet */ + if (dma->out_map_array) { + for (count = 0; count < dma->out_num_pages; count++) { + dma_unmap_page(&sep->pdev->dev, + dma->out_map_array[count].dma_addr, + dma->out_map_array[count].size, + DMA_FROM_DEVICE); + } + kfree(dma->out_map_array); + } + + /* Free page cache for output */ + if (dma->in_page_array) { + for (count = 0; count < dma->in_num_pages; count++) { + flush_dcache_page(dma->in_page_array[count]); + page_cache_release(dma->in_page_array[count]); + } + kfree(dma->in_page_array); + } + + if (dma->out_page_array) { + for (count = 0; count < dma->out_num_pages; count++) { + if (!PageReserved(dma->out_page_array[count])) + + SetPageDirty(dma-> + out_page_array[count]); + + flush_dcache_page(dma->out_page_array[count]); + page_cache_release(dma->out_page_array[count]); + } + kfree(dma->out_page_array); + } + + /** + * Note that here we use in_map_num_entries because we + * don't have a page array; the page array is generated + * only in the lock_user_pages, which is not called + * for kernel crypto, which is what the sg (scatter gather + * is used for exclusively + */ + if (dma->src_sg) { + dma_unmap_sg(&sep->pdev->dev, dma->src_sg, + dma->in_map_num_entries, DMA_TO_DEVICE); + dma->src_sg = NULL; + } + + if (dma->dst_sg) { + dma_unmap_sg(&sep->pdev->dev, dma->dst_sg, + dma->in_map_num_entries, DMA_FROM_DEVICE); + dma->dst_sg = NULL; + } + + /* Reset all the values */ + dma->in_page_array = NULL; + dma->out_page_array = NULL; + dma->in_num_pages = 0; + dma->out_num_pages = 0; + dma->in_map_array = NULL; + dma->out_map_array = NULL; + dma->in_map_num_entries = 0; + dma->out_map_num_entries = 0; + } + + (*dma_ctx)->nr_dcb_creat = 0; + (*dma_ctx)->num_lli_tables_created = 0; + + kfree(*dma_ctx); + *dma_ctx = NULL; + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_free_dma_table_data_handler end\n", + current->pid); + + return 0; +} + +/** + * sep_end_transaction_handler - end transaction + * @sep: pointer to struct sep_device + * @dma_ctx: DMA context + * @call_status: Call status + * + * This API handles the end transaction request. + */ +static int sep_end_transaction_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx, + struct sep_call_status *call_status, + struct sep_queue_info **my_queue_elem) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] ending transaction\n", current->pid); + + /* + * Extraneous transaction clearing would mess up PM + * device usage counters and SEP would get suspended + * just before we send a command to SEP in the next + * transaction + * */ + if (sep_check_transaction_owner(sep)) { + dev_dbg(&sep->pdev->dev, "[PID%d] not transaction owner\n", + current->pid); + return 0; + } + + /* Update queue status */ + sep_queue_status_remove(sep, my_queue_elem); + + /* Check that all the DMA resources were freed */ + if (dma_ctx) + sep_free_dma_table_data_handler(sep, dma_ctx); + + /* Reset call status for next transaction */ + if (call_status) + call_status->status = 0; + + /* Clear the message area to avoid next transaction reading + * sensitive results from previous transaction */ + memset(sep->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* start suspend delay */ +#ifdef SEP_ENABLE_RUNTIME_PM + if (sep->in_use) { + sep->in_use = 0; + pm_runtime_mark_last_busy(&sep->pdev->dev); + pm_runtime_put_autosuspend(&sep->pdev->dev); + } +#endif + + clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags); + sep->pid_doing_transaction = 0; + + /* Now it's safe for next process to proceed */ + dev_dbg(&sep->pdev->dev, "[PID%d] waking up next transaction\n", + current->pid); + clear_bit(SEP_TRANSACTION_STARTED_LOCK_BIT, &sep->in_use_flags); + wake_up(&sep->event_transactions); + + return 0; +} + + +/** + * sep_release - close a SEP device + * @inode: inode of SEP device + * @filp: file handle being closed + * + * Called on the final close of a SEP device. + */ +static int sep_release(struct inode *inode, struct file *filp) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + + dev_dbg(&sep->pdev->dev, "[PID%d] release\n", current->pid); + + sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + + kfree(filp->private_data); + + return 0; +} + +/** + * sep_mmap - maps the shared area to user space + * @filp: pointer to struct file + * @vma: pointer to vm_area_struct + * + * Called on an mmap of our space via the normal SEP device + */ +static int sep_mmap(struct file *filp, struct vm_area_struct *vma) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + dma_addr_t bus_addr; + unsigned long error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_mmap\n", current->pid); + + /* Set the transaction busy (own the device) */ + /* + * Problem for multithreaded applications is that here we're + * possibly going to sleep while holding a write lock on + * current->mm->mmap_sem, which will cause deadlock for ongoing + * transaction trying to create DMA tables + */ + error = sep_wait_transaction(sep); + if (error) + /* Interrupted by signal, don't clear transaction */ + goto end_function; + + /* Clear the message area to avoid next transaction reading + * sensitive results from previous transaction */ + memset(sep->shared_addr, 0, + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES); + + /* + * Check that the size of the mapped range is as the size of the message + * shared area + */ + if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { + error = -EINVAL; + goto end_function_with_error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] shared_addr is %p\n", + current->pid, sep->shared_addr); + + /* Get bus address */ + bus_addr = sep->shared_bus; + + if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + dev_dbg(&sep->pdev->dev, "[PID%d] remap_page_range failed\n", + current->pid); + error = -EAGAIN; + goto end_function_with_error; + } + + /* Update call status */ + set_bit(SEP_LEGACY_MMAP_DONE_OFFSET, &call_status->status); + + goto end_function; + +end_function_with_error: + /* Clear our transaction */ + sep_end_transaction_handler(sep, NULL, call_status, + my_queue_elem); + +end_function: + return error; +} + +/** + * sep_poll - poll handler + * @filp: pointer to struct file + * @wait: pointer to poll_table + * + * Called by the OS when the kernel is asked to do a poll on + * a SEP file handle. + */ +static unsigned int sep_poll(struct file *filp, poll_table *wait) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + u32 mask = 0; + u32 retval = 0; + u32 retval2 = 0; + unsigned long lock_irq_flag; + + /* Am I the process that owns the transaction? */ + if (sep_check_transaction_owner(sep)) { + dev_dbg(&sep->pdev->dev, "[PID%d] poll pid not owner\n", + current->pid); + mask = POLLERR; + goto end_function; + } + + /* Check if send command or send_reply were activated previously */ + if (0 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_warn(&sep->pdev->dev, "[PID%d] sendmsg not called\n", + current->pid); + mask = POLLERR; + goto end_function; + } + + + /* Add the event to the polling wait table */ + dev_dbg(&sep->pdev->dev, "[PID%d] poll: calling wait sep_event\n", + current->pid); + + poll_wait(filp, &sep->event_interrupt, wait); + + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: send_ct is %lx reply ct is %lx\n", + current->pid, sep->send_ct, sep->reply_ct); + + /* Check if error occured during poll */ + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + if ((retval2 != 0x0) && (retval2 != 0x8)) { + dev_dbg(&sep->pdev->dev, "[PID%d] poll; poll error %x\n", + current->pid, retval2); + mask |= POLLERR; + goto end_function; + } + + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + + if (sep->send_ct == sep->reply_ct) { + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: data ready check (GPR2) %x\n", + current->pid, retval); + + /* Check if printf request */ + if ((retval >> 30) & 0x1) { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: SEP printf request\n", + current->pid); + goto end_function; + } + + /* Check if the this is SEP reply or request */ + if (retval >> 31) { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: SEP request\n", + current->pid); + } else { + dev_dbg(&sep->pdev->dev, + "[PID%d] poll: normal return\n", + current->pid); + sep_dump_message(sep); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll; SEP reply POLLIN|POLLRDNORM\n", + current->pid); + mask |= POLLIN | POLLRDNORM; + } + set_bit(SEP_LEGACY_POLL_DONE_OFFSET, &call_status->status); + } else { + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + dev_dbg(&sep->pdev->dev, + "[PID%d] poll; no reply; returning mask of 0\n", + current->pid); + mask = 0; + } + +end_function: + return mask; +} + +/** + * sep_time_address - address in SEP memory of time + * @sep: SEP device we want the address from + * + * Return the address of the two dwords in memory used for time + * setting. + */ +static u32 *sep_time_address(struct sep_device *sep) +{ + return sep->shared_addr + + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; +} + +/** + * sep_set_time - set the SEP time + * @sep: the SEP we are setting the time for + * + * Calculates time and sets it at the predefined address. + * Called with the SEP mutex held. + */ +static unsigned long sep_set_time(struct sep_device *sep) +{ + struct timeval time; + u32 *time_addr; /* Address of time as seen by the kernel */ + + + do_gettimeofday(&time); + + /* Set value in the SYSTEM MEMORY offset */ + time_addr = sep_time_address(sep); + + time_addr[0] = SEP_TIME_VAL_TOKEN; + time_addr[1] = time.tv_sec; + + dev_dbg(&sep->pdev->dev, "[PID%d] time.tv_sec is %lu\n", + current->pid, time.tv_sec); + dev_dbg(&sep->pdev->dev, "[PID%d] time_addr is %p\n", + current->pid, time_addr); + dev_dbg(&sep->pdev->dev, "[PID%d] sep->shared_addr is %p\n", + current->pid, sep->shared_addr); + + return time.tv_sec; +} + +/** + * sep_send_command_handler - kick off a command + * @sep: SEP being signalled + * + * This function raises interrupt to SEP that signals that is has a new + * command from the host + * + * Note that this function does fall under the ioctl lock + */ +int sep_send_command_handler(struct sep_device *sep) +{ + unsigned long lock_irq_flag; + u32 *msg_pool; + int error = 0; + + /* Basic sanity check; set msg pool to start of shared area */ + msg_pool = (u32 *)sep->shared_addr; + msg_pool += 2; + + /* Look for start msg token */ + if (*msg_pool != SEP_START_MSG_TOKEN) { + dev_warn(&sep->pdev->dev, "start message token not present\n"); + error = -EPROTO; + goto end_function; + } + + /* Do we have a reasonable size? */ + msg_pool += 1; + if ((*msg_pool < 2) || + (*msg_pool > SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES)) { + + dev_warn(&sep->pdev->dev, "invalid message size\n"); + error = -EPROTO; + goto end_function; + } + + /* Does the command look reasonable? */ + msg_pool += 1; + if (*msg_pool < 2) { + dev_warn(&sep->pdev->dev, "invalid message opcode\n"); + error = -EPROTO; + goto end_function; + } + +#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM) + dev_dbg(&sep->pdev->dev, "[PID%d] before pm sync status 0x%X\n", + current->pid, + sep->pdev->dev.power.runtime_status); + sep->in_use = 1; /* device is about to be used */ + pm_runtime_get_sync(&sep->pdev->dev); +#endif + + if (test_and_set_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags)) { + error = -EPROTO; + goto end_function; + } + sep->in_use = 1; /* device is about to be used */ + sep_set_time(sep); + + sep_dump_message(sep); + + /* Update counter */ + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + sep->send_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + + dev_dbg(&sep->pdev->dev, + "[PID%d] sep_send_command_handler send_ct %lx reply_ct %lx\n", + current->pid, sep->send_ct, sep->reply_ct); + + /* Send interrupt to SEP */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); + +end_function: + return error; +} + +/** + * sep_crypto_dma - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist + * @direction: + * @dma_maps: pointer to place a pointer to array of dma maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @returns number of dma maps on success; negative on error + * + * This creates the dma table from the scatterlist + * It is used only for kernel crypto as it works with scatterlists + * representation of data buffers + * + */ +static int sep_crypto_dma( + struct sep_device *sep, + struct scatterlist *sg, + struct sep_dma_map **dma_maps, + enum dma_data_direction direction) +{ + struct scatterlist *temp_sg; + + u32 count_segment; + u32 count_mapped; + struct sep_dma_map *sep_dma; + int ct1; + + if (sg->length == 0) + return 0; + + /* Count the segments */ + temp_sg = sg; + count_segment = 0; + while (temp_sg) { + count_segment += 1; + temp_sg = scatterwalk_sg_next(temp_sg); + } + dev_dbg(&sep->pdev->dev, + "There are (hex) %x segments in sg\n", count_segment); + + /* DMA map segments */ + count_mapped = dma_map_sg(&sep->pdev->dev, sg, + count_segment, direction); + + dev_dbg(&sep->pdev->dev, + "There are (hex) %x maps in sg\n", count_mapped); + + if (count_mapped == 0) { + dev_dbg(&sep->pdev->dev, "Cannot dma_map_sg\n"); + return -ENOMEM; + } + + sep_dma = kmalloc(sizeof(struct sep_dma_map) * + count_mapped, GFP_ATOMIC); + + if (sep_dma == NULL) { + dev_dbg(&sep->pdev->dev, "Cannot allocate dma_maps\n"); + return -ENOMEM; + } + + for_each_sg(sg, temp_sg, count_mapped, ct1) { + sep_dma[ct1].dma_addr = sg_dma_address(temp_sg); + sep_dma[ct1].size = sg_dma_len(temp_sg); + dev_dbg(&sep->pdev->dev, "(all hex) map %x dma %lx len %lx\n", + ct1, (unsigned long)sep_dma[ct1].dma_addr, + (unsigned long)sep_dma[ct1].size); + } + + *dma_maps = sep_dma; + return count_mapped; + +} + +/** + * sep_crypto_lli - + * @sep: pointer to struct sep_device + * @sg: pointer to struct scatterlist + * @data_size: total data size + * @direction: + * @dma_maps: pointer to place a pointer to array of dma maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @lli_maps: pointer to place a pointer to array of lli maps + * This is filled in; anything previous there will be lost + * The structure for dma maps is sep_dma_map + * @returns number of dma maps on success; negative on error + * + * This creates the LLI table from the scatterlist + * It is only used for kernel crypto as it works exclusively + * with scatterlists (struct scatterlist) representation of + * data buffers + */ +static int sep_crypto_lli( + struct sep_device *sep, + struct scatterlist *sg, + struct sep_dma_map **maps, + struct sep_lli_entry **llis, + u32 data_size, + enum dma_data_direction direction) +{ + + int ct1; + struct sep_lli_entry *sep_lli; + struct sep_dma_map *sep_map; + + int nbr_ents; + + nbr_ents = sep_crypto_dma(sep, sg, maps, direction); + if (nbr_ents <= 0) { + dev_dbg(&sep->pdev->dev, "crypto_dma failed %x\n", + nbr_ents); + return nbr_ents; + } + + sep_map = *maps; + + sep_lli = kmalloc(sizeof(struct sep_lli_entry) * nbr_ents, GFP_ATOMIC); + + if (sep_lli == NULL) { + dev_dbg(&sep->pdev->dev, "Cannot allocate lli_maps\n"); + + kfree(*maps); + *maps = NULL; + return -ENOMEM; + } + + for (ct1 = 0; ct1 < nbr_ents; ct1 += 1) { + sep_lli[ct1].bus_address = (u32)sep_map[ct1].dma_addr; + + /* Maximum for page is total data size */ + if (sep_map[ct1].size > data_size) + sep_map[ct1].size = data_size; + + sep_lli[ct1].block_size = (u32)sep_map[ct1].size; + } + + *llis = sep_lli; + return nbr_ents; +} + +/** + * sep_lock_kernel_pages - map kernel pages for DMA + * @sep: pointer to struct sep_device + * @kernel_virt_addr: address of data buffer in kernel + * @data_size: size of data + * @lli_array_ptr: lli array + * @in_out_flag: input into device or output from device + * + * This function locks all the physical pages of the kernel virtual buffer + * and construct a basic lli array, where each entry holds the physical + * page address and the size that application data holds in this page + * This function is used only during kernel crypto mod calls from within + * the kernel (when ioctl is not used) + * + * This is used only for kernel crypto. Kernel pages + * are handled differently as they are done via + * scatter gather lists (struct scatterlist) + */ +static int sep_lock_kernel_pages(struct sep_device *sep, + unsigned long kernel_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag, + struct sep_dma_context *dma_ctx) + +{ + u32 num_pages; + struct scatterlist *sg; + + /* Array of lli */ + struct sep_lli_entry *lli_array; + /* Map array */ + struct sep_dma_map *map_array; + + enum dma_data_direction direction; + + lli_array = NULL; + map_array = NULL; + + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + direction = DMA_TO_DEVICE; + sg = dma_ctx->src_sg; + } else { + direction = DMA_FROM_DEVICE; + sg = dma_ctx->dst_sg; + } + + num_pages = sep_crypto_lli(sep, sg, &map_array, &lli_array, + data_size, direction); + + if (num_pages <= 0) { + dev_dbg(&sep->pdev->dev, "sep_crypto_lli returned error %x\n", + num_pages); + return -ENOMEM; + } + + /* Put mapped kernel sg into kernel resource array */ + + /* Set output params acording to the in_out flag */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = + NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = + dma_ctx->src_sg; + } else { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = + NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_map_num_entries = num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = + dma_ctx->dst_sg; + } + + return 0; +} + +/** + * sep_lock_user_pages - lock and map user pages for DMA + * @sep: pointer to struct sep_device + * @app_virt_addr: user memory data buffer + * @data_size: size of data buffer + * @lli_array_ptr: lli array + * @in_out_flag: input or output to device + * + * This function locks all the physical pages of the application + * virtual buffer and construct a basic lli array, where each entry + * holds the physical page address and the size that application + * data holds in this physical pages + */ +static int sep_lock_user_pages(struct sep_device *sep, + u32 app_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag, + struct sep_dma_context *dma_ctx) + +{ + int error = 0; + u32 count; + int result; + /* The the page of the end address of the user space buffer */ + u32 end_page; + /* The page of the start address of the user space buffer */ + u32 start_page; + /* The range in pages */ + u32 num_pages; + /* Array of pointers to page */ + struct page **page_array; + /* Array of lli */ + struct sep_lli_entry *lli_array; + /* Map array */ + struct sep_dma_map *map_array; + + /* Set start and end pages and num pages */ + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = app_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lock user pages app_virt_addr is %x\n", + current->pid, app_virt_addr); + + dev_dbg(&sep->pdev->dev, "[PID%d] data_size is (hex) %x\n", + current->pid, data_size); + dev_dbg(&sep->pdev->dev, "[PID%d] start_page is (hex) %x\n", + current->pid, start_page); + dev_dbg(&sep->pdev->dev, "[PID%d] end_page is (hex) %x\n", + current->pid, end_page); + dev_dbg(&sep->pdev->dev, "[PID%d] num_pages is (hex) %x\n", + current->pid, num_pages); + + /* Allocate array of pages structure pointers */ + page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); + if (!page_array) { + error = -ENOMEM; + goto end_function; + } + map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); + if (!map_array) { + dev_warn(&sep->pdev->dev, + "[PID%d] kmalloc for map_array failed\n", + current->pid); + error = -ENOMEM; + goto end_function_with_error1; + } + + lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, + GFP_ATOMIC); + + if (!lli_array) { + dev_warn(&sep->pdev->dev, + "[PID%d] kmalloc for lli_array failed\n", + current->pid); + error = -ENOMEM; + goto end_function_with_error2; + } + + /* Convert the application virtual address into a set of physical */ + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, app_virt_addr, + num_pages, + ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), + 0, page_array, NULL); + + up_read(¤t->mm->mmap_sem); + + /* Check the number of pages locked - if not all then exit with error */ + if (result != num_pages) { + dev_warn(&sep->pdev->dev, + "[PID%d] not all pages locked by get_user_pages, " + "result 0x%X, num_pages 0x%X\n", + current->pid, result, num_pages); + error = -ENOMEM; + goto end_function_with_error3; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] get_user_pages succeeded\n", + current->pid); + + /* + * Fill the array using page array data and + * map the pages - this action will also flush the cache as needed + */ + for (count = 0; count < num_pages; count++) { + /* Fill the map array */ + map_array[count].dma_addr = + dma_map_page(&sep->pdev->dev, page_array[count], + 0, PAGE_SIZE, DMA_BIDIRECTIONAL); + + map_array[count].size = PAGE_SIZE; + + /* Fill the lli array entry */ + lli_array[count].bus_address = (u32)map_array[count].dma_addr; + lli_array[count].block_size = PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[%x].bus_address is %08lx, " + "lli_array[%x].block_size is (hex) %x\n", current->pid, + count, (unsigned long)lli_array[count].bus_address, + count, lli_array[count].block_size); + } + + /* Check the offset for the first page */ + lli_array[0].bus_address = + lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); + + /* Check that not all the data is in the first page only */ + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = + PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); + + dev_dbg(&sep->pdev->dev, + "[PID%d] After check if page 0 has all data\n", + current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[0].bus_address is (hex) %08lx, " + "lli_array[0].block_size is (hex) %x\n", + current->pid, + (unsigned long)lli_array[0].bus_address, + lli_array[0].block_size); + + + /* Check the size of the last page */ + if (num_pages > 1) { + lli_array[num_pages - 1].block_size = + (app_virt_addr + data_size) & (~PAGE_MASK); + if (lli_array[num_pages - 1].block_size == 0) + lli_array[num_pages - 1].block_size = PAGE_SIZE; + + dev_dbg(&sep->pdev->dev, + "[PID%d] After last page size adjustment\n", + current->pid); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_array[%x].bus_address is (hex) %08lx, " + "lli_array[%x].block_size is (hex) %x\n", + current->pid, + num_pages - 1, + (unsigned long)lli_array[num_pages - 1].bus_address, + num_pages - 1, + lli_array[num_pages - 1].block_size); + } + + /* Set output params acording to the in_out flag */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = + page_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_num_entries = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].src_sg = NULL; + } else { + *lli_array_ptr = lli_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages = + num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = + page_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array = + map_array; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_map_num_entries = num_pages; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].dst_sg = NULL; + } + goto end_function; + +end_function_with_error3: + /* Free lli array */ + kfree(lli_array); + +end_function_with_error2: + kfree(map_array); + +end_function_with_error1: + /* Free page array */ + kfree(page_array); + +end_function: + return error; +} + +/** + * sep_calculate_lli_table_max_size - size the LLI table + * @sep: pointer to struct sep_device + * @lli_in_array_ptr + * @num_array_entries + * @last_table_flag + * + * This function calculates the size of data that can be inserted into + * the lli table from this array, such that either the table is full + * (all entries are entered), or there are no more entries in the + * lli array + */ +static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, + struct sep_lli_entry *lli_in_array_ptr, + u32 num_array_entries, + u32 *last_table_flag) +{ + u32 counter; + /* Table data size */ + u32 table_data_size = 0; + /* Data size for the next table */ + u32 next_table_data_size; + + *last_table_flag = 0; + + /* + * Calculate the data in the out lli table till we fill the whole + * table or till the data has ended + */ + for (counter = 0; + (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && + (counter < num_array_entries); counter++) + table_data_size += lli_in_array_ptr[counter].block_size; + + /* + * Check if we reached the last entry, + * meaning this ia the last table to build, + * and no need to check the block alignment + */ + if (counter == num_array_entries) { + /* Set the last table flag */ + *last_table_flag = 1; + goto end_function; + } + + /* + * Calculate the data size of the next table. + * Stop if no entries left or if data size is more the DMA restriction + */ + next_table_data_size = 0; + for (; counter < num_array_entries; counter++) { + next_table_data_size += lli_in_array_ptr[counter].block_size; + if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + break; + } + + /* + * Check if the next table data size is less then DMA rstriction. + * if it is - recalculate the current table size, so that the next + * table data size will be adaquete for DMA + */ + if (next_table_data_size && + next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + + table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - + next_table_data_size); + +end_function: + return table_data_size; +} + +/** + * sep_build_lli_table - build an lli array for the given table + * @sep: pointer to struct sep_device + * @lli_array_ptr: pointer to lli array + * @lli_table_ptr: pointer to lli table + * @num_processed_entries_ptr: pointer to number of entries + * @num_table_entries_ptr: pointer to number of tables + * @table_data_size: total data size + * + * Builds ant lli table from the lli_array according to + * the given size of data + */ +static void sep_build_lli_table(struct sep_device *sep, + struct sep_lli_entry *lli_array_ptr, + struct sep_lli_entry *lli_table_ptr, + u32 *num_processed_entries_ptr, + u32 *num_table_entries_ptr, + u32 table_data_size) +{ + /* Current table data size */ + u32 curr_table_data_size; + /* Counter of lli array entry */ + u32 array_counter; + + /* Init current table data size and lli array entry counter */ + curr_table_data_size = 0; + array_counter = 0; + *num_table_entries_ptr = 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] build lli table table_data_size: (hex) %x\n", + current->pid, table_data_size); + + /* Fill the table till table size reaches the needed amount */ + while (curr_table_data_size < table_data_size) { + /* Update the number of entries in table */ + (*num_table_entries_ptr)++; + + lli_table_ptr->bus_address = + cpu_to_le32(lli_array_ptr[array_counter].bus_address); + + lli_table_ptr->block_size = + cpu_to_le32(lli_array_ptr[array_counter].block_size); + + curr_table_data_size += lli_array_ptr[array_counter].block_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr is %p\n", + current->pid, lli_table_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->bus_address: %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->block_size is (hex) %x\n", + current->pid, lli_table_ptr->block_size); + + /* Check for overflow of the table data */ + if (curr_table_data_size > table_data_size) { + dev_dbg(&sep->pdev->dev, + "[PID%d] curr_table_data_size too large\n", + current->pid); + + /* Update the size of block in the table */ + lli_table_ptr->block_size = + cpu_to_le32(lli_table_ptr->block_size) - + (curr_table_data_size - table_data_size); + + /* Update the physical address in the lli array */ + lli_array_ptr[array_counter].bus_address += + cpu_to_le32(lli_table_ptr->block_size); + + /* Update the block size left in the lli array */ + lli_array_ptr[array_counter].block_size = + (curr_table_data_size - table_data_size); + } else + /* Advance to the next entry in the lli_array */ + array_counter++; + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->bus_address is %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr->block_size is (hex) %x\n", + current->pid, + lli_table_ptr->block_size); + + /* Move to the next entry in table */ + lli_table_ptr++; + } + + /* Set the info entry to default */ + lli_table_ptr->bus_address = 0xffffffff; + lli_table_ptr->block_size = 0; + + /* Set the output parameter */ + *num_processed_entries_ptr += array_counter; + +} + +/** + * sep_shared_area_virt_to_bus - map shared area to bus address + * @sep: pointer to struct sep_device + * @virt_address: virtual address to convert + * + * This functions returns the physical address inside shared area according + * to the virtual address. It can be either on the externa RAM device + * (ioremapped), or on the system RAM + * This implementation is for the external RAM + */ +static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, + void *virt_address) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys v %p\n", + current->pid, virt_address); + dev_dbg(&sep->pdev->dev, "[PID%d] sh virt to phys p %08lx\n", + current->pid, + (unsigned long) + sep->shared_bus + (virt_address - sep->shared_addr)); + + return sep->shared_bus + (size_t)(virt_address - sep->shared_addr); +} + +/** + * sep_shared_area_bus_to_virt - map shared area bus address to kernel + * @sep: pointer to struct sep_device + * @bus_address: bus address to convert + * + * This functions returns the virtual address inside shared area + * according to the physical address. It can be either on the + * externa RAM device (ioremapped), or on the system RAM + * This implementation is for the external RAM + */ +static void *sep_shared_area_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] shared bus to virt b=%lx v=%lx\n", + current->pid, + (unsigned long)bus_address, (unsigned long)(sep->shared_addr + + (size_t)(bus_address - sep->shared_bus))); + + return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); +} + +/** + * sep_debug_print_lli_tables - dump LLI table + * @sep: pointer to struct sep_device + * @lli_table_ptr: pointer to sep_lli_entry + * @num_table_entries: number of entries + * @table_data_size: total data size + * + * Walk the the list of the print created tables and print all the data + */ +static void sep_debug_print_lli_tables(struct sep_device *sep, + struct sep_lli_entry *lli_table_ptr, + unsigned long num_table_entries, + unsigned long table_data_size) +{ + unsigned long table_count = 1; + unsigned long entries_count = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables start\n", + current->pid); + if (num_table_entries == 0) { + dev_dbg(&sep->pdev->dev, "[PID%d] no table to print\n", + current->pid); + return; + } + + while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) { + dev_dbg(&sep->pdev->dev, + "[PID%d] lli table %08lx, " + "table_data_size is (hex) %lx\n", + current->pid, table_count, table_data_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] num_table_entries is (hex) %lx\n", + current->pid, num_table_entries); + + /* Print entries of the table (without info entry) */ + for (entries_count = 0; entries_count < num_table_entries; + entries_count++, lli_table_ptr++) { + + dev_dbg(&sep->pdev->dev, + "[PID%d] lli_table_ptr address is %08lx\n", + current->pid, + (unsigned long) lli_table_ptr); + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys address is %08lx " + "block size is (hex) %x\n", current->pid, + (unsigned long)lli_table_ptr->bus_address, + lli_table_ptr->block_size); + } + + /* Point to the info entry */ + lli_table_ptr--; + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys lli_table_ptr->block_size " + "is (hex) %x\n", + current->pid, + lli_table_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys lli_table_ptr->physical_address " + "is %08lx\n", + current->pid, + (unsigned long)lli_table_ptr->bus_address); + + + table_data_size = lli_table_ptr->block_size & 0xffffff; + num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; + + dev_dbg(&sep->pdev->dev, + "[PID%d] phys table_data_size is " + "(hex) %lx num_table_entries is" + " %lx bus_address is%lx\n", + current->pid, + table_data_size, + num_table_entries, + (unsigned long)lli_table_ptr->bus_address); + + if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff) + lli_table_ptr = (struct sep_lli_entry *) + sep_shared_bus_to_virt(sep, + (unsigned long)lli_table_ptr->bus_address); + + table_count++; + } + dev_dbg(&sep->pdev->dev, "[PID%d] sep_debug_print_lli_tables end\n", + current->pid); +} + + +/** + * sep_prepare_empty_lli_table - create a blank LLI table + * @sep: pointer to struct sep_device + * @lli_table_addr_ptr: pointer to lli table + * @num_entries_ptr: pointer to number of entries + * @table_data_size_ptr: point to table data size + * @dmatables_region: Optional buffer for DMA tables + * @dma_ctx: DMA context + * + * This function creates empty lli tables when there is no data + */ +static void sep_prepare_empty_lli_table(struct sep_device *sep, + dma_addr_t *lli_table_addr_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + struct sep_lli_entry *lli_table_ptr; + + /* Find the area for new table */ + lli_table_ptr = + (struct sep_lli_entry *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + if (dmatables_region && *dmatables_region) + lli_table_ptr = *dmatables_region; + + lli_table_ptr->bus_address = 0; + lli_table_ptr->block_size = 0; + + lli_table_ptr++; + lli_table_ptr->bus_address = 0xFFFFFFFF; + lli_table_ptr->block_size = 0; + + /* Set the output parameter value */ + *lli_table_addr_ptr = sep->shared_bus + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Set the num of entries and table data size for empty table */ + *num_entries_ptr = 2; + *table_data_size_ptr = 0; + + /* Update the number of created tables */ + dma_ctx->num_lli_tables_created++; +} + +/** + * sep_prepare_input_dma_table - prepare input DMA mappings + * @sep: pointer to struct sep_device + * @data_size: + * @block_size: + * @lli_table_ptr: + * @num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data (kernel cryptio call) + * + * This function prepares only input DMA table for synhronic symmetric + * operations (HASH) + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_prepare_input_dma_table(struct sep_device *sep, + unsigned long app_virt_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva, + void **dmatables_region, + struct sep_dma_context *dma_ctx +) +{ + int error = 0; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_entry_ptr; + /* Array of pointers to page */ + struct sep_lli_entry *lli_array_ptr; + /* Points to the first entry to be processed in the lli_in_array */ + u32 current_entry = 0; + /* Num entries in the virtual buffer */ + u32 sep_lli_entries = 0; + /* Lli table pointer */ + struct sep_lli_entry *in_lli_table_ptr; + /* The total data in one table */ + u32 table_data_size = 0; + /* Flag for last table */ + u32 last_table_flag = 0; + /* Number of entries in lli table */ + u32 num_entries_in_table = 0; + /* Next table address */ + void *lli_table_alloc_addr = NULL; + void *dma_lli_table_alloc_addr = NULL; + void *dma_in_lli_table_ptr = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] prepare intput dma " + "tbl data size: (hex) %x\n", + current->pid, data_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] block_size is (hex) %x\n", + current->pid, block_size); + + /* Initialize the pages pointers */ + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages = 0; + + /* Set the kernel address for first table to be allocated */ + lli_table_alloc_addr = (void *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + dma_ctx->num_lli_tables_created * sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + if (data_size == 0) { + if (dmatables_region) { + error = sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + 1); + if (error) + return error; + } + /* Special case - create meptu table - 2 entries, zero data */ + sep_prepare_empty_lli_table(sep, lli_table_ptr, + num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + goto update_dcb_counter; + } + + /* Check if the pages are in Kernel Virtual Address layout */ + if (is_kva == true) + error = sep_lock_kernel_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG, + dma_ctx); + else + /* + * Lock the pages of the user buffer + * and translate them to pages + */ + error = sep_lock_user_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG, + dma_ctx); + + if (error) + goto end_function; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output sep_in_num_pages is (hex) %x\n", + current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages); + + current_entry = 0; + info_entry_ptr = NULL; + + sep_lli_entries = + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages; + + dma_lli_table_alloc_addr = lli_table_alloc_addr; + if (dmatables_region) { + error = sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + sep_lli_entries); + if (error) + return error; + lli_table_alloc_addr = *dmatables_region; + } + + /* Loop till all the entries in in array are processed */ + while (current_entry < sep_lli_entries) { + + /* Set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_in_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + if (dma_lli_table_alloc_addr > + ((void *)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + error = -ENOMEM; + goto end_function_error; + + } + + /* Update the number of created tables */ + dma_ctx->num_lli_tables_created++; + + /* Calculate the maximum size of data for input table */ + table_data_size = sep_calculate_lli_table_max_size(sep, + &lli_array_ptr[current_entry], + (sep_lli_entries - current_entry), + &last_table_flag); + + /* + * If this is not the last table - + * then allign it to the block size + */ + if (!last_table_flag) + table_data_size = + (table_data_size / block_size) * block_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output table_data_size is (hex) %x\n", + current->pid, + table_data_size); + + /* Construct input lli table */ + sep_build_lli_table(sep, &lli_array_ptr[current_entry], + in_lli_table_ptr, + ¤t_entry, &num_entries_in_table, table_data_size); + + if (info_entry_ptr == NULL) { + + /* Set the output parameters to physical addresses */ + *lli_table_ptr = sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + *num_entries_ptr = num_entries_in_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_ptr); + + } else { + /* Update the info entry of the previous in table */ + info_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + info_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + } + /* Save the pointer to the info entry of the current tables */ + info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; + } + /* Print input tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_ptr), + *num_entries_ptr, *table_data_size_ptr); + } + + /* The array of the pages */ + kfree(lli_array_ptr); + +update_dcb_counter: + /* Update DCB counter */ + dma_ctx->nr_dcb_creat++; + goto end_function; + +end_function_error: + /* Free all the allocated resources */ + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + kfree(lli_array_ptr); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + +end_function: + return error; + +} + +/** + * sep_construct_dma_tables_from_lli - prepare AES/DES mappings + * @sep: pointer to struct sep_device + * @lli_in_array: + * @sep_in_lli_entries: + * @lli_out_array: + * @sep_out_lli_entries + * @block_size + * @lli_table_in_ptr + * @lli_table_out_ptr + * @in_num_entries_ptr + * @out_num_entries_ptr + * @table_data_size_ptr + * + * This function creates the input and output DMA tables for + * symmetric operations (AES/DES) according to the block + * size from LLI arays + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_construct_dma_tables_from_lli( + struct sep_device *sep, + struct sep_lli_entry *lli_in_array, + u32 sep_in_lli_entries, + struct sep_lli_entry *lli_out_array, + u32 sep_out_lli_entries, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + /* Points to the area where next lli table can be allocated */ + void *lli_table_alloc_addr = NULL; + /* + * Points to the area in shared region where next lli table + * can be allocated + */ + void *dma_lli_table_alloc_addr = NULL; + /* Input lli table in dmatables_region or shared region */ + struct sep_lli_entry *in_lli_table_ptr = NULL; + /* Input lli table location in the shared region */ + struct sep_lli_entry *dma_in_lli_table_ptr = NULL; + /* Output lli table in dmatables_region or shared region */ + struct sep_lli_entry *out_lli_table_ptr = NULL; + /* Output lli table location in the shared region */ + struct sep_lli_entry *dma_out_lli_table_ptr = NULL; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_in_entry_ptr = NULL; + /* Pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_out_entry_ptr = NULL; + /* Points to the first entry to be processed in the lli_in_array */ + u32 current_in_entry = 0; + /* Points to the first entry to be processed in the lli_out_array */ + u32 current_out_entry = 0; + /* Max size of the input table */ + u32 in_table_data_size = 0; + /* Max size of the output table */ + u32 out_table_data_size = 0; + /* Flag te signifies if this is the last tables build */ + u32 last_table_flag = 0; + /* The data size that should be in table */ + u32 table_data_size = 0; + /* Number of etnries in the input table */ + u32 num_entries_in_table = 0; + /* Number of etnries in the output table */ + u32 num_entries_out_table = 0; + + if (!dma_ctx) { + dev_warn(&sep->pdev->dev, "DMA context uninitialized\n"); + return -EINVAL; + } + + /* Initiate to point after the message area */ + lli_table_alloc_addr = (void *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + (dma_ctx->num_lli_tables_created * + (sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); + dma_lli_table_alloc_addr = lli_table_alloc_addr; + + if (dmatables_region) { + /* 2 for both in+out table */ + if (sep_allocate_dmatables_region(sep, + dmatables_region, + dma_ctx, + 2*sep_in_lli_entries)) + return -ENOMEM; + lli_table_alloc_addr = *dmatables_region; + } + + /* Loop till all the entries in in array are not processed */ + while (current_in_entry < sep_in_lli_entries) { + /* Set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_in_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Set the first output tables */ + out_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + dma_out_lli_table_ptr = + (struct sep_lli_entry *)dma_lli_table_alloc_addr; + + /* Check if the DMA table area limit was overrun */ + if ((dma_lli_table_alloc_addr + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > + ((void *)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + dev_warn(&sep->pdev->dev, "dma table limit overrun\n"); + return -ENOMEM; + } + + /* Update the number of the lli tables created */ + dma_ctx->num_lli_tables_created += 2; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + dma_lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* Calculate the maximum size of data for input table */ + in_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_in_array[current_in_entry], + (sep_in_lli_entries - current_in_entry), + &last_table_flag); + + /* Calculate the maximum size of data for output table */ + out_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_out_array[current_out_entry], + (sep_out_lli_entries - current_out_entry), + &last_table_flag); + + if (!last_table_flag) { + in_table_data_size = (in_table_data_size / + block_size) * block_size; + out_table_data_size = (out_table_data_size / + block_size) * block_size; + } + + table_data_size = in_table_data_size; + if (table_data_size > out_table_data_size) + table_data_size = out_table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] construct tables from lli" + " in_table_data_size is (hex) %x\n", current->pid, + in_table_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] construct tables from lli" + "out_table_data_size is (hex) %x\n", current->pid, + out_table_data_size); + + /* Construct input lli table */ + sep_build_lli_table(sep, &lli_in_array[current_in_entry], + in_lli_table_ptr, + ¤t_in_entry, + &num_entries_in_table, + table_data_size); + + /* Construct output lli table */ + sep_build_lli_table(sep, &lli_out_array[current_out_entry], + out_lli_table_ptr, + ¤t_out_entry, + &num_entries_out_table, + table_data_size); + + /* If info entry is null - this is the first table built */ + if (info_in_entry_ptr == NULL) { + /* Set the output parameters to physical addresses */ + *lli_table_in_ptr = + sep_shared_area_virt_to_bus(sep, dma_in_lli_table_ptr); + + *in_num_entries_ptr = num_entries_in_table; + + *lli_table_out_ptr = + sep_shared_area_virt_to_bus(sep, + dma_out_lli_table_ptr); + + *out_num_entries_ptr = num_entries_out_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_in_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_out_ptr is %08lx\n", + current->pid, + (unsigned long)*lli_table_out_ptr); + } else { + /* Update the info entry of the previous in table */ + info_in_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_in_lli_table_ptr); + + info_in_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + + /* Update the info entry of the previous in table */ + info_out_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + dma_out_lli_table_ptr); + + info_out_entry_ptr->block_size = + ((num_entries_out_table) << 24) | + (table_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_in_ptr:%08lx %08x\n", + current->pid, + (unsigned long)info_in_entry_ptr->bus_address, + info_in_entry_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] output lli_table_out_ptr:" + "%08lx %08x\n", + current->pid, + (unsigned long)info_out_entry_ptr->bus_address, + info_out_entry_ptr->block_size); + } + + /* Save the pointer to the info entry of the current tables */ + info_in_entry_ptr = in_lli_table_ptr + + num_entries_in_table - 1; + info_out_entry_ptr = out_lli_table_ptr + + num_entries_out_table - 1; + + dev_dbg(&sep->pdev->dev, + "[PID%d] output num_entries_out_table is %x\n", + current->pid, + (u32)num_entries_out_table); + dev_dbg(&sep->pdev->dev, + "[PID%d] output info_in_entry_ptr is %lx\n", + current->pid, + (unsigned long)info_in_entry_ptr); + dev_dbg(&sep->pdev->dev, + "[PID%d] output info_out_entry_ptr is %lx\n", + current->pid, + (unsigned long)info_out_entry_ptr); + } + + /* Print input tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables( + sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), + *in_num_entries_ptr, + *table_data_size_ptr); + } + + /* Print output tables */ + if (!dmatables_region) { + sep_debug_print_lli_tables( + sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), + *out_num_entries_ptr, + *table_data_size_ptr); + } + + return 0; +} + +/** + * sep_prepare_input_output_dma_table - prepare DMA I/O table + * @app_virt_in_addr: + * @app_virt_out_addr: + * @data_size: + * @block_size: + * @lli_table_in_ptr: + * @lli_table_out_ptr: + * @in_num_entries_ptr: + * @out_num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data; used only for kernel crypto module + * + * This function builds input and output DMA tables for synhronic + * symmetric operations (AES, DES, HASH). It also checks that each table + * is of the modular block size + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +static int sep_prepare_input_output_dma_table(struct sep_device *sep, + unsigned long app_virt_in_addr, + unsigned long app_virt_out_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva, + void **dmatables_region, + struct sep_dma_context *dma_ctx) + +{ + int error = 0; + /* Array of pointers of page */ + struct sep_lli_entry *lli_in_array; + /* Array of pointers of page */ + struct sep_lli_entry *lli_out_array; + + if (!dma_ctx) { + error = -EINVAL; + goto end_function; + } + + if (data_size == 0) { + /* Prepare empty table for input and output */ + if (dmatables_region) { + error = sep_allocate_dmatables_region( + sep, + dmatables_region, + dma_ctx, + 2); + if (error) + goto end_function; + } + sep_prepare_empty_lli_table(sep, lli_table_in_ptr, + in_num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + + sep_prepare_empty_lli_table(sep, lli_table_out_ptr, + out_num_entries_ptr, table_data_size_ptr, + dmatables_region, dma_ctx); + + goto update_dcb_counter; + } + + /* Initialize the pages pointers */ + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array = NULL; + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array = NULL; + + /* Lock the pages of the buffer and translate them to pages */ + if (is_kva == true) { + dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel input pages\n", + current->pid); + error = sep_lock_kernel_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG, + dma_ctx); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_kernel_pages for input " + "virtual buffer failed\n", current->pid); + + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] Locking kernel output pages\n", + current->pid); + error = sep_lock_kernel_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, + dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_kernel_pages for output " + "virtual buffer failed\n", current->pid); + + goto end_function_free_lli_in; + } + + } + + else { + dev_dbg(&sep->pdev->dev, "[PID%d] Locking user input pages\n", + current->pid); + error = sep_lock_user_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG, + dma_ctx); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_user_pages for input " + "virtual buffer failed\n", current->pid); + + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] Locking user output pages\n", + current->pid); + + error = sep_lock_user_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG, + dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_lock_user_pages" + " for output virtual buffer failed\n", + current->pid); + + goto end_function_free_lli_in; + } + } + + dev_dbg(&sep->pdev->dev, "[PID%d] After lock; prep input output dma " + "table sep_in_num_pages is (hex) %x\n", current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_num_pages); + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_out_num_pages is (hex) %x\n", + current->pid, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_num_pages); + + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP" + " is (hex) %x\n", current->pid, + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + /* Call the fucntion that creates table from the lli arrays */ + dev_dbg(&sep->pdev->dev, "[PID%d] calling create table from lli\n", + current->pid); + error = sep_construct_dma_tables_from_lli( + sep, lli_in_array, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + in_num_pages, + lli_out_array, + dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat]. + out_num_pages, + block_size, lli_table_in_ptr, lli_table_out_ptr, + in_num_entries_ptr, out_num_entries_ptr, + table_data_size_ptr, dmatables_region, dma_ctx); + + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] sep_construct_dma_tables_from_lli failed\n", + current->pid); + goto end_function_with_error; + } + + kfree(lli_out_array); + kfree(lli_in_array); + +update_dcb_counter: + /* Update DCB counter */ + dma_ctx->nr_dcb_creat++; + + goto end_function; + +end_function_with_error: + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_map_array); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].out_page_array); + kfree(lli_out_array); + + +end_function_free_lli_in: + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_map_array); + kfree(dma_ctx->dma_res_arr[dma_ctx->nr_dcb_creat].in_page_array); + kfree(lli_in_array); + +end_function: + + return error; + +} + +/** + * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks + * @app_in_address: unsigned long; for data buffer in (user space) + * @app_out_address: unsigned long; for data buffer out (user space) + * @data_in_size: u32; for size of data + * @block_size: u32; for block size + * @tail_block_size: u32; for size of tail block + * @isapplet: bool; to indicate external app + * @is_kva: bool; kernel buffer; only used for kernel crypto module + * + * This function prepares the linked DMA tables and puts the + * address for the linked list of tables inta a DCB (data control + * block) the address of which is known by the SEP hardware + * Note that all bus addresses that are passed to the SEP + * are in 32 bit format; the SEP is a 32 bit device + */ +int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, + unsigned long app_in_address, + unsigned long app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva, + struct sep_dcblock *dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + struct scatterlist *src_sg, + struct scatterlist *dst_sg) +{ + int error = 0; + /* Size of tail */ + u32 tail_size = 0; + /* Address of the created DCB table */ + struct sep_dcblock *dcb_table_ptr = NULL; + /* The physical address of the first input DMA table */ + dma_addr_t in_first_mlli_address = 0; + /* Number of entries in the first input DMA table */ + u32 in_first_num_entries = 0; + /* The physical address of the first output DMA table */ + dma_addr_t out_first_mlli_address = 0; + /* Number of entries in the first output DMA table */ + u32 out_first_num_entries = 0; + /* Data in the first input/output table */ + u32 first_data_size = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] app_in_address %lx\n", + current->pid, app_in_address); + + dev_dbg(&sep->pdev->dev, "[PID%d] app_out_address %lx\n", + current->pid, app_out_address); + + dev_dbg(&sep->pdev->dev, "[PID%d] data_in_size %x\n", + current->pid, data_in_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] block_size %x\n", + current->pid, block_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] tail_block_size %x\n", + current->pid, tail_block_size); + + dev_dbg(&sep->pdev->dev, "[PID%d] isapplet %x\n", + current->pid, isapplet); + + dev_dbg(&sep->pdev->dev, "[PID%d] is_kva %x\n", + current->pid, is_kva); + + dev_dbg(&sep->pdev->dev, "[PID%d] src_sg %p\n", + current->pid, src_sg); + + dev_dbg(&sep->pdev->dev, "[PID%d] dst_sg %p\n", + current->pid, dst_sg); + + if (!dma_ctx) { + dev_warn(&sep->pdev->dev, "[PID%d] no DMA context pointer\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + if (*dma_ctx) { + /* In case there are multiple DCBs for this transaction */ + dev_dbg(&sep->pdev->dev, "[PID%d] DMA context already set\n", + current->pid); + } else { + *dma_ctx = kzalloc(sizeof(**dma_ctx), GFP_KERNEL); + if (!(*dma_ctx)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] Not enough memory for DMA context\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + dev_dbg(&sep->pdev->dev, + "[PID%d] Created DMA context addr at 0x%p\n", + current->pid, *dma_ctx); + } + + /* these are for kernel crypto only */ + (*dma_ctx)->src_sg = src_sg; + (*dma_ctx)->dst_sg = dst_sg; + + if ((*dma_ctx)->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { + /* No more DCBs to allocate */ + dev_dbg(&sep->pdev->dev, "[PID%d] no more DCBs available\n", + current->pid); + error = -ENOSPC; + goto end_function_error; + } + + /* Allocate new DCB */ + if (dcb_region) { + dcb_table_ptr = dcb_region; + } else { + dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + + ((*dma_ctx)->nr_dcb_creat * + sizeof(struct sep_dcblock))); + } + + /* Set the default values in the DCB */ + dcb_table_ptr->input_mlli_address = 0; + dcb_table_ptr->input_mlli_num_entries = 0; + dcb_table_ptr->input_mlli_data_size = 0; + dcb_table_ptr->output_mlli_address = 0; + dcb_table_ptr->output_mlli_num_entries = 0; + dcb_table_ptr->output_mlli_data_size = 0; + dcb_table_ptr->tail_data_size = 0; + dcb_table_ptr->out_vr_tail_pt = 0; + + if (isapplet == true) { + + /* Check if there is enough data for DMA operation */ + if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { + if (is_kva == true) { + error = -ENODEV; + goto end_function_error; + } else { + if (copy_from_user(dcb_table_ptr->tail_data, + (void __user *)app_in_address, + data_in_size)) { + error = -EFAULT; + goto end_function_error; + } + } + + dcb_table_ptr->tail_data_size = data_in_size; + + /* Set the output user-space address for mem2mem op */ + if (app_out_address) + dcb_table_ptr->out_vr_tail_pt = + (aligned_u64)app_out_address; + + /* + * Update both data length parameters in order to avoid + * second data copy and allow building of empty mlli + * tables + */ + tail_size = 0x0; + data_in_size = 0x0; + + } else { + if (!app_out_address) { + tail_size = data_in_size % block_size; + if (!tail_size) { + if (tail_block_size == block_size) + tail_size = block_size; + } + } else { + tail_size = 0; + } + } + if (tail_size) { + if (tail_size > sizeof(dcb_table_ptr->tail_data)) + return -EINVAL; + if (is_kva == true) { + error = -ENODEV; + goto end_function_error; + } else { + /* We have tail data - copy it to DCB */ + if (copy_from_user(dcb_table_ptr->tail_data, + (void __user *)(app_in_address + + data_in_size - tail_size), tail_size)) { + error = -EFAULT; + goto end_function_error; + } + } + if (app_out_address) + /* + * Calculate the output address + * according to tail data size + */ + dcb_table_ptr->out_vr_tail_pt = + (aligned_u64)app_out_address + + data_in_size - tail_size; + + /* Save the real tail data size */ + dcb_table_ptr->tail_data_size = tail_size; + /* + * Update the data size without the tail + * data size AKA data for the dma + */ + data_in_size = (data_in_size - tail_size); + } + } + /* Check if we need to build only input table or input/output */ + if (app_out_address) { + /* Prepare input/output tables */ + error = sep_prepare_input_output_dma_table(sep, + app_in_address, + app_out_address, + data_in_size, + block_size, + &in_first_mlli_address, + &out_first_mlli_address, + &in_first_num_entries, + &out_first_num_entries, + &first_data_size, + is_kva, + dmatables_region, + *dma_ctx); + } else { + /* Prepare input tables */ + error = sep_prepare_input_dma_table(sep, + app_in_address, + data_in_size, + block_size, + &in_first_mlli_address, + &in_first_num_entries, + &first_data_size, + is_kva, + dmatables_region, + *dma_ctx); + } + + if (error) { + dev_warn(&sep->pdev->dev, + "prepare DMA table call failed " + "from prepare DCB call\n"); + goto end_function_error; + } + + /* Set the DCB values */ + dcb_table_ptr->input_mlli_address = in_first_mlli_address; + dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; + dcb_table_ptr->input_mlli_data_size = first_data_size; + dcb_table_ptr->output_mlli_address = out_first_mlli_address; + dcb_table_ptr->output_mlli_num_entries = out_first_num_entries; + dcb_table_ptr->output_mlli_data_size = first_data_size; + + goto end_function; + +end_function_error: + kfree(*dma_ctx); + +end_function: + return error; + +} + + +/** + * sep_free_dma_tables_and_dcb - free DMA tables and DCBs + * @sep: pointer to struct sep_device + * @isapplet: indicates external application (used for kernel access) + * @is_kva: indicates kernel addresses (only used for kernel crypto) + * + * This function frees the DMA tables and DCB + */ +static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, + bool is_kva, struct sep_dma_context **dma_ctx) +{ + struct sep_dcblock *dcb_table_ptr; + unsigned long pt_hold; + void *tail_pt; + + int i = 0; + int error = 0; + int error_temp = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb\n", + current->pid); + + if (isapplet == true) { + /* Set pointer to first DCB table */ + dcb_table_ptr = (struct sep_dcblock *) + (sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); + + /* Go over each DCB and see if tail pointer must be updated */ + for (i = 0; + i < (*dma_ctx)->nr_dcb_creat; i++, dcb_table_ptr++) { + if (dcb_table_ptr->out_vr_tail_pt) { + pt_hold = (unsigned long)dcb_table_ptr-> + out_vr_tail_pt; + tail_pt = (void *)pt_hold; + if (is_kva == true) { + error = -ENODEV; + break; + } else { + error_temp = copy_to_user( + (void __user *)tail_pt, + dcb_table_ptr->tail_data, + dcb_table_ptr->tail_data_size); + } + if (error_temp) { + /* Release the DMA resource */ + error = -EFAULT; + break; + } + } + } + } + /* Free the output pages, if any */ + sep_free_dma_table_data_handler(sep, dma_ctx); + + dev_dbg(&sep->pdev->dev, "[PID%d] sep_free_dma_tables_and_dcb end\n", + current->pid); + + return error; +} + +/** + * sep_prepare_dcb_handler - prepare a control block + * @sep: pointer to struct sep_device + * @arg: pointer to user parameters + * + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. + */ +static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg, + struct sep_dma_context **dma_ctx) +{ + int error; + /* Command arguments */ + static struct build_dcb_struct command_args; + + /* Get the command arguments */ + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(struct build_dcb_struct))) { + error = -EFAULT; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "[PID%d] prep dcb handler app_in_address is %08llx\n", + current->pid, command_args.app_in_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] app_out_address is %08llx\n", + current->pid, command_args.app_out_address); + dev_dbg(&sep->pdev->dev, + "[PID%d] data_size is %x\n", + current->pid, command_args.data_in_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] block_size is %x\n", + current->pid, command_args.block_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] tail block_size is %x\n", + current->pid, command_args.tail_block_size); + dev_dbg(&sep->pdev->dev, + "[PID%d] is_applet is %x\n", + current->pid, command_args.is_applet); + + if (!command_args.app_in_address) { + dev_warn(&sep->pdev->dev, + "[PID%d] null app_in_address\n", current->pid); + error = -EINVAL; + goto end_function; + } + + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)command_args.app_in_address, + (unsigned long)command_args.app_out_address, + command_args.data_in_size, command_args.block_size, + command_args.tail_block_size, + command_args.is_applet, false, + NULL, NULL, dma_ctx, NULL, NULL); + +end_function: + return error; + +} + +/** + * sep_free_dcb_handler - free control block resources + * @sep: pointer to struct sep_device + * + * This function frees the DCB resources and updates the needed + * user-space buffers. + */ +static int sep_free_dcb_handler(struct sep_device *sep, + struct sep_dma_context **dma_ctx) +{ + int error = 0; + + if (!dma_ctx || !(*dma_ctx)) { + dev_dbg(&sep->pdev->dev, "[PID%d] no dma context defined, nothing to free\n", + current->pid); + return error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] free dcbs num of DCBs %x\n", + current->pid, + (*dma_ctx)->nr_dcb_creat); + + error = sep_free_dma_tables_and_dcb(sep, false, false, dma_ctx); + + return error; +} + +/** + * sep_ioctl - ioctl handler for sep device + * @filp: pointer to struct file + * @cmd: command + * @arg: pointer to argument structure + * + * Implement the ioctl methods availble on the SEP device. + */ +static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + int error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl cmd 0x%x\n", + current->pid, cmd); + dev_dbg(&sep->pdev->dev, "[PID%d] dma context addr 0x%p\n", + current->pid, *dma_ctx); + + /* Make sure we own this device */ + error = sep_check_transaction_owner(sep); + if (error) { + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl pid is not owner\n", + current->pid); + goto end_function; + } + + /* Check that sep_mmap has been called before */ + if (0 == test_bit(SEP_LEGACY_MMAP_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] mmap not called\n", current->pid); + error = -EPROTO; + goto end_function; + } + + /* Check that the command is for SEP device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { + error = -ENOTTY; + goto end_function; + } + + switch (cmd) { + case SEP_IOCSENDSEPCOMMAND: + if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, "[PID%d] send msg already done\n", + current->pid); + error = -EPROTO; + goto end_function; + } + /* Send command to SEP */ + error = sep_send_command_handler(sep); + if (!error) + set_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCSENDSEPCOMMAND end\n", + current->pid); + break; + case SEP_IOCENDTRANSACTION: + error = sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCENDTRANSACTION end\n", + current->pid); + break; + case SEP_IOCPREPAREDCB: + if (1 == test_bit(SEP_LEGACY_SENDMSG_DONE_OFFSET, + &call_status->status)) { + dev_dbg(&sep->pdev->dev, + "[PID%d] dcb preparation needed before send msg\n", + current->pid); + error = -EPROTO; + goto end_function; + } + + if (!arg) { + dev_dbg(&sep->pdev->dev, + "[PID%d] dcb prep null arg\n", current->pid); + error = -EINVAL; + goto end_function; + } + + error = sep_prepare_dcb_handler(sep, arg, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCPREPAREDCB end\n", + current->pid); + break; + case SEP_IOCFREEDCB: + error = sep_free_dcb_handler(sep, dma_ctx); + dev_dbg(&sep->pdev->dev, "[PID%d] SEP_IOCFREEDCB end\n", + current->pid); + break; + default: + error = -ENOTTY; + dev_dbg(&sep->pdev->dev, "[PID%d] default end\n", + current->pid); + break; + } + +end_function: + dev_dbg(&sep->pdev->dev, "[PID%d] ioctl end\n", current->pid); + + return error; +} + +/** + * sep_inthandler - interrupt handler for sep device + * @irq: interrupt + * @dev_id: device id + */ +static irqreturn_t sep_inthandler(int irq, void *dev_id) +{ + unsigned long lock_irq_flag; + u32 reg_val, reg_val2 = 0; + struct sep_device *sep = dev_id; + irqreturn_t int_error = IRQ_HANDLED; + + /* Are we in power save? */ +#if defined(CONFIG_PM_RUNTIME) && defined(SEP_ENABLE_RUNTIME_PM) + if (sep->pdev->dev.power.runtime_status != RPM_ACTIVE) { + dev_dbg(&sep->pdev->dev, "interrupt during pwr save\n"); + return IRQ_NONE; + } +#endif + + if (test_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags) == 0) { + dev_dbg(&sep->pdev->dev, "interrupt while nobody using sep\n"); + return IRQ_NONE; + } + + /* Read the IRR register to check if this is SEP interrupt */ + reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); + + dev_dbg(&sep->pdev->dev, "sep int: IRR REG val: %x\n", reg_val); + + if (reg_val & (0x1 << 13)) { + + /* Lock and update the counter of reply messages */ + spin_lock_irqsave(&sep->snd_rply_lck, lock_irq_flag); + sep->reply_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lock_irq_flag); + + dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", + sep->send_ct, sep->reply_ct); + + /* Is this a kernel client request */ + if (sep->in_kernel) { + tasklet_schedule(&sep->finish_tasklet); + goto finished_interrupt; + } + + /* Is this printf or daemon request? */ + reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "SEP Interrupt - GPR2 is %08x\n", reg_val2); + + clear_bit(SEP_WORKING_LOCK_BIT, &sep->in_use_flags); + + if ((reg_val2 >> 30) & 0x1) { + dev_dbg(&sep->pdev->dev, "int: printf request\n"); + } else if (reg_val2 >> 31) { + dev_dbg(&sep->pdev->dev, "int: daemon request\n"); + } else { + dev_dbg(&sep->pdev->dev, "int: SEP reply\n"); + wake_up(&sep->event_interrupt); + } + } else { + dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n"); + int_error = IRQ_NONE; + } + +finished_interrupt: + + if (int_error == IRQ_HANDLED) + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); + + return int_error; +} + +/** + * sep_reconfig_shared_area - reconfigure shared area + * @sep: pointer to struct sep_device + * + * Reconfig the shared area between HOST and SEP - needed in case + * the DX_CC_Init function was called before OS loading. + */ +static int sep_reconfig_shared_area(struct sep_device *sep) +{ + int ret_val; + + /* use to limit waiting for SEP */ + unsigned long end_time; + + /* Send the new SHARED MESSAGE AREA to the SEP */ + dev_dbg(&sep->pdev->dev, "reconfig shared; sending %08llx to sep\n", + (unsigned long long)sep->shared_bus); + + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); + + /* Poll for SEP response */ + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + end_time = jiffies + (WAIT_TIME * HZ); + + while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) && + (ret_val != sep->shared_bus)) + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + /* Check the return value (register) */ + if (ret_val != sep->shared_bus) { + dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); + dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); + ret_val = -ENOMEM; + } else + ret_val = 0; + + dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); + + return ret_val; +} + +/** + * sep_activate_dcb_dmatables_context - Takes DCB & DMA tables + * contexts into use + * @sep: SEP device + * @dcb_region: DCB region copy + * @dmatables_region: MLLI/DMA tables copy + * @dma_ctx: DMA context for current transaction + */ +ssize_t sep_activate_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context *dma_ctx) +{ + void *dmaregion_free_start = NULL; + void *dmaregion_free_end = NULL; + void *dcbregion_free_start = NULL; + void *dcbregion_free_end = NULL; + ssize_t error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] activating dcb/dma region\n", + current->pid); + + if (1 > dma_ctx->nr_dcb_creat) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs to activate 0x%08X\n", + current->pid, dma_ctx->nr_dcb_creat); + error = -EINVAL; + goto end_function; + } + + dmaregion_free_start = sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES; + dmaregion_free_end = dmaregion_free_start + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES - 1; + + if (dmaregion_free_start + + dma_ctx->dmatables_len > dmaregion_free_end) { + error = -ENOMEM; + goto end_function; + } + memcpy(dmaregion_free_start, + *dmatables_region, + dma_ctx->dmatables_len); + /* Free MLLI table copy */ + kfree(*dmatables_region); + *dmatables_region = NULL; + + /* Copy thread's DCB table copy to DCB table region */ + dcbregion_free_start = sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES; + dcbregion_free_end = dcbregion_free_start + + (SEP_MAX_NUM_SYNC_DMA_OPS * + sizeof(struct sep_dcblock)) - 1; + + if (dcbregion_free_start + + (dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock)) + > dcbregion_free_end) { + error = -ENOMEM; + goto end_function; + } + + memcpy(dcbregion_free_start, + *dcb_region, + dma_ctx->nr_dcb_creat * sizeof(struct sep_dcblock)); + + /* Print the tables */ + dev_dbg(&sep->pdev->dev, "activate: input table\n"); + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep, + (*dcb_region)->input_mlli_address), + (*dcb_region)->input_mlli_num_entries, + (*dcb_region)->input_mlli_data_size); + + dev_dbg(&sep->pdev->dev, "activate: output table\n"); + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *)sep_shared_area_bus_to_virt(sep, + (*dcb_region)->output_mlli_address), + (*dcb_region)->output_mlli_num_entries, + (*dcb_region)->output_mlli_data_size); + + dev_dbg(&sep->pdev->dev, + "[PID%d] printing activated tables\n", current->pid); + +end_function: + kfree(*dmatables_region); + *dmatables_region = NULL; + + kfree(*dcb_region); + *dcb_region = NULL; + + return error; +} + +/** + * sep_create_dcb_dmatables_context - Creates DCB & MLLI/DMA table context + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + */ +static ssize_t sep_create_dcb_dmatables_context(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct __user *user_dcb_args, + const u32 num_dcbs) +{ + int error = 0; + int i = 0; + struct build_dcb_struct *dcb_args = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n", + current->pid); + + if (!dcb_region || !dma_ctx || !dmatables_region || !user_dcb_args) { + error = -EINVAL; + goto end_function; + } + + if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs 0x%08X\n", + current->pid, num_dcbs); + error = -EINVAL; + goto end_function; + } + + dcb_args = kzalloc(num_dcbs * sizeof(struct build_dcb_struct), + GFP_KERNEL); + if (!dcb_args) { + dev_warn(&sep->pdev->dev, "[PID%d] no memory for dcb args\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + + if (copy_from_user(dcb_args, + user_dcb_args, + num_dcbs * sizeof(struct build_dcb_struct))) { + error = -EINVAL; + goto end_function; + } + + /* Allocate thread-specific memory for DCB */ + *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock), + GFP_KERNEL); + if (!(*dcb_region)) { + error = -ENOMEM; + goto end_function; + } + + /* Prepare DCB and MLLI table into the allocated regions */ + for (i = 0; i < num_dcbs; i++) { + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)dcb_args[i].app_in_address, + (unsigned long)dcb_args[i].app_out_address, + dcb_args[i].data_in_size, + dcb_args[i].block_size, + dcb_args[i].tail_block_size, + dcb_args[i].is_applet, + false, + *dcb_region, dmatables_region, + dma_ctx, + NULL, + NULL); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma table creation failed\n", + current->pid); + goto end_function; + } + } + +end_function: + kfree(dcb_args); + return error; + +} + +/** + * sep_create_dcb_dmatables_context_kernel - Creates DCB & MLLI/DMA table context + * for kernel crypto + * @sep: SEP device + * @dcb_region: DCB region buf to create for current transaction + * @dmatables_region: MLLI/DMA tables buf to create for current transaction + * @dma_ctx: DMA context buf to create for current transaction + * @user_dcb_args: User arguments for DCB/MLLI creation + * @num_dcbs: Number of DCBs to create + * This does that same thing as sep_create_dcb_dmatables_context + * except that it is used only for the kernel crypto operation. It is + * separate because there is no user data involved; the dcb data structure + * is specific for kernel crypto (build_dcb_struct_kernel) + */ +int sep_create_dcb_dmatables_context_kernel(struct sep_device *sep, + struct sep_dcblock **dcb_region, + void **dmatables_region, + struct sep_dma_context **dma_ctx, + const struct build_dcb_struct_kernel *dcb_data, + const u32 num_dcbs) +{ + int error = 0; + int i = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating dcb/dma region\n", + current->pid); + + if (!dcb_region || !dma_ctx || !dmatables_region || !dcb_data) { + error = -EINVAL; + goto end_function; + } + + if (SEP_MAX_NUM_SYNC_DMA_OPS < num_dcbs) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid number of dcbs 0x%08X\n", + current->pid, num_dcbs); + error = -EINVAL; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] num_dcbs is %d\n", + current->pid, num_dcbs); + + /* Allocate thread-specific memory for DCB */ + *dcb_region = kzalloc(num_dcbs * sizeof(struct sep_dcblock), + GFP_KERNEL); + if (!(*dcb_region)) { + error = -ENOMEM; + goto end_function; + } + + /* Prepare DCB and MLLI table into the allocated regions */ + for (i = 0; i < num_dcbs; i++) { + error = sep_prepare_input_output_dma_table_in_dcb(sep, + (unsigned long)dcb_data->app_in_address, + (unsigned long)dcb_data->app_out_address, + dcb_data->data_in_size, + dcb_data->block_size, + dcb_data->tail_block_size, + dcb_data->is_applet, + true, + *dcb_region, dmatables_region, + dma_ctx, + dcb_data->src_sg, + dcb_data->dst_sg); + if (error) { + dev_warn(&sep->pdev->dev, + "[PID%d] dma table creation failed\n", + current->pid); + goto end_function; + } + } + +end_function: + return error; + +} + +/** + * sep_activate_msgarea_context - Takes the message area context into use + * @sep: SEP device + * @msg_region: Message area context buf + * @msg_len: Message area context buffer size + */ +static ssize_t sep_activate_msgarea_context(struct sep_device *sep, + void **msg_region, + const size_t msg_len) +{ + dev_dbg(&sep->pdev->dev, "[PID%d] activating msg region\n", + current->pid); + + if (!msg_region || !(*msg_region) || + SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid act msgarea len 0x%08X\n", + current->pid, msg_len); + return -EINVAL; + } + + memcpy(sep->shared_addr, *msg_region, msg_len); + + return 0; +} + +/** + * sep_create_msgarea_context - Creates message area context + * @sep: SEP device + * @msg_region: Msg area region buf to create for current transaction + * @msg_user: Content for msg area region from user + * @msg_len: Message area size + */ +static ssize_t sep_create_msgarea_context(struct sep_device *sep, + void **msg_region, + const void __user *msg_user, + const size_t msg_len) +{ + int error = 0; + + dev_dbg(&sep->pdev->dev, "[PID%d] creating msg region\n", + current->pid); + + if (!msg_region || + !msg_user || + SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len || + SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid creat msgarea len 0x%08X\n", + current->pid, msg_len); + error = -EINVAL; + goto end_function; + } + + /* Allocate thread-specific memory for message buffer */ + *msg_region = kzalloc(msg_len, GFP_KERNEL); + if (!(*msg_region)) { + dev_warn(&sep->pdev->dev, + "[PID%d] no mem for msgarea context\n", + current->pid); + error = -ENOMEM; + goto end_function; + } + + /* Copy input data to write() to allocated message buffer */ + if (copy_from_user(*msg_region, msg_user, msg_len)) { + error = -EINVAL; + goto end_function; + } + +end_function: + if (error && msg_region) { + kfree(*msg_region); + *msg_region = NULL; + } + + return error; +} + + +/** + * sep_read - Returns results of an operation for fastcall interface + * @filp: File pointer + * @buf_user: User buffer for storing results + * @count_user: User buffer size + * @offset: File offset, not supported + * + * The implementation does not support reading in chunks, all data must be + * consumed during a single read system call. + */ +static ssize_t sep_read(struct file *filp, + char __user *buf_user, size_t count_user, + loff_t *offset) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context **dma_ctx = &private_data->dma_ctx; + struct sep_queue_info **my_queue_elem = &private_data->my_queue_elem; + ssize_t error = 0, error_tmp = 0; + + /* Am I the process that owns the transaction? */ + error = sep_check_transaction_owner(sep); + if (error) { + dev_dbg(&sep->pdev->dev, "[PID%d] read pid is not owner\n", + current->pid); + goto end_function; + } + + /* Checks that user has called necessarry apis */ + if (0 == test_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, + &call_status->status)) { + dev_warn(&sep->pdev->dev, + "[PID%d] fastcall write not called\n", + current->pid); + error = -EPROTO; + goto end_function_error; + } + + if (!buf_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] null user buffer\n", + current->pid); + error = -EINVAL; + goto end_function_error; + } + + + /* Wait for SEP to finish */ + wait_event(sep->event_interrupt, + test_bit(SEP_WORKING_LOCK_BIT, + &sep->in_use_flags) == 0); + + sep_dump_message(sep); + + dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08X\n", + current->pid, count_user); + + /* In case user has allocated bigger buffer */ + if (count_user > SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) + count_user = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES; + + if (copy_to_user(buf_user, sep->shared_addr, count_user)) { + error = -EFAULT; + goto end_function_error; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] read succeeded\n", current->pid); + error = count_user; + +end_function_error: + /* Copy possible tail data to user and free DCB and MLLIs */ + error_tmp = sep_free_dcb_handler(sep, dma_ctx); + if (error_tmp) + dev_warn(&sep->pdev->dev, "[PID%d] dcb free failed\n", + current->pid); + + /* End the transaction, wakeup pending ones */ + error_tmp = sep_end_transaction_handler(sep, dma_ctx, call_status, + my_queue_elem); + if (error_tmp) + dev_warn(&sep->pdev->dev, + "[PID%d] ending transaction failed\n", + current->pid); + +end_function: + return error; +} + +/** + * sep_fastcall_args_get - Gets fastcall params from user + * sep: SEP device + * @args: Parameters buffer + * @buf_user: User buffer for operation parameters + * @count_user: User buffer size + */ +static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, + struct sep_fastcall_hdr *args, + const char __user *buf_user, + const size_t count_user) +{ + ssize_t error = 0; + size_t actual_count = 0; + + if (!buf_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] null user buffer\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + if (count_user < sizeof(struct sep_fastcall_hdr)) { + dev_warn(&sep->pdev->dev, + "[PID%d] too small message size 0x%08X\n", + current->pid, count_user); + error = -EINVAL; + goto end_function; + } + + + if (copy_from_user(args, buf_user, sizeof(struct sep_fastcall_hdr))) { + error = -EFAULT; + goto end_function; + } + + if (SEP_FC_MAGIC != args->magic) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid fastcall magic 0x%08X\n", + current->pid, args->magic); + error = -EINVAL; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr num of DCBs 0x%08X\n", + current->pid, args->num_dcbs); + dev_dbg(&sep->pdev->dev, "[PID%d] fastcall hdr msg len 0x%08X\n", + current->pid, args->msg_len); + + if (SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < args->msg_len || + SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > args->msg_len) { + dev_warn(&sep->pdev->dev, + "[PID%d] invalid message length\n", + current->pid); + error = -EINVAL; + goto end_function; + } + + actual_count = sizeof(struct sep_fastcall_hdr) + + args->msg_len + + (args->num_dcbs * sizeof(struct build_dcb_struct)); + + if (actual_count != count_user) { + dev_warn(&sep->pdev->dev, + "[PID%d] inconsistent message " + "sizes 0x%08X vs 0x%08X\n", + current->pid, actual_count, count_user); + error = -EMSGSIZE; + goto end_function; + } + +end_function: + return error; +} + +/** + * sep_write - Starts an operation for fastcall interface + * @filp: File pointer + * @buf_user: User buffer for operation parameters + * @count_user: User buffer size + * @offset: File offset, not supported + * + * The implementation does not support writing in chunks, + * all data must be given during a single write system call. + */ +static ssize_t sep_write(struct file *filp, + const char __user *buf_user, size_t count_user, + loff_t *offset) +{ + struct sep_private_data * const private_data = filp->private_data; + struct sep_call_status *call_status = &private_data->call_status; + struct sep_device *sep = private_data->device; + struct sep_dma_context *dma_ctx = NULL; + struct sep_fastcall_hdr call_hdr = {0}; + void *msg_region = NULL; + void *dmatables_region = NULL; + struct sep_dcblock *dcb_region = NULL; + ssize_t error = 0; + struct sep_queue_info *my_queue_elem = NULL; + + dev_dbg(&sep->pdev->dev, "[PID%d] sep dev is 0x%p\n", + current->pid, sep); + dev_dbg(&sep->pdev->dev, "[PID%d] private_data is 0x%p\n", + current->pid, private_data); + + error = sep_fastcall_args_get(sep, &call_hdr, buf_user, count_user); + if (error) + goto end_function; + + buf_user += sizeof(struct sep_fastcall_hdr); + + /* + * Controlling driver memory usage by limiting amount of + * buffers created. Only SEP_DOUBLEBUF_USERS_LIMIT number + * of threads can progress further at a time + */ + dev_dbg(&sep->pdev->dev, "[PID%d] waiting for double buffering " + "region access\n", current->pid); + error = down_interruptible(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region start\n", + current->pid); + if (error) { + /* Signal received */ + goto end_function_error; + } + + + /* + * Prepare contents of the shared area regions for + * the operation into temporary buffers + */ + if (0 < call_hdr.num_dcbs) { + error = sep_create_dcb_dmatables_context(sep, + &dcb_region, + &dmatables_region, + &dma_ctx, + (const struct build_dcb_struct __user *) + buf_user, + call_hdr.num_dcbs); + if (error) + goto end_function_error_doublebuf; + + buf_user += call_hdr.num_dcbs * sizeof(struct build_dcb_struct); + } + + error = sep_create_msgarea_context(sep, + &msg_region, + buf_user, + call_hdr.msg_len); + if (error) + goto end_function_error_doublebuf; + + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue status\n", + current->pid); + my_queue_elem = sep_queue_status_add(sep, + ((struct sep_msgarea_hdr *)msg_region)->opcode, + (dma_ctx) ? dma_ctx->input_data_len : 0, + current->pid, + current->comm, sizeof(current->comm)); + + if (!my_queue_elem) { + dev_dbg(&sep->pdev->dev, "[PID%d] updating queue" + "status error\n", current->pid); + error = -ENOMEM; + goto end_function_error_doublebuf; + } + + /* Wait until current process gets the transaction */ + error = sep_wait_transaction(sep); + + if (error) { + /* Interrupted by signal, don't clear transaction */ + dev_dbg(&sep->pdev->dev, "[PID%d] interrupted by signal\n", + current->pid); + sep_queue_status_remove(sep, &my_queue_elem); + goto end_function_error_doublebuf; + } + + dev_dbg(&sep->pdev->dev, "[PID%d] saving queue element\n", + current->pid); + private_data->my_queue_elem = my_queue_elem; + + /* Activate shared area regions for the transaction */ + error = sep_activate_msgarea_context(sep, &msg_region, + call_hdr.msg_len); + if (error) + goto end_function_error_clear_transact; + + sep_dump_message(sep); + + if (0 < call_hdr.num_dcbs) { + error = sep_activate_dcb_dmatables_context(sep, + &dcb_region, + &dmatables_region, + dma_ctx); + if (error) + goto end_function_error_clear_transact; + } + + /* Send command to SEP */ + error = sep_send_command_handler(sep); + if (error) + goto end_function_error_clear_transact; + + /* Store DMA context for the transaction */ + private_data->dma_ctx = dma_ctx; + /* Update call status */ + set_bit(SEP_FASTCALL_WRITE_DONE_OFFSET, &call_status->status); + error = count_user; + + up(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n", + current->pid); + + goto end_function; + +end_function_error_clear_transact: + sep_end_transaction_handler(sep, &dma_ctx, call_status, + &private_data->my_queue_elem); + +end_function_error_doublebuf: + up(&sep->sep_doublebuf); + dev_dbg(&sep->pdev->dev, "[PID%d] double buffering region end\n", + current->pid); + +end_function_error: + if (dma_ctx) + sep_free_dma_table_data_handler(sep, &dma_ctx); + +end_function: + kfree(dcb_region); + kfree(dmatables_region); + kfree(msg_region); + + return error; +} +/** + * sep_seek - Handler for seek system call + * @filp: File pointer + * @offset: File offset + * @origin: Options for offset + * + * Fastcall interface does not support seeking, all reads + * and writes are from/to offset zero + */ +static loff_t sep_seek(struct file *filp, loff_t offset, int origin) +{ + return -ENOSYS; +} + + + +/** + * sep_file_operations - file operation on sep device + * @sep_ioctl: ioctl handler from user space call + * @sep_poll: poll handler + * @sep_open: handles sep device open request + * @sep_release:handles sep device release request + * @sep_mmap: handles memory mapping requests + * @sep_read: handles read request on sep device + * @sep_write: handles write request on sep device + * @sep_seek: handles seek request on sep device + */ +static const struct file_operations sep_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_ioctl, + .poll = sep_poll, + .open = sep_open, + .release = sep_release, + .mmap = sep_mmap, + .read = sep_read, + .write = sep_write, + .llseek = sep_seek, +}; + +/** + * sep_sysfs_read - read sysfs entry per gives arguments + * @filp: file pointer + * @kobj: kobject pointer + * @attr: binary file attributes + * @buf: read to this buffer + * @pos: offset to read + * @count: amount of data to read + * + * This function is to read sysfs entries for sep driver per given arguments. + */ +static ssize_t +sep_sysfs_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t pos, size_t count) +{ + unsigned long lck_flags; + size_t nleft = count; + struct sep_device *sep = sep_dev; + struct sep_queue_info *queue_elem = NULL; + u32 queue_num = 0; + u32 i = 1; + + spin_lock_irqsave(&sep->sep_queue_lock, lck_flags); + + queue_num = sep->sep_queue_num; + if (queue_num > SEP_DOUBLEBUF_USERS_LIMIT) + queue_num = SEP_DOUBLEBUF_USERS_LIMIT; + + + if (count < sizeof(queue_num) + + (queue_num * sizeof(struct sep_queue_data))) { + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + return -EINVAL; + } + + memcpy(buf, &queue_num, sizeof(queue_num)); + buf += sizeof(queue_num); + nleft -= sizeof(queue_num); + + list_for_each_entry(queue_elem, &sep->sep_queue_status, list) { + if (i++ > queue_num) + break; + + memcpy(buf, &queue_elem->data, sizeof(queue_elem->data)); + nleft -= sizeof(queue_elem->data); + buf += sizeof(queue_elem->data); + } + spin_unlock_irqrestore(&sep->sep_queue_lock, lck_flags); + + return count - nleft; +} + +/** + * bin_attributes - defines attributes for queue_status + * @attr: attributes (name & permissions) + * @read: function pointer to read this file + * @size: maxinum size of binary attribute + */ +static const struct bin_attribute queue_status = { + .attr = {.name = "queue_status", .mode = 0444}, + .read = sep_sysfs_read, + .size = sizeof(u32) + + (SEP_DOUBLEBUF_USERS_LIMIT * sizeof(struct sep_queue_data)), +}; + +/** + * sep_register_driver_with_fs - register misc devices + * @sep: pointer to struct sep_device + * + * This function registers the driver with the file system + */ +static int sep_register_driver_with_fs(struct sep_device *sep) +{ + int ret_val; + + sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_sep.name = SEP_DEV_NAME; + sep->miscdev_sep.fops = &sep_file_operations; + + ret_val = misc_register(&sep->miscdev_sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", + ret_val); + return ret_val; + } + + ret_val = device_create_bin_file(sep->miscdev_sep.this_device, + &queue_status); + if (ret_val) { + dev_warn(&sep->pdev->dev, "sysfs attribute1 fails for SEP %x\n", + ret_val); + return ret_val; + } + + return ret_val; +} + + +/** + *sep_probe - probe a matching PCI device + *@pdev: pci_device + *@ent: pci_device_id + * + *Attempt to set up and configure a SEP device that has been + *discovered by the PCI layer. Allocates all required resources. + */ +static int __devinit sep_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int error = 0; + struct sep_device *sep = NULL; + + if (sep_dev != NULL) { + dev_dbg(&pdev->dev, "only one SEP supported.\n"); + return -EBUSY; + } + + /* Enable the device */ + error = pci_enable_device(pdev); + if (error) { + dev_warn(&pdev->dev, "error enabling pci device\n"); + goto end_function; + } + + /* Allocate the sep_device structure for this device */ + sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); + if (sep_dev == NULL) { + dev_warn(&pdev->dev, + "can't kmalloc the sep_device structure\n"); + error = -ENOMEM; + goto end_function_disable_device; + } + + /* + * We're going to use another variable for actually + * working with the device; this way, if we have + * multiple devices in the future, it would be easier + * to make appropriate changes + */ + sep = sep_dev; + + sep->pdev = pci_dev_get(pdev); + + init_waitqueue_head(&sep->event_transactions); + init_waitqueue_head(&sep->event_interrupt); + spin_lock_init(&sep->snd_rply_lck); + spin_lock_init(&sep->sep_queue_lock); + sema_init(&sep->sep_doublebuf, SEP_DOUBLEBUF_USERS_LIMIT); + + INIT_LIST_HEAD(&sep->sep_queue_status); + + dev_dbg(&sep->pdev->dev, "sep probe: PCI obtained, " + "device being prepared\n"); + dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); + + /* Set up our register area */ + sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); + if (!sep->reg_physical_addr) { + dev_warn(&sep->pdev->dev, "Error getting register start\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + sep->reg_physical_end = pci_resource_end(sep->pdev, 0); + if (!sep->reg_physical_end) { + dev_warn(&sep->pdev->dev, "Error getting register end\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, + (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); + if (!sep->reg_addr) { + dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); + error = -ENODEV; + goto end_function_free_sep_dev; + } + + dev_dbg(&sep->pdev->dev, + "Register area start %llx end %llx virtual %p\n", + (unsigned long long)sep->reg_physical_addr, + (unsigned long long)sep->reg_physical_end, + sep->reg_addr); + + /* Allocate the shared area */ + sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; + + if (sep_map_and_alloc_shared_area(sep)) { + error = -ENOMEM; + /* Allocation failed */ + goto end_function_error; + } + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + /* Get the interrupt line */ + error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, + "sep_driver", sep); + + if (error) + goto end_function_deallocate_sep_shared_area; + + /* The new chip requires a shared area reconfigure */ + if (sep->pdev->revision != 0) { /* Only for new chip */ + error = sep_reconfig_shared_area(sep); + if (error) + goto end_function_free_irq; + } + + sep->in_use = 1; + + /* Finally magic up the device nodes */ + /* Register driver with the fs */ + error = sep_register_driver_with_fs(sep); + if (error) + goto end_function_free_irq; + +#ifdef SEP_ENABLE_RUNTIME_PM + pm_runtime_put_noidle(&sep->pdev->dev); + pm_runtime_allow(&sep->pdev->dev); + pm_runtime_set_autosuspend_delay(&sep->pdev->dev, + SUSPEND_DELAY); + pm_runtime_use_autosuspend(&sep->pdev->dev); + sep->power_save_setup = 1; +#endif + + sep->in_use = 0; + + /* register kernel crypto driver */ + error = sep_crypto_setup(); + if (error) { + dev_dbg(&sep->pdev->dev, "crypto setup fail\n"); + goto end_function_free_irq; + } + + goto end_function; + +end_function_free_irq: + free_irq(pdev->irq, sep); + +end_function_deallocate_sep_shared_area: + /* De-allocate shared area */ + sep_unmap_and_free_shared_area(sep); + +end_function_error: + iounmap(sep->reg_addr); + +end_function_free_sep_dev: + pci_dev_put(sep_dev->pdev); + kfree(sep_dev); + sep_dev = NULL; + +end_function_disable_device: + pci_disable_device(pdev); + +end_function: + return error; +} + +/** + * sep_remove - handles removing device from pci subsystem + * @pdev: pointer to pci device + * + * This function will handle removing our sep device from pci subsystem on exit + * or unloading this module. It should free up all used resources, and unmap if + * any memory regions mapped. + */ +static void sep_remove(struct pci_dev *pdev) +{ + struct sep_device *sep = sep_dev; + + /* Unregister from fs */ + misc_deregister(&sep->miscdev_sep); + + /* Unregister from kernel crypto */ + sep_crypto_takedown(); + + /* Free the irq */ + free_irq(sep->pdev->irq, sep); + + /* Free the shared area */ + sep_unmap_and_free_shared_area(sep_dev); + iounmap((void __iomem *)sep_dev->reg_addr); + +#ifdef SEP_ENABLE_RUNTIME_PM + if (sep->in_use) { + sep->in_use = 0; + pm_runtime_forbid(&sep->pdev->dev); + pm_runtime_get_noresume(&sep->pdev->dev); + } +#endif + pci_dev_put(sep_dev->pdev); + kfree(sep_dev); + sep_dev = NULL; +} + +/* Initialize struct pci_device_id for our driver */ +static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, + {0} +}; + +/* Export our pci_device_id structure to user space */ +MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); + +#ifdef SEP_ENABLE_RUNTIME_PM + +/** + * sep_pm_resume - rsume routine while waking up from S3 state + * @dev: pointer to sep device + * + * This function is to be used to wake up sep driver while system awakes from S3 + * state i.e. suspend to ram. The RAM in intact. + * Notes - revisit with more understanding of pm, ICR/IMR & counters. + */ +static int sep_pci_resume(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pci resume called\n"); + + if (sep->power_state == SEP_DRIVER_POWERON) + return 0; + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + sep->power_state = SEP_DRIVER_POWERON; + + return 0; +} + +/** + * sep_pm_suspend - suspend routine while going to S3 state + * @dev: pointer to sep device + * + * This function is to be used to suspend sep driver while system goes to S3 + * state i.e. suspend to ram. The RAM in intact and ON during this suspend. + * Notes - revisit with more understanding of pm, ICR/IMR + */ +static int sep_pci_suspend(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pci suspend called\n"); + if (sep->in_use == 1) + return -EAGAIN; + + sep->power_state = SEP_DRIVER_POWEROFF; + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR to block all */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, 0xFFFFFFFF); + + return 0; +} + +/** + * sep_pm_runtime_resume - runtime resume routine + * @dev: pointer to sep device + * + * Notes - revisit with more understanding of pm, ICR/IMR & counters + */ +static int sep_pm_runtime_resume(struct device *dev) +{ + + u32 retval2; + u32 delay_count; + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pm runtime resume called\n"); + + /** + * Wait until the SCU boot is ready + * This is done by iterating SCU_DELAY_ITERATION (10 + * microseconds each) up to SCU_DELAY_MAX (50) times. + * This bit can be set in a random time that is less + * than 500 microseconds after each power resume + */ + retval2 = 0; + delay_count = 0; + while ((!retval2) && (delay_count < SCU_DELAY_MAX)) { + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + retval2 &= 0x00000008; + if (!retval2) { + udelay(SCU_DELAY_ITERATION); + delay_count += 1; + } + } + + if (!retval2) { + dev_warn(&sep->pdev->dev, "scu boot bit not set at resume\n"); + return -EINVAL; + } + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* Set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + + return 0; +} + +/** + * sep_pm_runtime_suspend - runtime suspend routine + * @dev: pointer to sep device + * + * Notes - revisit with more understanding of pm + */ +static int sep_pm_runtime_suspend(struct device *dev) +{ + struct sep_device *sep = sep_dev; + + dev_dbg(&sep->pdev->dev, "pm runtime suspend called\n"); + + /* Clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + return 0; +} + +/** + * sep_pm - power management for sep driver + * @sep_pm_runtime_resume: resume- no communication with cpu & main memory + * @sep_pm_runtime_suspend: suspend- no communication with cpu & main memory + * @sep_pci_suspend: suspend - main memory is still ON + * @sep_pci_resume: resume - main meory is still ON + */ +static const struct dev_pm_ops sep_pm = { + .runtime_resume = sep_pm_runtime_resume, + .runtime_suspend = sep_pm_runtime_suspend, + .resume = sep_pci_resume, + .suspend = sep_pci_suspend, +}; +#endif /* SEP_ENABLE_RUNTIME_PM */ + +/** + * sep_pci_driver - registers this device with pci subsystem + * @name: name identifier for this driver + * @sep_pci_id_tbl: pointer to struct pci_device_id table + * @sep_probe: pointer to probe function in PCI driver + * @sep_remove: pointer to remove function in PCI driver + */ +static struct pci_driver sep_pci_driver = { +#ifdef SEP_ENABLE_RUNTIME_PM + .driver = { + .pm = &sep_pm, + }, +#endif + .name = "sep_sec_driver", + .id_table = sep_pci_id_tbl, + .probe = sep_probe, + .remove = sep_remove +}; + +/** + * sep_init - init function + * + * Module load time. Register the PCI device driver. + */ + +static int __init sep_init(void) +{ + return pci_register_driver(&sep_pci_driver); +} + + +/** + * sep_exit - called to unload driver + * + * Unregister the driver The device will perform all the cleanup required. + */ +static void __exit sep_exit(void) +{ + pci_unregister_driver(&sep_pci_driver); +} + + +module_init(sep_init); +module_exit(sep_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sep/sep_trace_events.h b/drivers/staging/sep/sep_trace_events.h new file mode 100644 index 00000000000..2b053a93afe --- /dev/null +++ b/drivers/staging/sep/sep_trace_events.h @@ -0,0 +1,188 @@ +/* + * If TRACE_SYSTEM is defined, that will be the directory created + * in the ftrace directory under /sys/kernel/debug/tracing/events/ + * + * The define_trace.h below will also look for a file name of + * TRACE_SYSTEM.h where TRACE_SYSTEM is what is defined here. + * In this case, it would look for sample.h + * + * If the header name will be different than the system name + * (as in this case), then you can override the header name that + * define_trace.h will look up by defining TRACE_INCLUDE_FILE + * + * This file is called trace-events-sample.h but we want the system + * to be called "sample". Therefore we must define the name of this + * file: + * + * #define TRACE_INCLUDE_FILE trace-events-sample + * + * As we do an the bottom of this file. + * + * Notice that TRACE_SYSTEM should be defined outside of #if + * protection, just like TRACE_INCLUDE_FILE. + */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM sep + +/* + * Notice that this file is not protected like a normal header. + * We also must allow for rereading of this file. The + * + * || defined(TRACE_HEADER_MULTI_READ) + * + * serves this purpose. + */ +#if !defined(_TRACE_SEP_EVENTS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_SEP_EVENTS_H + +#ifdef SEP_PERF_DEBUG +#define SEP_TRACE_FUNC_IN() trace_sep_func_start(__func__, 0) +#define SEP_TRACE_FUNC_OUT(branch) trace_sep_func_end(__func__, branch) +#define SEP_TRACE_EVENT(branch) trace_sep_misc_event(__func__, branch) +#else +#define SEP_TRACE_FUNC_IN() +#define SEP_TRACE_FUNC_OUT(branch) +#define SEP_TRACE_EVENT(branch) +#endif + + +/* + * All trace headers should include tracepoint.h, until we finally + * make it into a standard header. + */ +#include + +/* + * The TRACE_EVENT macro is broken up into 5 parts. + * + * name: name of the trace point. This is also how to enable the tracepoint. + * A function called trace_foo_bar() will be created. + * + * proto: the prototype of the function trace_foo_bar() + * Here it is trace_foo_bar(char *foo, int bar). + * + * args: must match the arguments in the prototype. + * Here it is simply "foo, bar". + * + * struct: This defines the way the data will be stored in the ring buffer. + * There are currently two types of elements. __field and __array. + * a __field is broken up into (type, name). Where type can be any + * type but an array. + * For an array. there are three fields. (type, name, size). The + * type of elements in the array, the name of the field and the size + * of the array. + * + * __array( char, foo, 10) is the same as saying char foo[10]. + * + * fast_assign: This is a C like function that is used to store the items + * into the ring buffer. + * + * printk: This is a way to print out the data in pretty print. This is + * useful if the system crashes and you are logging via a serial line, + * the data can be printed to the console using this "printk" method. + * + * Note, that for both the assign and the printk, __entry is the handler + * to the data structure in the ring buffer, and is defined by the + * TP_STRUCT__entry. + */ +TRACE_EVENT(sep_func_start, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("func_start %s %d", __entry->name, __entry->branch) +); + +TRACE_EVENT(sep_func_end, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("func_end %s %d", __entry->name, __entry->branch) +); + +TRACE_EVENT(sep_misc_event, + + TP_PROTO(const char *name, int branch), + + TP_ARGS(name, branch), + + TP_STRUCT__entry( + __array(char, name, 20) + __field(int, branch) + ), + + TP_fast_assign( + strncpy(__entry->name, name, 20); + __entry->branch = branch; + ), + + TP_printk("misc_event %s %d", __entry->name, __entry->branch) +); + + +#endif + +/***** NOTICE! The #if protection ends here. *****/ + + +/* + * There are several ways I could have done this. If I left out the + * TRACE_INCLUDE_PATH, then it would default to the kernel source + * include/trace/events directory. + * + * I could specify a path from the define_trace.h file back to this + * file. + * + * #define TRACE_INCLUDE_PATH ../../samples/trace_events + * + * But the safest and easiest way to simply make it use the directory + * that the file is in is to add in the Makefile: + * + * CFLAGS_trace-events-sample.o := -I$(src) + * + * This will make sure the current path is part of the include + * structure for our file so that define_trace.h can find it. + * + * I could have made only the top level directory the include: + * + * CFLAGS_trace-events-sample.o := -I$(PWD) + * + * And then let the path to this directory be the TRACE_INCLUDE_PATH: + * + * #define TRACE_INCLUDE_PATH samples/trace_events + * + * But then if something defines "samples" or "trace_events" as a macro + * then we could risk that being converted too, and give us an unexpected + * result. + */ +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +/* + * TRACE_INCLUDE_FILE is not needed if the filename and TRACE_SYSTEM are equal + */ +#define TRACE_INCLUDE_FILE sep_trace_events +#include -- cgit v1.2.3-70-g09d2 From 5c0480f21f9896c443b0e65d779c8e09a695da7b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:30 +0100 Subject: drm/i915: fall through pwrite_gtt_slow to the shmem slow path The gtt_pwrite slowpath grabs the userspace memory with get_user_pages. This will not work for non-page backed memory, like a gtt mmapped gem object. Hence fall throuh to the shmem paths if we hit -EFAULT in the gtt paths. Now the shmem paths have exactly the same problem, but this way we only need to rearrange the code in one write path. v2: v1 accidentaly falls back to shmem pwrite for phys objects. Fixed. v3: Make the codeflow around phys_pwrite cleara as suggested by Chris Wilson. Reviewed-by: Chris Wilson Signed-Off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index df23c627341..7bb32ecc13c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -996,10 +996,13 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj->phys_obj) + if (obj->phys_obj) { ret = i915_gem_phys_pwrite(dev, obj, args, file); - else if (obj->gtt_space && - obj->base.write_domain != I915_GEM_DOMAIN_CPU) { + goto out; + } + + if (obj->gtt_space && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1018,18 +1021,24 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, out_unpin: i915_gem_object_unpin(obj); - } else { - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - ret = -EFAULT; - if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); - if (ret == -EFAULT) - ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + if (ret != -EFAULT) + goto out; + /* Fall through to the shmfs paths because the gtt paths might + * fail with non-page-backed user pointers (e.g. gtt mappings + * when moving data between textures). */ } + ret = i915_gem_object_set_to_cpu_domain(obj, 1); + if (ret) + goto out; + + ret = -EFAULT; + if (!i915_gem_object_needs_bit17_swizzle(obj)) + ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); + if (ret == -EFAULT) + ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); + out: drm_gem_object_unreference(&obj->base); unlock: -- cgit v1.2.3-70-g09d2 From 8c59967c448af5d77fe5189d0e73f32cd3dbe439 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:31 +0100 Subject: drm/i915: rewrite shmem_pwrite_slow to use copy_from_user ... instead of get_user_pages, because that fails on non page-backed user addresses like e.g. a gtt mapping of a bo. To get there essentially copy the vfs read path into pagecache. We can't call that right away because we have to take care of bit17 swizzling. To not deadlock with our own pagefault handler we need to completely drop struct_mutex, reducing the atomicty-guarantees of our userspace abi. Implications for racing with other gem ioctl: - execbuf, pwrite, pread: Due to -EFAULT fallback to slow paths there's already the risk of the pwrite call not being atomic, no degration. - read/write access to mmaps: already fully racy, no degration. - set_tiling: Calling set_tiling while reading/writing is already pretty much undefined, now it just got a bit worse. set_tiling is only called by libdrm on unused/new bos, so no problem. - set_domain: When changing to the gtt domain while copying (without any read/write access, e.g. for synchronization), we might leave unflushed data in the cpu caches. The clflush_object at the end of pwrite_slow takes care of this problem. - truncating of purgeable objects: the shmem_read_mapping_page call could reinstate backing storage for truncated objects. The check at the end of pwrite_slow takes care of this. v2: - add missing intel_gtt_chipset_flush - add __ to copy_from_user_swizzled as suggest by Chris Wilson. v3: Fixup bit17 swizzling, it swizzled the wrong pages. Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 127 ++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 62 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7bb32ecc13c..3f391aa76d3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -58,6 +58,7 @@ static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); static int i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc); +static void i915_gem_object_truncate(struct drm_i915_gem_object *obj); /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, @@ -385,6 +386,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, return 0; } +static inline int +__copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, + const char *cpu_vaddr, + int length) +{ + int ret, cpu_offset = 0; + + while (length > 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_from_user(gpu_vaddr + swizzled_gpu_offset, + cpu_vaddr + cpu_offset, + this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + /** * This is the fallback shmem pread path, which allocates temporary storage * in kernel space to copy_to_user into outside of the struct_mutex, so we @@ -841,71 +868,36 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - struct mm_struct *mm = current->mm; - struct page **user_pages; ssize_t remain; - loff_t offset, pinned_pages, i; - loff_t first_data_page, last_data_page, num_pages; - int shmem_page_offset; - int data_page_index, data_page_offset; - int page_length; - int ret; - uint64_t data_ptr = args->data_ptr; - int do_bit17_swizzling; + loff_t offset; + char __user *user_data; + int shmem_page_offset, page_length, ret; + int obj_do_bit17_swizzling, page_do_bit17_swizzling; + user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - /* Pin the user pages containing the data. We can't fault while - * holding the struct mutex, and all of the pwrite implementations - * want to hold it while dereferencing the user data. - */ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; - - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; - - mutex_unlock(&dev->struct_mutex); - down_read(&mm->mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, - num_pages, 0, 0, user_pages, NULL); - up_read(&mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - if (pinned_pages < num_pages) { - ret = -EFAULT; - goto out; - } - - ret = i915_gem_object_set_to_cpu_domain(obj, 1); - if (ret) - goto out; - - do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); + obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); offset = args->offset; obj->dirty = 1; + mutex_unlock(&dev->struct_mutex); + while (remain > 0) { struct page *page; + char *vaddr; /* Operation in this page * * shmem_page_offset = offset within page in shmem file - * data_page_index = page number in get_user_pages return - * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ shmem_page_offset = offset_in_page(offset); - data_page_index = data_ptr / PAGE_SIZE - first_data_page; - data_page_offset = offset_in_page(data_ptr); page_length = remain; if ((shmem_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - shmem_page_offset; - if ((data_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - data_page_offset; page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { @@ -913,34 +905,45 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, goto out; } - if (do_bit17_swizzling) { - slow_shmem_bit17_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 0); - } else { - slow_shmem_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length); - } + page_do_bit17_swizzling = obj_do_bit17_swizzling && + (page_to_phys(page) & (1 << 17)) != 0; + + vaddr = kmap(page); + if (page_do_bit17_swizzling) + ret = __copy_from_user_swizzled(vaddr, shmem_page_offset, + user_data, + page_length); + else + ret = __copy_from_user(vaddr + shmem_page_offset, + user_data, + page_length); + kunmap(page); set_page_dirty(page); mark_page_accessed(page); page_cache_release(page); + if (ret) { + ret = -EFAULT; + goto out; + } + remain -= page_length; - data_ptr += page_length; + user_data += page_length; offset += page_length; } out: - for (i = 0; i < pinned_pages; i++) - page_cache_release(user_pages[i]); - drm_free_large(user_pages); + mutex_lock(&dev->struct_mutex); + /* Fixup: Kill any reinstated backing storage pages */ + if (obj->madv == __I915_MADV_PURGED) + i915_gem_object_truncate(obj); + /* and flush dirty cachelines in case the object isn't in the cpu write + * domain anymore. */ + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) { + i915_gem_clflush_object(obj); + intel_gtt_chipset_flush(); + } return ret; } -- cgit v1.2.3-70-g09d2 From 8461d2267726dddcb9b5d6ae6b32769b38a326cc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 14 Dec 2011 13:57:32 +0100 Subject: drm/i915: rewrite shmem_pread_slow to use copy_to_user Like for shmem_pwrite_slow. The only difference is that because we read data, we can leave the fetched cachelines in the cpu: In the case that the object isn't in the cpu read domain anymore, the clflush for the next cpu read domain invalidation will simply drop these cachelines. slow_shmem_bit17_copy is now ununsed, so kill it. With this patch tests/gem_mmap_gtt now actually works. v2: add __ to copy_to_user_swizzled as suggested by Chris Wilson. v3: Fixup the swizzling logic, it swizzled the wrong pages. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=38115 Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 191 ++++++++++++---------------------------- 1 file changed, 57 insertions(+), 134 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3f391aa76d3..51a2b0c2a30 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -259,73 +259,6 @@ static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) obj->tiling_mode != I915_TILING_NONE; } -static inline void -slow_shmem_copy(struct page *dst_page, - int dst_offset, - struct page *src_page, - int src_offset, - int length) -{ - char *dst_vaddr, *src_vaddr; - - dst_vaddr = kmap(dst_page); - src_vaddr = kmap(src_page); - - memcpy(dst_vaddr + dst_offset, src_vaddr + src_offset, length); - - kunmap(src_page); - kunmap(dst_page); -} - -static inline void -slow_shmem_bit17_copy(struct page *gpu_page, - int gpu_offset, - struct page *cpu_page, - int cpu_offset, - int length, - int is_read) -{ - char *gpu_vaddr, *cpu_vaddr; - - /* Use the unswizzled path if this page isn't affected. */ - if ((page_to_phys(gpu_page) & (1 << 17)) == 0) { - if (is_read) - return slow_shmem_copy(cpu_page, cpu_offset, - gpu_page, gpu_offset, length); - else - return slow_shmem_copy(gpu_page, gpu_offset, - cpu_page, cpu_offset, length); - } - - gpu_vaddr = kmap(gpu_page); - cpu_vaddr = kmap(cpu_page); - - /* Copy the data, XORing A6 with A17 (1). The user already knows he's - * XORing with the other bits (A9 for Y, A9 and A10 for X) - */ - while (length > 0) { - int cacheline_end = ALIGN(gpu_offset + 1, 64); - int this_length = min(cacheline_end - gpu_offset, length); - int swizzled_gpu_offset = gpu_offset ^ 64; - - if (is_read) { - memcpy(cpu_vaddr + cpu_offset, - gpu_vaddr + swizzled_gpu_offset, - this_length); - } else { - memcpy(gpu_vaddr + swizzled_gpu_offset, - cpu_vaddr + cpu_offset, - this_length); - } - cpu_offset += this_length; - gpu_offset += this_length; - length -= this_length; - } - - kunmap(cpu_page); - kunmap(gpu_page); -} - /** * This is the fast shmem pread path, which attempts to copy_from_user directly * from the backing pages of the object to the user's address space. On a @@ -386,6 +319,32 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, return 0; } +static inline int +__copy_to_user_swizzled(char __user *cpu_vaddr, + const char *gpu_vaddr, int gpu_offset, + int length) +{ + int ret, cpu_offset = 0; + + while (length > 0) { + int cacheline_end = ALIGN(gpu_offset + 1, 64); + int this_length = min(cacheline_end - gpu_offset, length); + int swizzled_gpu_offset = gpu_offset ^ 64; + + ret = __copy_to_user(cpu_vaddr + cpu_offset, + gpu_vaddr + swizzled_gpu_offset, + this_length); + if (ret) + return ret + length; + + cpu_offset += this_length; + gpu_offset += this_length; + length -= this_length; + } + + return 0; +} + static inline int __copy_from_user_swizzled(char __user *gpu_vaddr, int gpu_offset, const char *cpu_vaddr, @@ -425,72 +384,34 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_file *file) { struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; - struct mm_struct *mm = current->mm; - struct page **user_pages; + char __user *user_data; ssize_t remain; - loff_t offset, pinned_pages, i; - loff_t first_data_page, last_data_page, num_pages; - int shmem_page_offset; - int data_page_index, data_page_offset; - int page_length; - int ret; - uint64_t data_ptr = args->data_ptr; - int do_bit17_swizzling; + loff_t offset; + int shmem_page_offset, page_length, ret; + int obj_do_bit17_swizzling, page_do_bit17_swizzling; + user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - /* Pin the user pages containing the data. We can't fault while - * holding the struct mutex, yet we want to hold it while - * dereferencing the user data. - */ - first_data_page = data_ptr / PAGE_SIZE; - last_data_page = (data_ptr + args->size - 1) / PAGE_SIZE; - num_pages = last_data_page - first_data_page + 1; + obj_do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - user_pages = drm_malloc_ab(num_pages, sizeof(struct page *)); - if (user_pages == NULL) - return -ENOMEM; + offset = args->offset; mutex_unlock(&dev->struct_mutex); - down_read(&mm->mmap_sem); - pinned_pages = get_user_pages(current, mm, (uintptr_t)args->data_ptr, - num_pages, 1, 0, user_pages, NULL); - up_read(&mm->mmap_sem); - mutex_lock(&dev->struct_mutex); - if (pinned_pages < num_pages) { - ret = -EFAULT; - goto out; - } - - ret = i915_gem_object_set_cpu_read_domain_range(obj, - args->offset, - args->size); - if (ret) - goto out; - - do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - - offset = args->offset; while (remain > 0) { struct page *page; + char *vaddr; /* Operation in this page * * shmem_page_offset = offset within page in shmem file - * data_page_index = page number in get_user_pages return - * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ shmem_page_offset = offset_in_page(offset); - data_page_index = data_ptr / PAGE_SIZE - first_data_page; - data_page_offset = offset_in_page(data_ptr); - page_length = remain; if ((shmem_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - shmem_page_offset; - if ((data_page_offset + page_length) > PAGE_SIZE) - page_length = PAGE_SIZE - data_page_offset; page = shmem_read_mapping_page(mapping, offset >> PAGE_SHIFT); if (IS_ERR(page)) { @@ -498,36 +419,38 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, goto out; } - if (do_bit17_swizzling) { - slow_shmem_bit17_copy(page, - shmem_page_offset, - user_pages[data_page_index], - data_page_offset, - page_length, - 1); - } else { - slow_shmem_copy(user_pages[data_page_index], - data_page_offset, - page, - shmem_page_offset, - page_length); - } + page_do_bit17_swizzling = obj_do_bit17_swizzling && + (page_to_phys(page) & (1 << 17)) != 0; + + vaddr = kmap(page); + if (page_do_bit17_swizzling) + ret = __copy_to_user_swizzled(user_data, + vaddr, shmem_page_offset, + page_length); + else + ret = __copy_to_user(user_data, + vaddr + shmem_page_offset, + page_length); + kunmap(page); mark_page_accessed(page); page_cache_release(page); + if (ret) { + ret = -EFAULT; + goto out; + } + remain -= page_length; - data_ptr += page_length; + user_data += page_length; offset += page_length; } out: - for (i = 0; i < pinned_pages; i++) { - SetPageDirty(user_pages[i]); - mark_page_accessed(user_pages[i]); - page_cache_release(user_pages[i]); - } - drm_free_large(user_pages); + mutex_lock(&dev->struct_mutex); + /* Fixup: Kill any reinstated backing storage pages */ + if (obj->madv == __I915_MADV_PURGED) + i915_gem_object_truncate(obj); return ret; } -- cgit v1.2.3-70-g09d2 From 7bec78e0a82418021dc2e63dea4d2b749953086d Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Jan 2012 10:55:06 +0100 Subject: drivers/dma/pl330.c: add missing iounmap Add missing iounmap in error handling code, in a case where the function already preforms iounmap on some other execution path. This patch additionally adds calls to clk_disable and clk_put. A simplified version of the semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression e; statement S,S1; int ret; @@ e = \(ioremap\|ioremap_nocache\)(...) ... when != iounmap(e) if (<+...e...+>) S ... when any when != iounmap(e) *if (...) { ... when != iounmap(e) return ...; } ... when any iounmap(e); // Signed-off-by: Julia Lawall Signed-off-by: Vinod Koul --- drivers/dma/pl330.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/pl330.c b/drivers/dma/pl330.c index b8ec03ee8e2..84ebea9bc53 100644 --- a/drivers/dma/pl330.c +++ b/drivers/dma/pl330.c @@ -829,7 +829,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) if (IS_ERR(pdmac->clk)) { dev_err(&adev->dev, "Cannot get operation clock.\n"); ret = -EINVAL; - goto probe_err1; + goto probe_err2; } amba_set_drvdata(adev, pdmac); @@ -843,11 +843,11 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ret = request_irq(irq, pl330_irq_handler, 0, dev_name(&adev->dev), pi); if (ret) - goto probe_err2; + goto probe_err3; ret = pl330_add(pi); if (ret) - goto probe_err3; + goto probe_err4; INIT_LIST_HEAD(&pdmac->desc_pool); spin_lock_init(&pdmac->pool_lock); @@ -904,7 +904,7 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) ret = dma_async_device_register(pd); if (ret) { dev_err(&adev->dev, "unable to register DMAC\n"); - goto probe_err4; + goto probe_err5; } dev_info(&adev->dev, @@ -917,10 +917,15 @@ pl330_probe(struct amba_device *adev, const struct amba_id *id) return 0; -probe_err4: +probe_err5: pl330_del(pi); -probe_err3: +probe_err4: free_irq(irq, pi); +probe_err3: +#ifndef CONFIG_PM_RUNTIME + clk_disable(pdmac->clk); +#endif + clk_put(pdmac->clk); probe_err2: iounmap(pi->base); probe_err1: -- cgit v1.2.3-70-g09d2 From 880db3ff17a973bc0e9847299d1fd9cdf4568ee1 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Thu, 12 Jan 2012 22:49:29 +0100 Subject: drivers/dma/amba-pl08x.c: adjust double test Rewrite a duplicated test to test the correct value The semantic match that finds this problem is as follows: (http://coccinelle.lip6.fr/) // @@ expression E; @@ ( * E || ... || E | * E && ... && E ) // Signed-off-by: Julia Lawall Signed-off-by: Vinod Koul --- drivers/dma/amba-pl08x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/amba-pl08x.c b/drivers/dma/amba-pl08x.c index 8a281584458..840c6c0dc53 100644 --- a/drivers/dma/amba-pl08x.c +++ b/drivers/dma/amba-pl08x.c @@ -649,7 +649,7 @@ static int pl08x_fill_llis_for_desc(struct pl08x_driver_data *pl08x, } if ((bd.srcbus.addr % bd.srcbus.buswidth) || - (bd.srcbus.addr % bd.srcbus.buswidth)) { + (bd.dstbus.addr % bd.dstbus.buswidth)) { dev_err(&pl08x->adev->dev, "%s src & dst address must be aligned to src" " & dst width if peripheral is flow controller", -- cgit v1.2.3-70-g09d2 From b9a591664a21a3d342b9e3b09b0aa2223ae7c469 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:09:56 +0800 Subject: dma/imx-sdma: let sdma_run_channel call sdma_enable_channel Let all enable channel code call sdma_enable_channel. Signed-off-by: Richard Zhao Acked-by: Shawn Guo Acked-by: Sascha Hauer Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index e58dbf638cc..46e334d48e8 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -394,6 +394,11 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, return 0; } +static void sdma_enable_channel(struct sdma_engine *sdma, int channel) +{ + __raw_writel(1 << channel, sdma->regs + SDMA_H_START); +} + /* * sdma_run_channel - run a channel and wait till it's done */ @@ -405,7 +410,7 @@ static int sdma_run_channel(struct sdma_channel *sdmac) init_completion(&sdmac->done); - __raw_writel(1 << channel, sdma->regs + SDMA_H_START); + sdma_enable_channel(sdma, channel); ret = wait_for_completion_timeout(&sdmac->done, HZ); @@ -811,11 +816,6 @@ out: return ret; } -static void sdma_enable_channel(struct sdma_engine *sdma, int channel) -{ - __raw_writel(1 << channel, sdma->regs + SDMA_H_START); -} - static dma_cookie_t sdma_assign_cookie(struct sdma_channel *sdmac) { dma_cookie_t cookie = sdmac->chan.cookie; -- cgit v1.2.3-70-g09d2 From c4b56857d17540e8085a04ea479b0239f4ee764c Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:09:57 +0800 Subject: dma/imx-sdma: use readl_relaxed/writel_relaxed and use writel when necessary use readl_relaxed/writel_relaxed in most places, and use writel when enable channel, because it needs memory barrier. Signed-off-by: Richard Zhao Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 46e334d48e8..fd9ce77655b 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -368,9 +368,9 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, if (event_override && mcu_override && dsp_override) return -EINVAL; - evt = __raw_readl(sdma->regs + SDMA_H_EVTOVR); - mcu = __raw_readl(sdma->regs + SDMA_H_HOSTOVR); - dsp = __raw_readl(sdma->regs + SDMA_H_DSPOVR); + evt = readl_relaxed(sdma->regs + SDMA_H_EVTOVR); + mcu = readl_relaxed(sdma->regs + SDMA_H_HOSTOVR); + dsp = readl_relaxed(sdma->regs + SDMA_H_DSPOVR); if (dsp_override) dsp &= ~(1 << channel); @@ -387,16 +387,16 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, else mcu |= (1 << channel); - __raw_writel(evt, sdma->regs + SDMA_H_EVTOVR); - __raw_writel(mcu, sdma->regs + SDMA_H_HOSTOVR); - __raw_writel(dsp, sdma->regs + SDMA_H_DSPOVR); + writel_relaxed(evt, sdma->regs + SDMA_H_EVTOVR); + writel_relaxed(mcu, sdma->regs + SDMA_H_HOSTOVR); + writel_relaxed(dsp, sdma->regs + SDMA_H_DSPOVR); return 0; } static void sdma_enable_channel(struct sdma_engine *sdma, int channel) { - __raw_writel(1 << channel, sdma->regs + SDMA_H_START); + writel(1 << channel, sdma->regs + SDMA_H_START); } /* @@ -460,9 +460,9 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event) u32 val; u32 chnenbl = chnenbl_ofs(sdma, event); - val = __raw_readl(sdma->regs + chnenbl); + val = readl_relaxed(sdma->regs + chnenbl); val |= (1 << channel); - __raw_writel(val, sdma->regs + chnenbl); + writel_relaxed(val, sdma->regs + chnenbl); } static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) @@ -472,9 +472,9 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) u32 chnenbl = chnenbl_ofs(sdma, event); u32 val; - val = __raw_readl(sdma->regs + chnenbl); + val = readl_relaxed(sdma->regs + chnenbl); val &= ~(1 << channel); - __raw_writel(val, sdma->regs + chnenbl); + writel_relaxed(val, sdma->regs + chnenbl); } static void sdma_handle_channel_loop(struct sdma_channel *sdmac) @@ -552,8 +552,8 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) struct sdma_engine *sdma = dev_id; u32 stat; - stat = __raw_readl(sdma->regs + SDMA_H_INTR); - __raw_writel(stat, sdma->regs + SDMA_H_INTR); + stat = readl_relaxed(sdma->regs + SDMA_H_INTR); + writel_relaxed(stat, sdma->regs + SDMA_H_INTR); while (stat) { int channel = fls(stat) - 1; @@ -707,7 +707,7 @@ static void sdma_disable_channel(struct sdma_channel *sdmac) struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; - __raw_writel(1 << channel, sdma->regs + SDMA_H_STATSTOP); + writel_relaxed(1 << channel, sdma->regs + SDMA_H_STATSTOP); sdmac->status = DMA_ERROR; } @@ -780,7 +780,7 @@ static int sdma_set_channel_priority(struct sdma_channel *sdmac, return -EINVAL; } - __raw_writel(priority, sdma->regs + SDMA_CHNPRI_0 + 4 * channel); + writel_relaxed(priority, sdma->regs + SDMA_CHNPRI_0 + 4 * channel); return 0; } @@ -1228,7 +1228,7 @@ static int __init sdma_init(struct sdma_engine *sdma) clk_enable(sdma->clk); /* Be sure SDMA has not started yet */ - __raw_writel(0, sdma->regs + SDMA_H_C0PTR); + writel_relaxed(0, sdma->regs + SDMA_H_C0PTR); sdma->channel_control = dma_alloc_coherent(NULL, MAX_DMA_CHANNELS * sizeof (struct sdma_channel_control) + @@ -1251,11 +1251,11 @@ static int __init sdma_init(struct sdma_engine *sdma) /* disable all channels */ for (i = 0; i < sdma->num_events; i++) - __raw_writel(0, sdma->regs + chnenbl_ofs(sdma, i)); + writel_relaxed(0, sdma->regs + chnenbl_ofs(sdma, i)); /* All channels have priority 0 */ for (i = 0; i < MAX_DMA_CHANNELS; i++) - __raw_writel(0, sdma->regs + SDMA_CHNPRI_0 + i * 4); + writel_relaxed(0, sdma->regs + SDMA_CHNPRI_0 + i * 4); ret = sdma_request_channel(&sdma->channel[0]); if (ret) @@ -1264,16 +1264,16 @@ static int __init sdma_init(struct sdma_engine *sdma) sdma_config_ownership(&sdma->channel[0], false, true, false); /* Set Command Channel (Channel Zero) */ - __raw_writel(0x4050, sdma->regs + SDMA_CHN0ADDR); + writel_relaxed(0x4050, sdma->regs + SDMA_CHN0ADDR); /* Set bits of CONFIG register but with static context switching */ /* FIXME: Check whether to set ACR bit depending on clock ratios */ - __raw_writel(0, sdma->regs + SDMA_H_CONFIG); + writel_relaxed(0, sdma->regs + SDMA_H_CONFIG); - __raw_writel(ccb_phys, sdma->regs + SDMA_H_C0PTR); + writel_relaxed(ccb_phys, sdma->regs + SDMA_H_C0PTR); /* Set bits of CONFIG register with given context switching mode */ - __raw_writel(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); + writel_relaxed(SDMA_H_CONFIG_CSM, sdma->regs + SDMA_H_CONFIG); /* Initializes channel's priorities */ sdma_set_channel_priority(&sdma->channel[0], 7); -- cgit v1.2.3-70-g09d2 From 3bb5e7caf9641b6a532a55cf3a3621ef814f57ee Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:09:58 +0800 Subject: dma/imx-sdma: call sdma_set_channel_priority after sdma_request_channel sdma_request_channel sets the default priority. sdma_alloc_chan_resources should call sdma_set_channel_priority thereafter to over write it. Signed-off-by: Richard Zhao Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index fd9ce77655b..17a9d46bba1 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -873,11 +873,11 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) sdmac->peripheral_type = data->peripheral_type; sdmac->event_id0 = data->dma_request; - ret = sdma_set_channel_priority(sdmac, prio); + ret = sdma_request_channel(sdmac); if (ret) return ret; - ret = sdma_request_channel(sdmac); + ret = sdma_set_channel_priority(sdmac, prio); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From c2c744d3aa48f845626131176772bae2a3c9d5bc Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:09:59 +0800 Subject: dma/imx-sdma: move clk_enable out of sdma_request_channel It makes clk_enable/disable pair more readable, and fix one bug: sdma_init calls sdma_request_channel, but seems don't know sdma_request_channel enabled the clock. Signed-off-by: Richard Zhao Acked-by: Shawn Guo [fixed typo in commit log] Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 17a9d46bba1..1e0e516b481 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -802,8 +802,6 @@ static int sdma_request_channel(struct sdma_channel *sdmac) sdma->channel_control[channel].base_bd_ptr = sdmac->bd_phys; sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys; - clk_enable(sdma->clk); - sdma_set_channel_priority(sdmac, MXC_SDMA_DEFAULT_PRIORITY); init_completion(&sdmac->done); @@ -873,6 +871,9 @@ static int sdma_alloc_chan_resources(struct dma_chan *chan) sdmac->peripheral_type = data->peripheral_type; sdmac->event_id0 = data->dma_request; + + clk_enable(sdmac->sdma->clk); + ret = sdma_request_channel(sdmac); if (ret) return ret; -- cgit v1.2.3-70-g09d2 From b78bd91f47b28ba1290a7eb95d8cf48a357e1b90 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:10:00 +0800 Subject: dma/imx-sdma: use num_events to validate event_id0 event number is not always 32. use num_events for checking instead. Signed-off-by: Richard Zhao Acked-by: Shawn Guo Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 1e0e516b481..5eb96b53e6d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -723,7 +723,7 @@ static int sdma_config_channel(struct sdma_channel *sdmac) sdmac->per_addr = 0; if (sdmac->event_id0) { - if (sdmac->event_id0 > 32) + if (sdmac->event_id0 >= sdmac->sdma->num_events) return -EINVAL; sdma_event_enable(sdmac, sdmac->event_id0); } -- cgit v1.2.3-70-g09d2 From 0bbc1413028e93629a2ecd5588cc427fa834404b Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Fri, 13 Jan 2012 11:10:01 +0800 Subject: dma/imx-sdma: convernt to use bit ops We don't need extra lock, so we use non-atomic bit ops to set/clear bits, merge event_mask0 and event_mask1 into an array, it helps use bit ops. It also fixs the issue: sdmac->event_mask0 = 1 << sdmac->event_id0; sdmac->event_mask1 = 1 << (sdmac->event_id0 - 32); It event_id0 < 32, it shifts negative number. If event_id0 >= 32, it shifts number >= sizeof(int). Both the cases behavior is undefined. Signed-off-by: Richard Zhao Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 68 +++++++++++++++++++++++++------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 5eb96b53e6d..f380e79fd4d 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -260,8 +261,8 @@ struct sdma_channel { unsigned int pc_from_device, pc_to_device; unsigned long flags; dma_addr_t per_address; - u32 event_mask0, event_mask1; - u32 watermark_level; + unsigned long event_mask[2]; + unsigned long watermark_level; u32 shp_addr, per_addr; struct dma_chan chan; spinlock_t lock; @@ -272,7 +273,7 @@ struct sdma_channel { unsigned int chn_real_count; }; -#define IMX_DMA_SG_LOOP (1 << 0) +#define IMX_DMA_SG_LOOP BIT(0) #define MAX_DMA_CHANNELS 32 #define MXC_SDMA_DEFAULT_PRIORITY 1 @@ -346,9 +347,9 @@ static const struct of_device_id sdma_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, sdma_dt_ids); -#define SDMA_H_CONFIG_DSPDMA (1 << 12) /* indicates if the DSPDMA is used */ -#define SDMA_H_CONFIG_RTD_PINS (1 << 11) /* indicates if Real-Time Debug pins are enabled */ -#define SDMA_H_CONFIG_ACR (1 << 4) /* indicates if AHB freq /core freq = 2 or 1 */ +#define SDMA_H_CONFIG_DSPDMA BIT(12) /* indicates if the DSPDMA is used */ +#define SDMA_H_CONFIG_RTD_PINS BIT(11) /* indicates if Real-Time Debug pins are enabled */ +#define SDMA_H_CONFIG_ACR BIT(4) /* indicates if AHB freq /core freq = 2 or 1 */ #define SDMA_H_CONFIG_CSM (3) /* indicates which context switch mode is selected*/ static inline u32 chnenbl_ofs(struct sdma_engine *sdma, unsigned int event) @@ -363,7 +364,7 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, { struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; - u32 evt, mcu, dsp; + unsigned long evt, mcu, dsp; if (event_override && mcu_override && dsp_override) return -EINVAL; @@ -373,19 +374,19 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, dsp = readl_relaxed(sdma->regs + SDMA_H_DSPOVR); if (dsp_override) - dsp &= ~(1 << channel); + __clear_bit(channel, &dsp); else - dsp |= (1 << channel); + __set_bit(channel, &dsp); if (event_override) - evt &= ~(1 << channel); + __clear_bit(channel, &evt); else - evt |= (1 << channel); + __set_bit(channel, &evt); if (mcu_override) - mcu &= ~(1 << channel); + __clear_bit(channel, &mcu); else - mcu |= (1 << channel); + __set_bit(channel, &mcu); writel_relaxed(evt, sdma->regs + SDMA_H_EVTOVR); writel_relaxed(mcu, sdma->regs + SDMA_H_HOSTOVR); @@ -396,7 +397,7 @@ static int sdma_config_ownership(struct sdma_channel *sdmac, static void sdma_enable_channel(struct sdma_engine *sdma, int channel) { - writel(1 << channel, sdma->regs + SDMA_H_START); + writel(BIT(channel), sdma->regs + SDMA_H_START); } /* @@ -457,11 +458,11 @@ static void sdma_event_enable(struct sdma_channel *sdmac, unsigned int event) { struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; - u32 val; + unsigned long val; u32 chnenbl = chnenbl_ofs(sdma, event); val = readl_relaxed(sdma->regs + chnenbl); - val |= (1 << channel); + __set_bit(channel, &val); writel_relaxed(val, sdma->regs + chnenbl); } @@ -470,10 +471,10 @@ static void sdma_event_disable(struct sdma_channel *sdmac, unsigned int event) struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; u32 chnenbl = chnenbl_ofs(sdma, event); - u32 val; + unsigned long val; val = readl_relaxed(sdma->regs + chnenbl); - val &= ~(1 << channel); + __clear_bit(channel, &val); writel_relaxed(val, sdma->regs + chnenbl); } @@ -550,7 +551,7 @@ static void mxc_sdma_handle_channel(struct sdma_channel *sdmac) static irqreturn_t sdma_int_handler(int irq, void *dev_id) { struct sdma_engine *sdma = dev_id; - u32 stat; + unsigned long stat; stat = readl_relaxed(sdma->regs + SDMA_H_INTR); writel_relaxed(stat, sdma->regs + SDMA_H_INTR); @@ -561,7 +562,7 @@ static irqreturn_t sdma_int_handler(int irq, void *dev_id) mxc_sdma_handle_channel(sdmac); - stat &= ~(1 << channel); + __clear_bit(channel, &stat); } return IRQ_HANDLED; @@ -669,11 +670,11 @@ static int sdma_load_context(struct sdma_channel *sdmac) return load_address; dev_dbg(sdma->dev, "load_address = %d\n", load_address); - dev_dbg(sdma->dev, "wml = 0x%08x\n", sdmac->watermark_level); + dev_dbg(sdma->dev, "wml = 0x%08x\n", (u32)sdmac->watermark_level); dev_dbg(sdma->dev, "shp_addr = 0x%08x\n", sdmac->shp_addr); dev_dbg(sdma->dev, "per_addr = 0x%08x\n", sdmac->per_addr); - dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", sdmac->event_mask0); - dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", sdmac->event_mask1); + dev_dbg(sdma->dev, "event_mask0 = 0x%08x\n", (u32)sdmac->event_mask[0]); + dev_dbg(sdma->dev, "event_mask1 = 0x%08x\n", (u32)sdmac->event_mask[1]); mutex_lock(&sdma->channel_0_lock); @@ -683,8 +684,8 @@ static int sdma_load_context(struct sdma_channel *sdmac) /* Send by context the event mask,base address for peripheral * and watermark level */ - context->gReg[0] = sdmac->event_mask1; - context->gReg[1] = sdmac->event_mask0; + context->gReg[0] = sdmac->event_mask[1]; + context->gReg[1] = sdmac->event_mask[0]; context->gReg[2] = sdmac->per_addr; context->gReg[6] = sdmac->shp_addr; context->gReg[7] = sdmac->watermark_level; @@ -707,7 +708,7 @@ static void sdma_disable_channel(struct sdma_channel *sdmac) struct sdma_engine *sdma = sdmac->sdma; int channel = sdmac->channel; - writel_relaxed(1 << channel, sdma->regs + SDMA_H_STATSTOP); + writel_relaxed(BIT(channel), sdma->regs + SDMA_H_STATSTOP); sdmac->status = DMA_ERROR; } @@ -717,8 +718,8 @@ static int sdma_config_channel(struct sdma_channel *sdmac) sdma_disable_channel(sdmac); - sdmac->event_mask0 = 0; - sdmac->event_mask1 = 0; + sdmac->event_mask[0] = 0; + sdmac->event_mask[1] = 0; sdmac->shp_addr = 0; sdmac->per_addr = 0; @@ -746,15 +747,14 @@ static int sdma_config_channel(struct sdma_channel *sdmac) (sdmac->peripheral_type != IMX_DMATYPE_DSP)) { /* Handle multiple event channels differently */ if (sdmac->event_id1) { - sdmac->event_mask1 = 1 << (sdmac->event_id1 % 32); + sdmac->event_mask[1] = BIT(sdmac->event_id1 % 32); if (sdmac->event_id1 > 31) - sdmac->watermark_level |= 1 << 31; - sdmac->event_mask0 = 1 << (sdmac->event_id0 % 32); + __set_bit(31, &sdmac->watermark_level); + sdmac->event_mask[0] = BIT(sdmac->event_id0 % 32); if (sdmac->event_id0 > 31) - sdmac->watermark_level |= 1 << 30; + __set_bit(30, &sdmac->watermark_level); } else { - sdmac->event_mask0 = 1 << sdmac->event_id0; - sdmac->event_mask1 = 1 << (sdmac->event_id0 - 32); + __set_bit(sdmac->event_id0, sdmac->event_mask); } /* Watermark Level */ sdmac->watermark_level |= sdmac->watermark_level; -- cgit v1.2.3-70-g09d2 From 393f9ffb7956c0ab8edb971d2c98d94aad9eeef8 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: pcf8574_keypad - fix typo in Kconfig Correct spelling "connetced" to "connected" in pcf8574_keypad description in drivers/input/misc/Kconfig. Signed-off-by: Masanari Iida Signed-off-by: Dmitry Torokhov --- drivers/input/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 7b46781c30c..c528deadd63 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -415,7 +415,7 @@ config INPUT_PCF8574 tristate "PCF8574 Keypad input device" depends on I2C && EXPERIMENTAL help - Say Y here if you want to support a keypad connetced via I2C + Say Y here if you want to support a keypad connected via I2C with a PCF8574. To compile this driver as a module, choose M here: the -- cgit v1.2.3-70-g09d2 From 8b4a0c1fe3b03c0cfe829413481d69c2e6fd844c Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: wacom - use BTN_TOOL_FINGER to indicate touch device type Tested-by: Chris Bagwell Reviewed-by: Chris Bagwell Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_sys.c | 6 +----- drivers/input/tablet/wacom_wac.c | 4 ++-- 2 files changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 7e63183a6c6..c9588eececf 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -176,7 +176,7 @@ static int wacom_parse_logical_collection(unsigned char *report, /* Logical collection is only used by 3rd gen Bamboo Touch */ features->pktlen = WACOM_PKGLEN_BBTOUCH3; - features->device_type = BTN_TOOL_DOUBLETAP; + features->device_type = BTN_TOOL_FINGER; /* * Stylus and Touch have same active area @@ -286,12 +286,10 @@ static int wacom_parse_hid(struct usb_interface *intf, if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; - features->device_type = BTN_TOOL_DOUBLETAP; } if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; - features->device_type = BTN_TOOL_DOUBLETAP; features->x_phy = get_unaligned_le16(&report[i + 5]); features->x_max = @@ -325,7 +323,6 @@ static int wacom_parse_hid(struct usb_interface *intf, if (features->type == TABLETPC2FG) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_TPC2FG; - features->device_type = BTN_TOOL_DOUBLETAP; features->y_max = get_unaligned_le16(&report[i + 3]); features->y_phy = @@ -334,7 +331,6 @@ static int wacom_parse_hid(struct usb_interface *intf, } else if (features->type == BAMBOO_PT) { /* need to reset back */ features->pktlen = WACOM_PKGLEN_BBTOUCH; - features->device_type = BTN_TOOL_DOUBLETAP; features->y_phy = get_unaligned_le16(&report[i + 3]); features->y_max = diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index a22e7789d91..e18f3623268 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -1317,7 +1317,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, break; case TABLETPC2FG: - if (features->device_type == BTN_TOOL_DOUBLETAP) { + if (features->device_type == BTN_TOOL_FINGER) { input_mt_init_slots(input_dev, 2); input_set_abs_params(input_dev, ABS_MT_TOOL_TYPE, @@ -1366,7 +1366,7 @@ void wacom_setup_input_capabilities(struct input_dev *input_dev, __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->device_type == BTN_TOOL_DOUBLETAP) { + if (features->device_type == BTN_TOOL_FINGER) { __set_bit(BTN_LEFT, input_dev->keybit); __set_bit(BTN_FORWARD, input_dev->keybit); __set_bit(BTN_BACK, input_dev->keybit); -- cgit v1.2.3-70-g09d2 From 31175a8348af76aea2f557857c90467d13632dc3 Mon Sep 17 00:00:00 2001 From: Ping Cheng Date: Tue, 31 Jan 2012 00:07:33 -0800 Subject: Input: wacom - use switch statement for wacom_tpc_irq() And add two new data formats. Tested-by: Chris Bagwell Reviewed-by: Chris Bagwell Signed-off-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 24 ++++++++++++++++++------ drivers/input/tablet/wacom_wac.h | 2 ++ 2 files changed, 20 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index e18f3623268..9283507b13a 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -832,12 +832,24 @@ static int wacom_tpc_irq(struct wacom_wac *wacom, size_t len) dbg("wacom_tpc_irq: received report #%d", data[0]); - if (len == WACOM_PKGLEN_TPC1FG || data[0] == WACOM_REPORT_TPC1FG) - return wacom_tpc_single_touch(wacom, len); - else if (data[0] == WACOM_REPORT_TPC2FG) - return wacom_tpc_mt_touch(wacom); - else if (data[0] == WACOM_REPORT_PENABLED) - return wacom_tpc_pen(wacom); + switch (len) { + case WACOM_PKGLEN_TPC1FG: + return wacom_tpc_single_touch(wacom, len); + + case WACOM_PKGLEN_TPC2FG: + return wacom_tpc_mt_touch(wacom); + + default: + switch (data[0]) { + case WACOM_REPORT_TPC1FG: + case WACOM_REPORT_TPCHID: + case WACOM_REPORT_TPCST: + return wacom_tpc_single_touch(wacom, len); + + case WACOM_REPORT_PENABLED: + return wacom_tpc_pen(wacom); + } + } return 0; } diff --git a/drivers/input/tablet/wacom_wac.h b/drivers/input/tablet/wacom_wac.h index 050acaefee7..4f0ba21b019 100644 --- a/drivers/input/tablet/wacom_wac.h +++ b/drivers/input/tablet/wacom_wac.h @@ -39,6 +39,8 @@ #define WACOM_REPORT_INTUOSPAD 12 #define WACOM_REPORT_TPC1FG 6 #define WACOM_REPORT_TPC2FG 13 +#define WACOM_REPORT_TPCHID 15 +#define WACOM_REPORT_TPCST 16 /* device quirks */ #define WACOM_QUIRK_MULTI_INPUT 0x0001 -- cgit v1.2.3-70-g09d2 From 4065d1e7b2164cff4af57b58fac887df2fe75d2a Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 31 Jan 2012 00:18:00 -0800 Subject: Input: add Cypress TTSP capacitive multi-touch screen support Cypress TrueTouch(tm) Standard Product controllers are found in a wide range of embedded devices. This driver add support for a variety of TTSP controllers. Since the hardware is capable of tracking identifiable contacts, multi-touch protocol type B (stateful) is used to report contact information. The driver is composed of a core driver that process the data sent by the contacts and a set of bus specific interface modules. This patch adds the base core TTSP driver. Signed-off-by: Javier Martinez Canillas Reviewed-by: Henrik Rydberg Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig | 32 +- drivers/input/touchscreen/Makefile | 5 +- drivers/input/touchscreen/cyttsp_core.c | 625 ++++++++++++++++++++++++++++++++ drivers/input/touchscreen/cyttsp_core.h | 149 ++++++++ drivers/input/touchscreen/cyttsp_i2c.c | 146 ++++++++ drivers/input/touchscreen/cyttsp_spi.c | 210 +++++++++++ include/linux/input/cyttsp.h | 58 +++ 7 files changed, 1223 insertions(+), 2 deletions(-) create mode 100644 drivers/input/touchscreen/cyttsp_core.c create mode 100644 drivers/input/touchscreen/cyttsp_core.h create mode 100644 drivers/input/touchscreen/cyttsp_i2c.c create mode 100644 drivers/input/touchscreen/cyttsp_spi.c create mode 100644 include/linux/input/cyttsp.h (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 4af2a18eb3b..2b21a7066d3 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -139,7 +139,6 @@ config TOUCHSCREEN_CY8CTMG110 tristate "cy8ctmg110 touchscreen" depends on I2C depends on GPIOLIB - help Say Y here if you have a cy8ctmg110 capacitive touchscreen on an AAVA device. @@ -149,6 +148,37 @@ config TOUCHSCREEN_CY8CTMG110 To compile this driver as a module, choose M here: the module will be called cy8ctmg110_ts. +config TOUCHSCREEN_CYTTSP_CORE + tristate "Cypress TTSP touchscreen" + help + Say Y here if you have a touchscreen using controller from + the Cypress TrueTouch(tm) Standard Product family connected + to your system. You will also need to select appropriate + bus connection below. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_core. + +config TOUCHSCREEN_CYTTSP_I2C + tristate "support I2C bus connection" + depends on TOUCHSCREEN_CYTTSP_CORE && I2C + help + Say Y here if the touchscreen is connected via I2C bus. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_i2c. + +config TOUCHSCREEN_CYTTSP_SPI + tristate "support SPI bus connection" + depends on TOUCHSCREEN_CYTTSP_CORE && SPI_MASTER + help + Say Y here if the touchscreen is connected via SPI bus. + + To compile this driver as a module, choose M here: the + module will be called cyttsp_spi. + config TOUCHSCREEN_DA9034 tristate "Touchscreen support for Dialog Semiconductor DA9034" depends on PMIC_DA903X diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 496091e8846..d9acbdcda3d 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -16,8 +16,11 @@ obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o obj-$(CONFIG_TOUCHSCREEN_BITSY) += h3600_ts_input.o -obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o +obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C) += cyttsp_i2c.o +obj-$(CONFIG_TOUCHSCREEN_CYTTSP_SPI) += cyttsp_spi.o obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o diff --git a/drivers/input/touchscreen/cyttsp_core.c b/drivers/input/touchscreen/cyttsp_core.c new file mode 100644 index 00000000000..8be22479b41 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_core.c @@ -0,0 +1,625 @@ +/* + * Core Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include +#include +#include +#include +#include +#include + +#include "cyttsp_core.h" + +/* Bootloader number of command keys */ +#define CY_NUM_BL_KEYS 8 + +/* helpers */ +#define GET_NUM_TOUCHES(x) ((x) & 0x0F) +#define IS_LARGE_AREA(x) (((x) & 0x10) >> 4) +#define IS_BAD_PKT(x) ((x) & 0x20) +#define IS_VALID_APP(x) ((x) & 0x01) +#define IS_OPERATIONAL_ERR(x) ((x) & 0x3F) +#define GET_HSTMODE(reg) (((reg) & 0x70) >> 4) +#define GET_BOOTLOADERMODE(reg) (((reg) & 0x10) >> 4) + +#define CY_REG_BASE 0x00 +#define CY_REG_ACT_DIST 0x1E +#define CY_REG_ACT_INTRVL 0x1D +#define CY_REG_TCH_TMOUT (CY_REG_ACT_INTRVL + 1) +#define CY_REG_LP_INTRVL (CY_REG_TCH_TMOUT + 1) +#define CY_MAXZ 255 +#define CY_DELAY_DFLT 20 /* ms */ +#define CY_DELAY_MAX 500 +#define CY_ACT_DIST_DFLT 0xF8 +#define CY_HNDSHK_BIT 0x80 +/* device mode bits */ +#define CY_OPERATE_MODE 0x00 +#define CY_SYSINFO_MODE 0x10 +/* power mode select bits */ +#define CY_SOFT_RESET_MODE 0x01 /* return to Bootloader mode */ +#define CY_DEEP_SLEEP_MODE 0x02 +#define CY_LOW_POWER_MODE 0x04 + +/* Slots management */ +#define CY_MAX_FINGER 4 +#define CY_MAX_ID 16 + +static const u8 bl_command[] = { + 0x00, /* file offset */ + 0xFF, /* command */ + 0xA5, /* exit bootloader command */ + 0, 1, 2, 3, 4, 5, 6, 7 /* default keys */ +}; + +static int ttsp_read_block_data(struct cyttsp *ts, u8 command, + u8 length, void *buf) +{ + int error; + int tries; + + for (tries = 0; tries < CY_NUM_RETRY; tries++) { + error = ts->bus_ops->read(ts, command, length, buf); + if (!error) + return 0; + + msleep(CY_DELAY_DFLT); + } + + return -EIO; +} + +static int ttsp_write_block_data(struct cyttsp *ts, u8 command, + u8 length, void *buf) +{ + int error; + int tries; + + for (tries = 0; tries < CY_NUM_RETRY; tries++) { + error = ts->bus_ops->write(ts, command, length, buf); + if (!error) + return 0; + + msleep(CY_DELAY_DFLT); + } + + return -EIO; +} + +static int ttsp_send_command(struct cyttsp *ts, u8 cmd) +{ + return ttsp_write_block_data(ts, CY_REG_BASE, sizeof(cmd), &cmd); +} + +static int cyttsp_load_bl_regs(struct cyttsp *ts) +{ + memset(&ts->bl_data, 0, sizeof(ts->bl_data)); + ts->bl_data.bl_status = 0x10; + + return ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->bl_data), &ts->bl_data); +} + +static int cyttsp_exit_bl_mode(struct cyttsp *ts) +{ + int error; + u8 bl_cmd[sizeof(bl_command)]; + + memcpy(bl_cmd, bl_command, sizeof(bl_command)); + if (ts->pdata->bl_keys) + memcpy(&bl_cmd[sizeof(bl_command) - CY_NUM_BL_KEYS], + ts->pdata->bl_keys, sizeof(bl_command)); + + error = ttsp_write_block_data(ts, CY_REG_BASE, + sizeof(bl_cmd), bl_cmd); + if (error) + return error; + + /* wait for TTSP Device to complete the operation */ + msleep(CY_DELAY_DFLT); + + error = cyttsp_load_bl_regs(ts); + if (error) + return error; + + if (GET_BOOTLOADERMODE(ts->bl_data.bl_status)) + return -EIO; + + return 0; +} + +static int cyttsp_set_operational_mode(struct cyttsp *ts) +{ + int error; + + error = ttsp_send_command(ts, CY_OPERATE_MODE); + if (error) + return error; + + /* wait for TTSP Device to complete switch to Operational mode */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->xy_data), &ts->xy_data); + if (error) + return error; + + return ts->xy_data.act_dist == CY_ACT_DIST_DFLT ? -EIO : 0; +} + +static int cyttsp_set_sysinfo_mode(struct cyttsp *ts) +{ + int error; + + memset(&ts->sysinfo_data, 0, sizeof(ts->sysinfo_data)); + + /* switch to sysinfo mode */ + error = ttsp_send_command(ts, CY_SYSINFO_MODE); + if (error) + return error; + + /* read sysinfo registers */ + msleep(CY_DELAY_DFLT); + error = ttsp_read_block_data(ts, CY_REG_BASE, sizeof(ts->sysinfo_data), + &ts->sysinfo_data); + if (error) + return error; + + if (!ts->sysinfo_data.tts_verh && !ts->sysinfo_data.tts_verl) + return -EIO; + + return 0; +} + +static int cyttsp_set_sysinfo_regs(struct cyttsp *ts) +{ + int retval = 0; + + if (ts->pdata->act_intrvl != CY_ACT_INTRVL_DFLT || + ts->pdata->tch_tmout != CY_TCH_TMOUT_DFLT || + ts->pdata->lp_intrvl != CY_LP_INTRVL_DFLT) { + + u8 intrvl_ray[] = { + ts->pdata->act_intrvl, + ts->pdata->tch_tmout, + ts->pdata->lp_intrvl + }; + + /* set intrvl registers */ + retval = ttsp_write_block_data(ts, CY_REG_ACT_INTRVL, + sizeof(intrvl_ray), intrvl_ray); + msleep(CY_DELAY_DFLT); + } + + return retval; +} + +static int cyttsp_soft_reset(struct cyttsp *ts) +{ + unsigned long timeout; + int retval; + + /* wait for interrupt to set ready completion */ + INIT_COMPLETION(ts->bl_ready); + ts->state = CY_BL_STATE; + + enable_irq(ts->irq); + + retval = ttsp_send_command(ts, CY_SOFT_RESET_MODE); + if (retval) + goto out; + + timeout = wait_for_completion_timeout(&ts->bl_ready, + msecs_to_jiffies(CY_DELAY_DFLT * CY_DELAY_MAX)); + retval = timeout ? 0 : -EIO; + +out: + ts->state = CY_IDLE_STATE; + disable_irq(ts->irq); + return retval; +} + +static int cyttsp_act_dist_setup(struct cyttsp *ts) +{ + u8 act_dist_setup = ts->pdata->act_dist; + + /* Init gesture; active distance setup */ + return ttsp_write_block_data(ts, CY_REG_ACT_DIST, + sizeof(act_dist_setup), &act_dist_setup); +} + +static void cyttsp_extract_track_ids(struct cyttsp_xydata *xy_data, int *ids) +{ + ids[0] = xy_data->touch12_id >> 4; + ids[1] = xy_data->touch12_id & 0xF; + ids[2] = xy_data->touch34_id >> 4; + ids[3] = xy_data->touch34_id & 0xF; +} + +static const struct cyttsp_tch *cyttsp_get_tch(struct cyttsp_xydata *xy_data, + int idx) +{ + switch (idx) { + case 0: + return &xy_data->tch1; + case 1: + return &xy_data->tch2; + case 2: + return &xy_data->tch3; + case 3: + return &xy_data->tch4; + default: + return NULL; + } +} + +static void cyttsp_report_tchdata(struct cyttsp *ts) +{ + struct cyttsp_xydata *xy_data = &ts->xy_data; + struct input_dev *input = ts->input; + int num_tch = GET_NUM_TOUCHES(xy_data->tt_stat); + const struct cyttsp_tch *tch; + int ids[CY_MAX_ID]; + int i; + DECLARE_BITMAP(used, CY_MAX_ID); + + if (IS_LARGE_AREA(xy_data->tt_stat) == 1) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Large area detected\n", __func__); + } else if (num_tch > CY_MAX_FINGER) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Num touch error detected\n", __func__); + } else if (IS_BAD_PKT(xy_data->tt_mode)) { + /* terminate all active tracks */ + num_tch = 0; + dev_dbg(ts->dev, "%s: Invalid buffer detected\n", __func__); + } + + cyttsp_extract_track_ids(xy_data, ids); + + bitmap_zero(used, CY_MAX_ID); + + for (i = 0; i < num_tch; i++) { + tch = cyttsp_get_tch(xy_data, i); + + input_mt_slot(input, ids[i]); + input_mt_report_slot_state(input, MT_TOOL_FINGER, true); + input_report_abs(input, ABS_MT_POSITION_X, be16_to_cpu(tch->x)); + input_report_abs(input, ABS_MT_POSITION_Y, be16_to_cpu(tch->y)); + input_report_abs(input, ABS_MT_TOUCH_MAJOR, tch->z); + + __set_bit(ids[i], used); + } + + for (i = 0; i < CY_MAX_ID; i++) { + if (test_bit(i, used)) + continue; + + input_mt_slot(input, i); + input_mt_report_slot_state(input, MT_TOOL_FINGER, false); + } + + input_sync(input); +} + +static irqreturn_t cyttsp_irq(int irq, void *handle) +{ + struct cyttsp *ts = handle; + int error; + + if (unlikely(ts->state == CY_BL_STATE)) { + complete(&ts->bl_ready); + goto out; + } + + /* Get touch data from CYTTSP device */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(struct cyttsp_xydata), &ts->xy_data); + if (error) + goto out; + + /* provide flow control handshake */ + if (ts->pdata->use_hndshk) { + error = ttsp_send_command(ts, + ts->xy_data.hst_mode ^ CY_HNDSHK_BIT); + if (error) + goto out; + } + + if (unlikely(ts->state == CY_IDLE_STATE)) + goto out; + + if (GET_BOOTLOADERMODE(ts->xy_data.tt_mode)) { + /* + * TTSP device has reset back to bootloader mode. + * Restore to operational mode. + */ + error = cyttsp_exit_bl_mode(ts); + if (error) { + dev_err(ts->dev, + "Could not return to operational mode, err: %d\n", + error); + ts->state = CY_IDLE_STATE; + } + } else { + cyttsp_report_tchdata(ts); + } + +out: + return IRQ_HANDLED; +} + +static int cyttsp_power_on(struct cyttsp *ts) +{ + int error; + + error = cyttsp_soft_reset(ts); + if (error) + return error; + + error = cyttsp_load_bl_regs(ts); + if (error) + return error; + + if (GET_BOOTLOADERMODE(ts->bl_data.bl_status) && + IS_VALID_APP(ts->bl_data.bl_status)) { + error = cyttsp_exit_bl_mode(ts); + if (error) + return error; + } + + if (GET_HSTMODE(ts->bl_data.bl_file) != CY_OPERATE_MODE || + IS_OPERATIONAL_ERR(ts->bl_data.bl_status)) { + return -ENODEV; + } + + error = cyttsp_set_sysinfo_mode(ts); + if (error) + return error; + + error = cyttsp_set_sysinfo_regs(ts); + if (error) + return error; + + error = cyttsp_set_operational_mode(ts); + if (error) + return error; + + /* init active distance */ + error = cyttsp_act_dist_setup(ts); + if (error) + return error; + + ts->state = CY_ACTIVE_STATE; + + return 0; +} + +static int cyttsp_enable(struct cyttsp *ts) +{ + int error; + + /* + * The device firmware can wake on an I2C or SPI memory slave + * address match. So just reading a register is sufficient to + * wake up the device. The first read attempt will fail but it + * will wake it up making the second read attempt successful. + */ + error = ttsp_read_block_data(ts, CY_REG_BASE, + sizeof(ts->xy_data), &ts->xy_data); + if (error) + return error; + + if (GET_HSTMODE(ts->xy_data.hst_mode)) + return -EIO; + + enable_irq(ts->irq); + + return 0; +} + +static int cyttsp_disable(struct cyttsp *ts) +{ + int error; + + error = ttsp_send_command(ts, CY_LOW_POWER_MODE); + if (error) + return error; + + disable_irq(ts->irq); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int cyttsp_suspend(struct device *dev) +{ + struct cyttsp *ts = dev_get_drvdata(dev); + int retval = 0; + + mutex_lock(&ts->input->mutex); + + if (ts->input->users) { + retval = cyttsp_disable(ts); + if (retval == 0) + ts->suspended = true; + } + + mutex_unlock(&ts->input->mutex); + + return retval; +} + +static int cyttsp_resume(struct device *dev) +{ + struct cyttsp *ts = dev_get_drvdata(dev); + + mutex_lock(&ts->input->mutex); + + if (ts->input->users) + cyttsp_enable(ts); + + ts->suspended = false; + + mutex_unlock(&ts->input->mutex); + + return 0; +} + +#endif + +SIMPLE_DEV_PM_OPS(cyttsp_pm_ops, cyttsp_suspend, cyttsp_resume); +EXPORT_SYMBOL_GPL(cyttsp_pm_ops); + +static int cyttsp_open(struct input_dev *dev) +{ + struct cyttsp *ts = input_get_drvdata(dev); + int retval = 0; + + if (!ts->suspended) + retval = cyttsp_enable(ts); + + return retval; +} + +static void cyttsp_close(struct input_dev *dev) +{ + struct cyttsp *ts = input_get_drvdata(dev); + + if (!ts->suspended) + cyttsp_disable(ts); +} + +struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, + struct device *dev, int irq, size_t xfer_buf_size) +{ + const struct cyttsp_platform_data *pdata = dev->platform_data; + struct cyttsp *ts; + struct input_dev *input_dev; + int error; + + if (!dev || !bus_ops || !pdata || !pdata->name || irq <= 0) { + error = -EINVAL; + goto err_out; + } + + ts = kzalloc(sizeof(*ts) + xfer_buf_size, GFP_KERNEL); + input_dev = input_allocate_device(); + if (!ts || !input_dev) { + error = -ENOMEM; + goto err_free_mem; + } + + ts->dev = dev; + ts->input = input_dev; + ts->pdata = dev->platform_data; + ts->bus_ops = bus_ops; + ts->irq = irq; + + init_completion(&ts->bl_ready); + snprintf(ts->phys, sizeof(ts->phys), "%s/input0", dev_name(dev)); + + if (pdata->init) { + error = pdata->init(); + if (error) { + dev_err(ts->dev, "platform init failed, err: %d\n", + error); + goto err_free_mem; + } + } + + input_dev->name = pdata->name; + input_dev->phys = ts->phys; + input_dev->id.bustype = bus_ops->bustype; + input_dev->dev.parent = ts->dev; + + input_dev->open = cyttsp_open; + input_dev->close = cyttsp_close; + + input_set_drvdata(input_dev, ts); + + __set_bit(EV_ABS, input_dev->evbit); + input_set_abs_params(input_dev, ABS_MT_POSITION_X, + 0, pdata->maxx, 0, 0); + input_set_abs_params(input_dev, ABS_MT_POSITION_Y, + 0, pdata->maxy, 0, 0); + input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, + 0, CY_MAXZ, 0, 0); + + input_mt_init_slots(input_dev, CY_MAX_ID); + + error = request_threaded_irq(ts->irq, NULL, cyttsp_irq, + IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + pdata->name, ts); + if (error) { + dev_err(ts->dev, "failed to request IRQ %d, err: %d\n", + ts->irq, error); + goto err_platform_exit; + } + + disable_irq(ts->irq); + + error = cyttsp_power_on(ts); + if (error) + goto err_free_irq; + + error = input_register_device(input_dev); + if (error) { + dev_err(ts->dev, "failed to register input device: %d\n", + error); + goto err_free_irq; + } + + return ts; + +err_free_irq: + free_irq(ts->irq, ts); +err_platform_exit: + if (pdata->exit) + pdata->exit(); +err_free_mem: + input_free_device(input_dev); + kfree(ts); +err_out: + return ERR_PTR(error); +} +EXPORT_SYMBOL_GPL(cyttsp_probe); + +void cyttsp_remove(struct cyttsp *ts) +{ + free_irq(ts->irq, ts); + input_unregister_device(ts->input); + if (ts->pdata->exit) + ts->pdata->exit(); + kfree(ts); +} +EXPORT_SYMBOL_GPL(cyttsp_remove); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard touchscreen driver core"); +MODULE_AUTHOR("Cypress"); diff --git a/drivers/input/touchscreen/cyttsp_core.h b/drivers/input/touchscreen/cyttsp_core.h new file mode 100644 index 00000000000..1aa3c6967e7 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_core.h @@ -0,0 +1,149 @@ +/* + * Header file for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + + +#ifndef __CYTTSP_CORE_H__ +#define __CYTTSP_CORE_H__ + +#include +#include +#include +#include +#include +#include + +#define CY_NUM_RETRY 16 /* max number of retries for read ops */ + +struct cyttsp_tch { + __be16 x, y; + u8 z; +} __packed; + +/* TrueTouch Standard Product Gen3 interface definition */ +struct cyttsp_xydata { + u8 hst_mode; + u8 tt_mode; + u8 tt_stat; + struct cyttsp_tch tch1; + u8 touch12_id; + struct cyttsp_tch tch2; + u8 gest_cnt; + u8 gest_id; + struct cyttsp_tch tch3; + u8 touch34_id; + struct cyttsp_tch tch4; + u8 tt_undef[3]; + u8 act_dist; + u8 tt_reserved; +} __packed; + + +/* TTSP System Information interface definition */ +struct cyttsp_sysinfo_data { + u8 hst_mode; + u8 mfg_cmd; + u8 mfg_stat; + u8 cid[3]; + u8 tt_undef1; + u8 uid[8]; + u8 bl_verh; + u8 bl_verl; + u8 tts_verh; + u8 tts_verl; + u8 app_idh; + u8 app_idl; + u8 app_verh; + u8 app_verl; + u8 tt_undef[5]; + u8 scn_typ; + u8 act_intrvl; + u8 tch_tmout; + u8 lp_intrvl; +}; + +/* TTSP Bootloader Register Map interface definition */ +#define CY_BL_CHKSUM_OK 0x01 +struct cyttsp_bootloader_data { + u8 bl_file; + u8 bl_status; + u8 bl_error; + u8 blver_hi; + u8 blver_lo; + u8 bld_blver_hi; + u8 bld_blver_lo; + u8 ttspver_hi; + u8 ttspver_lo; + u8 appid_hi; + u8 appid_lo; + u8 appver_hi; + u8 appver_lo; + u8 cid_0; + u8 cid_1; + u8 cid_2; +}; + +struct cyttsp; + +struct cyttsp_bus_ops { + u16 bustype; + int (*write)(struct cyttsp *ts, + u8 addr, u8 length, const void *values); + int (*read)(struct cyttsp *ts, u8 addr, u8 length, void *values); +}; + +enum cyttsp_state { + CY_IDLE_STATE, + CY_ACTIVE_STATE, + CY_BL_STATE, +}; + +struct cyttsp { + struct device *dev; + int irq; + struct input_dev *input; + char phys[32]; + const struct cyttsp_platform_data *pdata; + const struct cyttsp_bus_ops *bus_ops; + struct cyttsp_bootloader_data bl_data; + struct cyttsp_sysinfo_data sysinfo_data; + struct cyttsp_xydata xy_data; + struct completion bl_ready; + enum cyttsp_state state; + bool suspended; + + u8 xfer_buf[] ____cacheline_aligned; +}; + +struct cyttsp *cyttsp_probe(const struct cyttsp_bus_ops *bus_ops, + struct device *dev, int irq, size_t xfer_buf_size); +void cyttsp_remove(struct cyttsp *ts); + +extern const struct dev_pm_ops cyttsp_pm_ops; + +#endif /* __CYTTSP_CORE_H__ */ diff --git a/drivers/input/touchscreen/cyttsp_i2c.c b/drivers/input/touchscreen/cyttsp_i2c.c new file mode 100644 index 00000000000..c7110cc06b9 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_i2c.c @@ -0,0 +1,146 @@ +/* + * Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) I2C touchscreen driver. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include "cyttsp_core.h" + +#include +#include + +#define CY_I2C_DATA_SIZE 128 + +static int cyttsp_i2c_read_block_data(struct cyttsp *ts, + u8 addr, u8 length, void *values) +{ + struct i2c_client *client = to_i2c_client(ts->dev); + struct i2c_msg msgs[] = { + { + .addr = client->addr, + .flags = 0, + .len = 1, + .buf = &addr, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = values, + }, + }; + int retval; + + retval = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (retval < 0) + return retval; + + return retval != ARRAY_SIZE(msgs) ? -EIO : 0; +} + +static int cyttsp_i2c_write_block_data(struct cyttsp *ts, + u8 addr, u8 length, const void *values) +{ + struct i2c_client *client = to_i2c_client(ts->dev); + int retval; + + ts->xfer_buf[0] = addr; + memcpy(&ts->xfer_buf[1], values, length); + + retval = i2c_master_send(client, ts->xfer_buf, length + 1); + + return retval < 0 ? retval : 0; +} + +static const struct cyttsp_bus_ops cyttsp_i2c_bus_ops = { + .bustype = BUS_I2C, + .write = cyttsp_i2c_write_block_data, + .read = cyttsp_i2c_read_block_data, +}; + +static int __devinit cyttsp_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cyttsp *ts; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + dev_err(&client->dev, "I2C functionality not Supported\n"); + return -EIO; + } + + ts = cyttsp_probe(&cyttsp_i2c_bus_ops, &client->dev, client->irq, + CY_I2C_DATA_SIZE); + + if (IS_ERR(ts)) + return PTR_ERR(ts); + + i2c_set_clientdata(client, ts); + + return 0; +} + +static int __devexit cyttsp_i2c_remove(struct i2c_client *client) +{ + struct cyttsp *ts = i2c_get_clientdata(client); + + cyttsp_remove(ts); + + return 0; +} + +static const struct i2c_device_id cyttsp_i2c_id[] = { + { CY_I2C_NAME, 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, cyttsp_i2c_id); + +static struct i2c_driver cyttsp_i2c_driver = { + .driver = { + .name = CY_I2C_NAME, + .owner = THIS_MODULE, + .pm = &cyttsp_pm_ops, + }, + .probe = cyttsp_i2c_probe, + .remove = __devexit_p(cyttsp_i2c_remove), + .id_table = cyttsp_i2c_id, +}; + +static int __init cyttsp_i2c_init(void) +{ + return i2c_add_driver(&cyttsp_i2c_driver); +} +module_init(cyttsp_i2c_init); + +static void __exit cyttsp_i2c_exit(void) +{ + return i2c_del_driver(&cyttsp_i2c_driver); +} +module_exit(cyttsp_i2c_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) I2C driver"); +MODULE_AUTHOR("Cypress"); +MODULE_ALIAS("i2c:cyttsp"); diff --git a/drivers/input/touchscreen/cyttsp_spi.c b/drivers/input/touchscreen/cyttsp_spi.c new file mode 100644 index 00000000000..9db5f8754d1 --- /dev/null +++ b/drivers/input/touchscreen/cyttsp_spi.c @@ -0,0 +1,210 @@ +/* + * Source for: + * Cypress TrueTouch(TM) Standard Product (TTSP) SPI touchscreen driver. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com + * + */ + +#include "cyttsp_core.h" + +#include +#include +#include + +#define CY_SPI_WR_OP 0x00 /* r/~w */ +#define CY_SPI_RD_OP 0x01 +#define CY_SPI_CMD_BYTES 4 +#define CY_SPI_SYNC_BYTE 2 +#define CY_SPI_SYNC_ACK1 0x62 /* from protocol v.2 */ +#define CY_SPI_SYNC_ACK2 0x9D /* from protocol v.2 */ +#define CY_SPI_DATA_SIZE 128 +#define CY_SPI_DATA_BUF_SIZE (CY_SPI_CMD_BYTES + CY_SPI_DATA_SIZE) +#define CY_SPI_BITS_PER_WORD 8 + +static int cyttsp_spi_xfer(struct cyttsp *ts, + u8 op, u8 reg, u8 *buf, int length) +{ + struct spi_device *spi = to_spi_device(ts->dev); + struct spi_message msg; + struct spi_transfer xfer[2]; + u8 *wr_buf = &ts->xfer_buf[0]; + u8 *rd_buf = &ts->xfer_buf[CY_SPI_DATA_BUF_SIZE]; + int retval; + int i; + + if (length > CY_SPI_DATA_SIZE) { + dev_err(ts->dev, "%s: length %d is too big.\n", + __func__, length); + return -EINVAL; + } + + memset(wr_buf, 0, CY_SPI_DATA_BUF_SIZE); + memset(rd_buf, 0, CY_SPI_DATA_BUF_SIZE); + + wr_buf[0] = 0x00; /* header byte 0 */ + wr_buf[1] = 0xFF; /* header byte 1 */ + wr_buf[2] = reg; /* reg index */ + wr_buf[3] = op; /* r/~w */ + if (op == CY_SPI_WR_OP) + memcpy(wr_buf + CY_SPI_CMD_BYTES, buf, length); + + memset(xfer, 0, sizeof(xfer)); + spi_message_init(&msg); + + /* + We set both TX and RX buffers because Cypress TTSP + requires full duplex operation. + */ + xfer[0].tx_buf = wr_buf; + xfer[0].rx_buf = rd_buf; + switch (op) { + case CY_SPI_WR_OP: + xfer[0].len = length + CY_SPI_CMD_BYTES; + spi_message_add_tail(&xfer[0], &msg); + break; + + case CY_SPI_RD_OP: + xfer[0].len = CY_SPI_CMD_BYTES; + spi_message_add_tail(&xfer[0], &msg); + + xfer[1].rx_buf = buf; + xfer[1].len = length; + spi_message_add_tail(&xfer[1], &msg); + break; + + default: + dev_err(ts->dev, "%s: bad operation code=%d\n", __func__, op); + return -EINVAL; + } + + retval = spi_sync(spi, &msg); + if (retval < 0) { + dev_dbg(ts->dev, "%s: spi_sync() error %d, len=%d, op=%d\n", + __func__, retval, xfer[1].len, op); + + /* + * do not return here since was a bad ACK sequence + * let the following ACK check handle any errors and + * allow silent retries + */ + } + + if (rd_buf[CY_SPI_SYNC_BYTE] != CY_SPI_SYNC_ACK1 || + rd_buf[CY_SPI_SYNC_BYTE + 1] != CY_SPI_SYNC_ACK2) { + + dev_dbg(ts->dev, "%s: operation %d failed\n", __func__, op); + + for (i = 0; i < CY_SPI_CMD_BYTES; i++) + dev_dbg(ts->dev, "%s: test rd_buf[%d]:0x%02x\n", + __func__, i, rd_buf[i]); + for (i = 0; i < length; i++) + dev_dbg(ts->dev, "%s: test buf[%d]:0x%02x\n", + __func__, i, buf[i]); + + return -EIO; + } + + return 0; +} + +static int cyttsp_spi_read_block_data(struct cyttsp *ts, + u8 addr, u8 length, void *data) +{ + return cyttsp_spi_xfer(ts, CY_SPI_RD_OP, addr, data, length); +} + +static int cyttsp_spi_write_block_data(struct cyttsp *ts, + u8 addr, u8 length, const void *data) +{ + return cyttsp_spi_xfer(ts, CY_SPI_WR_OP, addr, (void *)data, length); +} + +static const struct cyttsp_bus_ops cyttsp_spi_bus_ops = { + .bustype = BUS_SPI, + .write = cyttsp_spi_write_block_data, + .read = cyttsp_spi_read_block_data, +}; + +static int __devinit cyttsp_spi_probe(struct spi_device *spi) +{ + struct cyttsp *ts; + int error; + + /* Set up SPI*/ + spi->bits_per_word = CY_SPI_BITS_PER_WORD; + spi->mode = SPI_MODE_0; + error = spi_setup(spi); + if (error < 0) { + dev_err(&spi->dev, "%s: SPI setup error %d\n", + __func__, error); + return error; + } + + ts = cyttsp_probe(&cyttsp_spi_bus_ops, &spi->dev, spi->irq, + CY_SPI_DATA_BUF_SIZE * 2); + if (IS_ERR(ts)) + return PTR_ERR(ts); + + spi_set_drvdata(spi, ts); + + return 0; +} + +static int __devexit cyttsp_spi_remove(struct spi_device *spi) +{ + struct cyttsp *ts = spi_get_drvdata(spi); + + cyttsp_remove(ts); + + return 0; +} + +static struct spi_driver cyttsp_spi_driver = { + .driver = { + .name = CY_SPI_NAME, + .owner = THIS_MODULE, + .pm = &cyttsp_pm_ops, + }, + .probe = cyttsp_spi_probe, + .remove = __devexit_p(cyttsp_spi_remove), +}; + +static int __init cyttsp_spi_init(void) +{ + return spi_register_driver(&cyttsp_spi_driver); +} +module_init(cyttsp_spi_init); + +static void __exit cyttsp_spi_exit(void) +{ + spi_unregister_driver(&cyttsp_spi_driver); +} +module_exit(cyttsp_spi_exit); + +MODULE_ALIAS("spi:cyttsp"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Cypress TrueTouch(R) Standard Product (TTSP) SPI driver"); +MODULE_AUTHOR("Cypress"); +MODULE_ALIAS("spi:cyttsp"); diff --git a/include/linux/input/cyttsp.h b/include/linux/input/cyttsp.h new file mode 100644 index 00000000000..5af7c66f1fc --- /dev/null +++ b/include/linux/input/cyttsp.h @@ -0,0 +1,58 @@ +/* + * Header file for: + * Cypress TrueTouch(TM) Standard Product (TTSP) touchscreen drivers. + * For use with Cypress Txx3xx parts. + * Supported parts include: + * CY8CTST341 + * CY8CTMA340 + * + * Copyright (C) 2009, 2010, 2011 Cypress Semiconductor, Inc. + * Copyright (C) 2012 Javier Martinez Canillas + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2, and only version 2, as published by the + * Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contact Cypress Semiconductor at www.cypress.com (kev@cypress.com) + * + */ +#ifndef _CYTTSP_H_ +#define _CYTTSP_H_ + +#define CY_SPI_NAME "cyttsp-spi" +#define CY_I2C_NAME "cyttsp-i2c" +/* Active Power state scanning/processing refresh interval */ +#define CY_ACT_INTRVL_DFLT 0x00 /* ms */ +/* touch timeout for the Active power */ +#define CY_TCH_TMOUT_DFLT 0xFF /* ms */ +/* Low Power state scanning/processing refresh interval */ +#define CY_LP_INTRVL_DFLT 0x0A /* ms */ +/* Active distance in pixels for a gesture to be reported */ +#define CY_ACT_DIST_DFLT 0xF8 /* pixels */ + +struct cyttsp_platform_data { + u32 maxx; + u32 maxy; + bool use_hndshk; + u8 act_dist; /* Active distance */ + u8 act_intrvl; /* Active refresh interval; ms */ + u8 tch_tmout; /* Active touch timeout; ms */ + u8 lp_intrvl; /* Low power refresh interval; ms */ + int (*init)(void); + void (*exit)(void); + char *name; + s16 irq_gpio; + u8 *bl_keys; +}; + +#endif /* _CYTTSP_H_ */ -- cgit v1.2.3-70-g09d2 From f35ef7cab2db0a8b577bef59122b59220efdac44 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Tue, 31 Jan 2012 20:06:07 +0900 Subject: ARM: S3C24XX: move spi-s3c24xx platdata out of mach spi.h now only contains the definition of the platform data structure for the driver in spi-s3c24xx.c . Therefore it does not need to stay in include/mach but can instead live in linux/spi/s3c24xx.h . Signed-off-by: Heiko Stuebner Cc: Grant Likely Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c2410/include/mach/spi.h | 27 --------------------------- arch/arm/mach-s3c2440/mach-gta02.c | 2 +- drivers/spi/spi-s3c24xx.c | 2 +- include/linux/spi/s3c24xx.h | 26 ++++++++++++++++++++++++++ 4 files changed, 28 insertions(+), 29 deletions(-) delete mode 100644 arch/arm/mach-s3c2410/include/mach/spi.h create mode 100644 include/linux/spi/s3c24xx.h (limited to 'drivers') diff --git a/arch/arm/mach-s3c2410/include/mach/spi.h b/arch/arm/mach-s3c2410/include/mach/spi.h deleted file mode 100644 index 2a686c0751c..00000000000 --- a/arch/arm/mach-s3c2410/include/mach/spi.h +++ /dev/null @@ -1,27 +0,0 @@ -/* arch/arm/mach-s3c2410/include/mach/spi.h - * - * Copyright (c) 2006 Simtec Electronics - * Ben Dooks - * - * S3C2410 - SPI Controller platform_device info - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - -#ifndef __ASM_ARCH_SPI_H -#define __ASM_ARCH_SPI_H __FILE__ - -struct s3c2410_spi_info { - int pin_cs; /* simple gpio cs */ - unsigned int num_cs; /* total chipselects */ - int bus_num; /* bus number to use. */ - - unsigned int use_fiq:1; /* use fiq */ - - void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); - void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); -}; - -#endif /* __ASM_ARCH_SPI_H */ diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c index 5859e609d28..cf270f51d14 100644 --- a/arch/arm/mach-s3c2440/mach-gta02.c +++ b/arch/arm/mach-s3c2440/mach-gta02.c @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -73,7 +74,6 @@ #include #include -#include #include #include #include diff --git a/drivers/spi/spi-s3c24xx.c b/drivers/spi/spi-s3c24xx.c index fc064535f4f..8ee7d790ce4 100644 --- a/drivers/spi/spi-s3c24xx.c +++ b/drivers/spi/spi-s3c24xx.c @@ -24,10 +24,10 @@ #include #include +#include #include #include -#include #include #include diff --git a/include/linux/spi/s3c24xx.h b/include/linux/spi/s3c24xx.h new file mode 100644 index 00000000000..c23b923e493 --- /dev/null +++ b/include/linux/spi/s3c24xx.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2006 Simtec Electronics + * Ben Dooks + * + * S3C2410 - SPI Controller platform_device info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#ifndef __LINUX_SPI_S3C24XX_H +#define __LINUX_SPI_S3C24XX_H __FILE__ + +struct s3c2410_spi_info { + int pin_cs; /* simple gpio cs */ + unsigned int num_cs; /* total chipselects */ + int bus_num; /* bus number to use. */ + + unsigned int use_fiq:1; /* use fiq */ + + void (*gpio_setup)(struct s3c2410_spi_info *spi, int enable); + void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); +}; + +#endif /* __LINUX_SPI_S3C24XX_H */ -- cgit v1.2.3-70-g09d2 From aa795d129246cb4c973076e3242b8a2eb374f1ef Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 31 Jan 2012 11:48:18 +0800 Subject: regmap: Remove incorrect unreachable comment in regcache_set_val() regcache_set_val() returns false if cache[idx] != val. Thus it actually is not unreachable. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/base/regmap/regcache.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 99beccfad4d..7e18d1e70f1 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -375,7 +375,6 @@ bool regcache_set_val(void *base, unsigned int idx, default: BUG(); } - /* unreachable */ return false; } -- cgit v1.2.3-70-g09d2 From e9e8c85e69310141d78daaecd6a56138700ac317 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 26 Jan 2012 12:40:23 +0200 Subject: usb: musb: make modules behave better There's really no point in doing all that initcall trickery when we can safely let udev handle module probing for us. Remove all of that trickery, by moving everybody to module_init() and making proper use of platform_device_register() rather than platform_device_probe(). Tested-by: Rajashekhara, Sudhakar Tested-by: Tasslehoff Kjappfot Signed-off-by: Felipe Balbi --- drivers/usb/musb/am35x.c | 11 ++++----- drivers/usb/musb/blackfin.c | 9 ++++---- drivers/usb/musb/da8xx.c | 11 ++++----- drivers/usb/musb/davinci.c | 11 ++++----- drivers/usb/musb/musb_core.c | 49 +++++++++++++++++++---------------------- drivers/usb/musb/musb_debugfs.c | 2 +- drivers/usb/musb/musb_gadget.c | 6 ++--- drivers/usb/musb/omap2430.c | 11 ++++----- drivers/usb/musb/tusb6010.c | 11 ++++----- drivers/usb/musb/ux500.c | 11 ++++----- 10 files changed, 68 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index e233d2b7d33..5285bda1dc4 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -456,7 +456,7 @@ static const struct musb_platform_ops am35x_ops = { static u64 am35x_dmamask = DMA_BIT_MASK(32); -static int __init am35x_probe(struct platform_device *pdev) +static int __devinit am35x_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -561,7 +561,7 @@ err0: return ret; } -static int __exit am35x_remove(struct platform_device *pdev) +static int __devexit am35x_remove(struct platform_device *pdev) { struct am35x_glue *glue = platform_get_drvdata(pdev); @@ -630,7 +630,8 @@ static struct dev_pm_ops am35x_pm_ops = { #endif static struct platform_driver am35x_driver = { - .remove = __exit_p(am35x_remove), + .probe = am35x_probe, + .remove = __devexit_p(am35x_remove), .driver = { .name = "musb-am35x", .pm = DEV_PM_OPS, @@ -643,9 +644,9 @@ MODULE_LICENSE("GPL v2"); static int __init am35x_init(void) { - return platform_driver_probe(&am35x_driver, am35x_probe); + return platform_driver_register(&am35x_driver); } -subsys_initcall(am35x_init); +module_init(am35x_init); static void __exit am35x_exit(void) { diff --git a/drivers/usb/musb/blackfin.c b/drivers/usb/musb/blackfin.c index 5e7cfba5b07..261af3487b5 100644 --- a/drivers/usb/musb/blackfin.c +++ b/drivers/usb/musb/blackfin.c @@ -463,7 +463,7 @@ static const struct musb_platform_ops bfin_ops = { static u64 bfin_dmamask = DMA_BIT_MASK(32); -static int __init bfin_probe(struct platform_device *pdev) +static int __devinit bfin_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -525,7 +525,7 @@ err0: return ret; } -static int __exit bfin_remove(struct platform_device *pdev) +static int __devexit bfin_remove(struct platform_device *pdev) { struct bfin_glue *glue = platform_get_drvdata(pdev); @@ -575,6 +575,7 @@ static struct dev_pm_ops bfin_pm_ops = { #endif static struct platform_driver bfin_driver = { + .probe = bfin_probe, .remove = __exit_p(bfin_remove), .driver = { .name = "musb-blackfin", @@ -588,9 +589,9 @@ MODULE_LICENSE("GPL v2"); static int __init bfin_init(void) { - return platform_driver_probe(&bfin_driver, bfin_probe); + return platform_driver_register(&bfin_driver); } -subsys_initcall(bfin_init); +module_init(bfin_init); static void __exit bfin_exit(void) { diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 2613bfdb09b..01c8f2ece08 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -478,7 +478,7 @@ static const struct musb_platform_ops da8xx_ops = { static u64 da8xx_dmamask = DMA_BIT_MASK(32); -static int __init da8xx_probe(struct platform_device *pdev) +static int __devinit da8xx_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -562,7 +562,7 @@ err0: return ret; } -static int __exit da8xx_remove(struct platform_device *pdev) +static int __devexit da8xx_remove(struct platform_device *pdev) { struct da8xx_glue *glue = platform_get_drvdata(pdev); @@ -576,7 +576,8 @@ static int __exit da8xx_remove(struct platform_device *pdev) } static struct platform_driver da8xx_driver = { - .remove = __exit_p(da8xx_remove), + .probe = da8xx_probe, + .remove = __devexit_p(da8xx_remove), .driver = { .name = "musb-da8xx", }, @@ -588,9 +589,9 @@ MODULE_LICENSE("GPL v2"); static int __init da8xx_init(void) { - return platform_driver_probe(&da8xx_driver, da8xx_probe); + return platform_driver_register(&da8xx_driver); } -subsys_initcall(da8xx_init); +module_init(da8xx_init); static void __exit da8xx_exit(void) { diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index f9a3f62a83b..7802c7ec43f 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c @@ -514,7 +514,7 @@ static const struct musb_platform_ops davinci_ops = { static u64 davinci_dmamask = DMA_BIT_MASK(32); -static int __init davinci_probe(struct platform_device *pdev) +static int __devinit davinci_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -597,7 +597,7 @@ err0: return ret; } -static int __exit davinci_remove(struct platform_device *pdev) +static int __devexit davinci_remove(struct platform_device *pdev) { struct davinci_glue *glue = platform_get_drvdata(pdev); @@ -611,7 +611,8 @@ static int __exit davinci_remove(struct platform_device *pdev) } static struct platform_driver davinci_driver = { - .remove = __exit_p(davinci_remove), + .probe = davinci_probe, + .remove = __devexit_p(davinci_remove), .driver = { .name = "musb-davinci", }, @@ -623,9 +624,9 @@ MODULE_LICENSE("GPL v2"); static int __init davinci_init(void) { - return platform_driver_probe(&davinci_driver, davinci_probe); + return platform_driver_register(&davinci_driver); } -subsys_initcall(davinci_init); +module_init(davinci_init); static void __exit davinci_exit(void) { diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 6a929859b55..d6134b39e8f 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1014,12 +1014,12 @@ static void musb_shutdown(struct platform_device *pdev) || defined(CONFIG_USB_MUSB_OMAP2PLUS_MODULE) \ || defined(CONFIG_USB_MUSB_AM35X) \ || defined(CONFIG_USB_MUSB_AM35X_MODULE) -static ushort __initdata fifo_mode = 4; +static ushort __devinitdata fifo_mode = 4; #elif defined(CONFIG_USB_MUSB_UX500) \ || defined(CONFIG_USB_MUSB_UX500_MODULE) -static ushort __initdata fifo_mode = 5; +static ushort __devinitdata fifo_mode = 5; #else -static ushort __initdata fifo_mode = 2; +static ushort __devinitdata fifo_mode = 2; #endif /* "modprobe ... fifo_mode=1" etc */ @@ -1032,7 +1032,7 @@ MODULE_PARM_DESC(fifo_mode, "initial endpoint configuration"); */ /* mode 0 - fits in 2KB */ -static struct musb_fifo_cfg __initdata mode_0_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_0_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, }, @@ -1041,7 +1041,7 @@ static struct musb_fifo_cfg __initdata mode_0_cfg[] = { }; /* mode 1 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_1_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_1_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_RXTX, .maxpacket = 512, .mode = BUF_DOUBLE, }, @@ -1050,7 +1050,7 @@ static struct musb_fifo_cfg __initdata mode_1_cfg[] = { }; /* mode 2 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_2_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_2_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1060,7 +1060,7 @@ static struct musb_fifo_cfg __initdata mode_2_cfg[] = { }; /* mode 3 - fits in 4KB */ -static struct musb_fifo_cfg __initdata mode_3_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_3_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, .mode = BUF_DOUBLE, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1070,7 +1070,7 @@ static struct musb_fifo_cfg __initdata mode_3_cfg[] = { }; /* mode 4 - fits in 16KB */ -static struct musb_fifo_cfg __initdata mode_4_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_4_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1101,7 +1101,7 @@ static struct musb_fifo_cfg __initdata mode_4_cfg[] = { }; /* mode 5 - fits in 8KB */ -static struct musb_fifo_cfg __initdata mode_5_cfg[] = { +static struct musb_fifo_cfg __devinitdata mode_5_cfg[] = { { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, @@ -1137,7 +1137,7 @@ static struct musb_fifo_cfg __initdata mode_5_cfg[] = { * * returns negative errno or offset for next fifo. */ -static int __init +static int __devinit fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, const struct musb_fifo_cfg *cfg, u16 offset) { @@ -1208,11 +1208,11 @@ fifo_setup(struct musb *musb, struct musb_hw_ep *hw_ep, return offset + (maxpacket << ((c_size & MUSB_FIFOSZ_DPB) ? 1 : 0)); } -static struct musb_fifo_cfg __initdata ep0_cfg = { +static struct musb_fifo_cfg __devinitdata ep0_cfg = { .style = FIFO_RXTX, .maxpacket = 64, }; -static int __init ep_config_from_table(struct musb *musb) +static int __devinit ep_config_from_table(struct musb *musb) { const struct musb_fifo_cfg *cfg; unsigned i, n; @@ -1303,7 +1303,7 @@ done: * ep_config_from_hw - when MUSB_C_DYNFIFO_DEF is false * @param musb the controller */ -static int __init ep_config_from_hw(struct musb *musb) +static int __devinit ep_config_from_hw(struct musb *musb) { u8 epnum = 0; struct musb_hw_ep *hw_ep; @@ -1350,7 +1350,7 @@ enum { MUSB_CONTROLLER_MHDRC, MUSB_CONTROLLER_HDRC, }; /* Initialize MUSB (M)HDRC part of the USB hardware subsystem; * configure endpoints, or take their config from silicon */ -static int __init musb_core_init(u16 musb_type, struct musb *musb) +static int __devinit musb_core_init(u16 musb_type, struct musb *musb) { u8 reg; char *type; @@ -1586,7 +1586,7 @@ irqreturn_t musb_interrupt(struct musb *musb) EXPORT_SYMBOL_GPL(musb_interrupt); #ifndef CONFIG_MUSB_PIO_ONLY -static bool __initdata use_dma = 1; +static bool __devinitdata use_dma = 1; /* "modprobe ... use_dma=0" etc */ module_param(use_dma, bool, 0); @@ -1774,7 +1774,7 @@ static void musb_irq_work(struct work_struct *data) * Init support */ -static struct musb *__init +static struct musb *__devinit allocate_instance(struct device *dev, struct musb_hdrc_config *config, void __iomem *mbase) { @@ -1852,7 +1852,7 @@ static void musb_free(struct musb *musb) * @mregs: virtual address of controller registers, * not yet corrected for platform-specific offsets */ -static int __init +static int __devinit musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) { int status; @@ -2072,7 +2072,7 @@ fail0: static u64 *orig_dma_mask; #endif -static int __init musb_probe(struct platform_device *pdev) +static int __devinit musb_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; int irq = platform_get_irq_byname(pdev, "mc"); @@ -2101,7 +2101,7 @@ static int __init musb_probe(struct platform_device *pdev) return status; } -static int __exit musb_remove(struct platform_device *pdev) +static int __devexit musb_remove(struct platform_device *pdev) { struct musb *musb = dev_to_musb(&pdev->dev); void __iomem *ctrl_base = musb->ctrl_base; @@ -2361,7 +2361,8 @@ static struct platform_driver musb_driver = { .owner = THIS_MODULE, .pm = MUSB_DEV_PM_OPS, }, - .remove = __exit_p(musb_remove), + .probe = musb_probe, + .remove = __devexit_p(musb_remove), .shutdown = musb_shutdown, }; @@ -2377,13 +2378,9 @@ static int __init musb_init(void) ", " "otg (peripheral+host)", musb_driver_name); - return platform_driver_probe(&musb_driver, musb_probe); + return platform_driver_register(&musb_driver); } - -/* make us init after usbcore and i2c (transceivers, regulators, etc) - * and before usb gadget and host-side drivers start to register - */ -fs_initcall(musb_init); +module_init(musb_init); static void __exit musb_cleanup(void) { diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 13d9af9bf92..219d0fba584 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -235,7 +235,7 @@ static const struct file_operations musb_test_mode_fops = { .release = single_release, }; -int __init musb_init_debugfs(struct musb *musb) +int __devinit musb_init_debugfs(struct musb *musb) { struct dentry *root; struct dentry *file; diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index ac3d2eec20f..59ab98f08e9 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1762,7 +1762,7 @@ static void musb_gadget_release(struct device *dev) } -static void __init +static void __devinit init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) { struct musb_hw_ep *hw_ep = musb->endpoints + epnum; @@ -1799,7 +1799,7 @@ init_peripheral_ep(struct musb *musb, struct musb_ep *ep, u8 epnum, int is_in) * Initialize the endpoints exposed to peripheral drivers, with backlinks * to the rest of the driver state. */ -static inline void __init musb_g_init_endpoints(struct musb *musb) +static inline void __devinit musb_g_init_endpoints(struct musb *musb) { u8 epnum; struct musb_hw_ep *hw_ep; @@ -1832,7 +1832,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb) /* called once during driver setup to initialize and link into * the driver model; memory is zeroed. */ -int __init musb_gadget_setup(struct musb *musb) +int __devinit musb_gadget_setup(struct musb *musb) { int status; diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index c27bbbf32b5..b254173e7e8 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -408,7 +408,7 @@ static const struct musb_platform_ops omap2430_ops = { static u64 omap2430_dmamask = DMA_BIT_MASK(32); -static int __init omap2430_probe(struct platform_device *pdev) +static int __devinit omap2430_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -471,7 +471,7 @@ err0: return ret; } -static int __exit omap2430_remove(struct platform_device *pdev) +static int __devexit omap2430_remove(struct platform_device *pdev) { struct omap2430_glue *glue = platform_get_drvdata(pdev); @@ -524,7 +524,8 @@ static struct dev_pm_ops omap2430_pm_ops = { #endif static struct platform_driver omap2430_driver = { - .remove = __exit_p(omap2430_remove), + .probe = omap2430_probe, + .remove = __devexit_p(omap2430_remove), .driver = { .name = "musb-omap2430", .pm = DEV_PM_OPS, @@ -537,9 +538,9 @@ MODULE_LICENSE("GPL v2"); static int __init omap2430_init(void) { - return platform_driver_probe(&omap2430_driver, omap2430_probe); + return platform_driver_register(&omap2430_driver); } -subsys_initcall(omap2430_init); +module_init(omap2430_init); static void __exit omap2430_exit(void) { diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c index 1f405616e6c..b387f12d05b 100644 --- a/drivers/usb/musb/tusb6010.c +++ b/drivers/usb/musb/tusb6010.c @@ -1165,7 +1165,7 @@ static const struct musb_platform_ops tusb_ops = { static u64 tusb_dmamask = DMA_BIT_MASK(32); -static int __init tusb_probe(struct platform_device *pdev) +static int __devinit tusb_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -1227,7 +1227,7 @@ err0: return ret; } -static int __exit tusb_remove(struct platform_device *pdev) +static int __devexit tusb_remove(struct platform_device *pdev) { struct tusb6010_glue *glue = platform_get_drvdata(pdev); @@ -1239,7 +1239,8 @@ static int __exit tusb_remove(struct platform_device *pdev) } static struct platform_driver tusb_driver = { - .remove = __exit_p(tusb_remove), + .probe = tusb_probe, + .remove = __devexit_p(tusb_remove), .driver = { .name = "musb-tusb", }, @@ -1251,9 +1252,9 @@ MODULE_LICENSE("GPL v2"); static int __init tusb_init(void) { - return platform_driver_probe(&tusb_driver, tusb_probe); + return platform_driver_register(&tusb_driver); } -subsys_initcall(tusb_init); +module_init(tusb_init); static void __exit tusb_exit(void) { diff --git a/drivers/usb/musb/ux500.c b/drivers/usb/musb/ux500.c index f7e04bf34a1..bcfc48f4854 100644 --- a/drivers/usb/musb/ux500.c +++ b/drivers/usb/musb/ux500.c @@ -58,7 +58,7 @@ static const struct musb_platform_ops ux500_ops = { .exit = ux500_musb_exit, }; -static int __init ux500_probe(struct platform_device *pdev) +static int __devinit ux500_probe(struct platform_device *pdev) { struct musb_hdrc_platform_data *pdata = pdev->dev.platform_data; struct platform_device *musb; @@ -141,7 +141,7 @@ err0: return ret; } -static int __exit ux500_remove(struct platform_device *pdev) +static int __devexit ux500_remove(struct platform_device *pdev) { struct ux500_glue *glue = platform_get_drvdata(pdev); @@ -194,7 +194,8 @@ static const struct dev_pm_ops ux500_pm_ops = { #endif static struct platform_driver ux500_driver = { - .remove = __exit_p(ux500_remove), + .probe = ux500_probe, + .remove = __devexit_p(ux500_remove), .driver = { .name = "musb-ux500", .pm = DEV_PM_OPS, @@ -207,9 +208,9 @@ MODULE_LICENSE("GPL v2"); static int __init ux500_init(void) { - return platform_driver_probe(&ux500_driver, ux500_probe); + return platform_driver_register(&ux500_driver); } -subsys_initcall(ux500_init); +module_init(ux500_init); static void __exit ux500_exit(void) { -- cgit v1.2.3-70-g09d2 From ae1f23fb433ac0aaff8aeaa5a7b14348e9aa8277 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 00:00:19 +0100 Subject: r8169: fix early queue wake-up. With infinite gratitude to Eric Dumazet for allowing me to identify the error. Signed-off-by: Francois Romieu Acked-by: Eric Dumazet Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d039d39963a..859554a03a0 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5559,7 +5559,18 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb, mmiowb(); if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) { + /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must + * not miss a ring update when it notices a stopped queue. + */ + smp_wmb(); netif_stop_queue(dev); + /* Sync with rtl_tx: + * - publish queue status and cur_tx ring index (write barrier) + * - refresh dirty_tx ring index (read barrier). + * May the current thread have a pessimistic view of the ring + * status and forget to wake up queue, a racing rtl_tx thread + * can't. + */ smp_mb(); if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS) netif_wake_queue(dev); @@ -5659,6 +5670,13 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) if (tp->dirty_tx != dirty_tx) { tp->dirty_tx = dirty_tx; + /* Sync with rtl8169_start_xmit: + * - publish dirty_tx ring index (write barrier) + * - refresh cur_tx ring index and queue status (read barrier) + * May the current thread miss the stopped queue condition, + * a racing xmit thread can only have a right view of the + * ring status. + */ smp_mb(); if (netif_queue_stopped(dev) && (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) { -- cgit v1.2.3-70-g09d2 From 98ddf986fca17840e46e070354b7e2cd2169da15 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 10:47:34 +0100 Subject: r8169: bh locking redux and task scheduling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - atomic bit operations are globally visible - pending status is always cleared before execution - scheduled works are either idempotent or only required to happen once after a series of originating events, say link events for instance Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 859554a03a0..118f6f6fcef 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3273,17 +3273,8 @@ out_mod_timer: static void rtl_schedule_task(struct rtl8169_private *tp, enum rtl_flag flag) { - spin_lock(&tp->lock); if (!test_and_set_bit(flag, tp->wk.flags)) schedule_work(&tp->wk.work); - spin_unlock(&tp->lock); -} - -static void rtl_schedule_task_bh(struct rtl8169_private *tp, enum rtl_flag flag) -{ - local_bh_disable(); - rtl_schedule_task(tp, flag); - local_bh_enable(); } static void rtl8169_phy_timer(unsigned long __opaque) @@ -3291,7 +3282,7 @@ static void rtl8169_phy_timer(unsigned long __opaque) struct net_device *dev = (struct net_device *)__opaque; struct rtl8169_private *tp = netdev_priv(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_PHY_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_PHY_PENDING); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -5635,7 +5626,7 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev) rtl8169_hw_reset(tp); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp) @@ -5852,7 +5843,7 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: netif_stop_queue(dev); - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); default: break; } @@ -5894,10 +5885,7 @@ static void rtl_task(struct work_struct *work) for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { bool pending; - spin_lock_bh(&tp->lock); pending = test_and_clear_bit(rtl_work[i].bitnr, tp->wk.flags); - spin_unlock_bh(&tp->lock); - if (pending) rtl_work[i].action(tp); } @@ -6116,7 +6104,7 @@ static void __rtl8169_resume(struct net_device *dev) tp->wk.enabled = true; - rtl_schedule_task_bh(tp, RTL_FLAG_TASK_RESET_PENDING); + rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } static int rtl8169_resume(struct device *device) -- cgit v1.2.3-70-g09d2 From 6c4a70c5f286077e78b294b3f3a93dc45c40db89 Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 10:56:44 +0100 Subject: r8169: move task enable boolean to bitfield. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Simpler, more consistent, with negligible cost in non-critical paths. Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 118f6f6fcef..679711e4c3c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -668,6 +668,7 @@ struct rtl8169_counters { }; enum rtl_flag { + RTL_FLAG_TASK_ENABLED, RTL_FLAG_TASK_SLOW_PENDING, RTL_FLAG_TASK_RESET_PENDING, RTL_FLAG_TASK_PHY_PENDING, @@ -725,7 +726,6 @@ struct rtl8169_private { DECLARE_BITMAP(flags, RTL_FLAG_MAX); struct mutex mutex; struct work_struct work; - bool enabled; } wk; unsigned features; @@ -4352,7 +4352,7 @@ static int rtl8169_open(struct net_device *dev) rtl_lock_work(tp); - tp->wk.enabled = true; + set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); napi_enable(&tp->napi); @@ -5879,7 +5879,8 @@ static void rtl_task(struct work_struct *work) rtl_lock_work(tp); - if (!netif_running(dev) || !tp->wk.enabled) + if (!netif_running(dev) || + !test_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags)) goto out_unlock; for (i = 0; i < ARRAY_SIZE(rtl_work); i++) { @@ -5977,7 +5978,7 @@ static int rtl8169_close(struct net_device *dev) rtl8169_update_counters(dev); rtl_lock_work(tp); - tp->wk.enabled = false; + clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl8169_down(dev); rtl_unlock_work(tp); @@ -6076,7 +6077,7 @@ static void rtl8169_net_suspend(struct net_device *dev) rtl_lock_work(tp); napi_disable(&tp->napi); - tp->wk.enabled = false; + clear_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_unlock_work(tp); rtl_pll_power_down(tp); @@ -6102,7 +6103,7 @@ static void __rtl8169_resume(struct net_device *dev) rtl_pll_power_up(tp); - tp->wk.enabled = true; + set_bit(RTL_FLAG_TASK_ENABLED, tp->wk.flags); rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); } -- cgit v1.2.3-70-g09d2 From 934714d088f35b81edafdce89397969baf77fb8a Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 11:09:21 +0100 Subject: r8169: avoid a useless work scheduling. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Francois Romieu Suggested-by: Michał Mirosław Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 679711e4c3c..0377ffaa8be 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5843,7 +5843,8 @@ static void rtl_slow_event_work(struct rtl8169_private *tp) /* Work around for rx fifo overflow */ case RTL_GIGA_MAC_VER_11: netif_stop_queue(dev); - rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING); + /* XXX - Hack alert. See rtl_task(). */ + set_bit(RTL_FLAG_TASK_RESET_PENDING, tp->wk.flags); default: break; } @@ -5868,6 +5869,7 @@ static void rtl_task(struct work_struct *work) int bitnr; void (*action)(struct rtl8169_private *); } rtl_work[] = { + /* XXX - keep rtl_slow_event_work() as first element. */ { RTL_FLAG_TASK_SLOW_PENDING, rtl_slow_event_work }, { RTL_FLAG_TASK_RESET_PENDING, rtl_reset_work }, { RTL_FLAG_TASK_PHY_PENDING, rtl_phy_work } -- cgit v1.2.3-70-g09d2 From 6c05d25267ebb371c4311de6904f740342e82f7c Mon Sep 17 00:00:00 2001 From: Francois Romieu Date: Tue, 31 Jan 2012 11:20:34 +0100 Subject: r8169: spinlock redux. rtl8169_get_regs operates under RTNL and rtl task mutex whereas rtl_set_rx_mode is either called under RTNL or rtl task mutex protection. Signed-off-by: Francois Romieu Cc: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0377ffaa8be..707742207c7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -680,7 +680,6 @@ struct rtl8169_private { struct pci_dev *pci_dev; struct net_device *dev; struct napi_struct napi; - spinlock_t lock; u32 msg_enable; u16 txd_version; u16 mac_version; @@ -1723,9 +1722,7 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, regs->len = R8169_REGS_SIZE; rtl_lock_work(tp); - spin_lock_bh(&tp->lock); memcpy_fromio(p, tp->mmio_addr, regs->len); - spin_unlock_bh(&tp->lock); rtl_unlock_work(tp); } @@ -4151,7 +4148,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) tp->do_ioctl = rtl_xmii_ioctl; } - spin_lock_init(&tp->lock); mutex_init(&tp->wk.mutex); /* Get MAC address */ @@ -6031,8 +6027,6 @@ static void rtl_set_rx_mode(struct net_device *dev) } } - spin_lock_bh(&tp->lock); - tmp = (RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK) | rx_mode; if (tp->mac_version > RTL_GIGA_MAC_VER_06) { @@ -6046,8 +6040,6 @@ static void rtl_set_rx_mode(struct net_device *dev) RTL_W32(MAR0 + 0, mc_filter[0]); RTL_W32(RxConfig, tmp); - - spin_unlock_bh(&tp->lock); } /** -- cgit v1.2.3-70-g09d2 From 5f356a67ae14033d734f73b79b926f8949300e83 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 31 Jan 2012 16:56:48 +0000 Subject: staging: sep: Fix warnings caused by sizeof() types Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_main.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/sep/sep_main.c b/drivers/staging/sep/sep_main.c index 0defb0ad4c8..7f8362cab7a 100644 --- a/drivers/staging/sep/sep_main.c +++ b/drivers/staging/sep/sep_main.c @@ -214,7 +214,7 @@ static int sep_allocate_dmatables_region(struct sep_device *sep, return -EINVAL; } - dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08X\n", + dev_dbg(&sep->pdev->dev, "[PID%d] newlen = 0x%08zX\n", current->pid, new_len); dev_dbg(&sep->pdev->dev, "[PID%d] oldlen = 0x%08X\n", current->pid, dma_ctx->dmatables_len); @@ -3344,7 +3344,7 @@ static ssize_t sep_activate_msgarea_context(struct sep_device *sep, if (!msg_region || !(*msg_region) || SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES < msg_len) { dev_warn(&sep->pdev->dev, - "[PID%d] invalid act msgarea len 0x%08X\n", + "[PID%d] invalid act msgarea len 0x%08zX\n", current->pid, msg_len); return -EINVAL; } @@ -3376,7 +3376,7 @@ static ssize_t sep_create_msgarea_context(struct sep_device *sep, SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES < msg_len || SEP_DRIVER_MIN_MESSAGE_SIZE_IN_BYTES > msg_len) { dev_warn(&sep->pdev->dev, - "[PID%d] invalid creat msgarea len 0x%08X\n", + "[PID%d] invalid creat msgarea len 0x%08zX\n", current->pid, msg_len); error = -EINVAL; goto end_function; @@ -3463,7 +3463,7 @@ static ssize_t sep_read(struct file *filp, sep_dump_message(sep); - dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08X\n", + dev_dbg(&sep->pdev->dev, "[PID%d] count_user = 0x%08zX\n", current->pid, count_user); /* In case user has allocated bigger buffer */ @@ -3522,7 +3522,7 @@ static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, if (count_user < sizeof(struct sep_fastcall_hdr)) { dev_warn(&sep->pdev->dev, - "[PID%d] too small message size 0x%08X\n", + "[PID%d] too small message size 0x%08zX\n", current->pid, count_user); error = -EINVAL; goto end_function; @@ -3563,7 +3563,7 @@ static inline ssize_t sep_fastcall_args_get(struct sep_device *sep, if (actual_count != count_user) { dev_warn(&sep->pdev->dev, "[PID%d] inconsistent message " - "sizes 0x%08X vs 0x%08X\n", + "sizes 0x%08zX vs 0x%08zX\n", current->pid, actual_count, count_user); error = -EMSGSIZE; goto end_function; -- cgit v1.2.3-70-g09d2 From d1b5342c1f5946c2219e4e5bd770b1c1fc186272 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:32 +0100 Subject: staging: nvec: ps2: add suspend/resume functions This adds suspend and resume functions to the nvec_ps2 mouse driver. During suspend the nvec sends a "Cancel all mouse events" command. If this is missed, there will be still some bytes in the received buffer after resume which make the mouse go out of sync. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 742f5ccfe76..4410dfb3e33 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -111,8 +111,27 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) return 0; } +static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + + /* send cancel autoreceive */ + nvec_write_async(nvec, "\x06\x04", 2); + + return 0; +} + +static int nvec_mouse_resume(struct platform_device *pdev) +{ + ps2_startstreaming(ps2_dev.ser_dev); + + return 0; +} + static struct platform_driver nvec_mouse_driver = { .probe = nvec_mouse_probe, + .suspend = nvec_mouse_suspend, + .resume = nvec_mouse_resume, .driver = { .name = "nvec-mouse", .owner = THIS_MODULE, -- cgit v1.2.3-70-g09d2 From 34ba143b9d1daf2eb7ea06b05c24b71faff82512 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:33 +0100 Subject: staging: nvec: ps2: let the start/stop streaming commands be called by the start/stop functions of serio Instead of executing these commands during open/close, the start/stop event of the serio device seem to be more appropiete. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 4410dfb3e33..f15283468c5 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -92,8 +92,8 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) ser_dev->id.type = SERIO_8042; ser_dev->write = ps2_sendcommand; - ser_dev->open = ps2_startstreaming; - ser_dev->close = ps2_stopstreaming; + ser_dev->start = ps2_startstreaming; + ser_dev->stop = ps2_stopstreaming; strlcpy(ser_dev->name, "nvec mouse", sizeof(ser_dev->name)); strlcpy(ser_dev->phys, "nvec", sizeof(ser_dev->phys)); -- cgit v1.2.3-70-g09d2 From 4b625c3abe91fca5b5a7f05681c10105af957e4f Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:34 +0100 Subject: staging: nvec: ps2: tell nvec to send 6 byte long messages This packet size used on most modern touchpads. Ideally, this should be configurable or autodetected. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index f15283468c5..8bfaccd04ac 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -21,7 +21,7 @@ #include "nvec.h" -#define START_STREAMING {'\x06', '\x03', '\x04'} +#define START_STREAMING {'\x06', '\x03', '\x06'} #define STOP_STREAMING {'\x06', '\x04'} #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} -- cgit v1.2.3-70-g09d2 From 0eedab704ed93d03b1ac392fd329f7ed20ab2279 Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:35 +0100 Subject: staging: nvec: ps2: add some more debug functions This can print the mouse traffic which goes over the i2c bus. Make mouse debugging messages configurable and disable them by default. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 8bfaccd04ac..7f470ba1160 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -25,6 +25,14 @@ #define STOP_STREAMING {'\x06', '\x04'} #define SEND_COMMAND {'\x06', '\x01', '\xf4', '\x01'} +#ifdef NVEC_PS2_DEBUG +#define NVEC_PHD(str, buf, len) \ + print_hex_dump(KERN_DEBUG, str, DUMP_PREFIX_NONE, \ + 16, 1, buf, len, false) +#else +#define NVEC_PHD(str, buf, len) +#endif + static const unsigned char MOUSE_RESET[] = {'\x06', '\x01', '\xff', '\x03'}; struct nvec_ps2 { @@ -67,18 +75,18 @@ static int nvec_ps2_notifier(struct notifier_block *nb, case NVEC_PS2_EVT: for (i = 0; i < msg[1]; i++) serio_interrupt(ps2_dev.ser_dev, msg[2 + i], 0); + NVEC_PHD("ps/2 mouse event: ", &msg[2], msg[1]); return NOTIFY_STOP; case NVEC_PS2: - if (msg[2] == 1) + if (msg[2] == 1) { for (i = 0; i < (msg[1] - 2); i++) serio_interrupt(ps2_dev.ser_dev, msg[i + 4], 0); - else if (msg[1] != 2) { /* !ack */ - print_hex_dump(KERN_WARNING, "unhandled mouse event: ", - DUMP_PREFIX_NONE, 16, 1, - msg, msg[1] + 2, true); + NVEC_PHD("ps/2 mouse reply: ", &msg[4], msg[1] - 2); } + else if (msg[1] != 2) /* !ack */ + NVEC_PHD("unhandled mouse event: ", msg, msg[1] + 2); return NOTIFY_STOP; } -- cgit v1.2.3-70-g09d2 From a573298b81ffd05856ddaa222826471eabf3953b Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:36 +0100 Subject: staging: nvec: ps2: disable/enable mouse on suspend/resume This change makes the touchpad buttons work after suspend/resume. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 7f470ba1160..4be3d220a63 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -123,6 +123,9 @@ static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + /* disable mouse */ + nvec_write_async(nvec, "\x06\xf4", 2); + /* send cancel autoreceive */ nvec_write_async(nvec, "\x06\x04", 2); @@ -131,8 +134,13 @@ static int nvec_mouse_suspend(struct platform_device *pdev, pm_message_t state) static int nvec_mouse_resume(struct platform_device *pdev) { + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); + ps2_startstreaming(ps2_dev.ser_dev); + /* enable mouse */ + nvec_write_async(nvec, "\x06\xf5", 2); + return 0; } -- cgit v1.2.3-70-g09d2 From 36b30d6138f4677514aca35ab76c20c1604baaad Mon Sep 17 00:00:00 2001 From: Marc Dietrich Date: Mon, 26 Dec 2011 17:57:37 +0100 Subject: staging: nvec: ps2: change serio type to passthrough This changes the serio type of the nvec_ps2 mouse port to passthrough. The old 8042 type seems appropiete for keyboards only. Signed-off-by: Marc Dietrich Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec_ps2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 4be3d220a63..14a6f687cf7 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -98,7 +98,7 @@ static int __devinit nvec_mouse_probe(struct platform_device *pdev) struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); - ser_dev->id.type = SERIO_8042; + ser_dev->id.type = SERIO_PS_PSTHRU; ser_dev->write = ps2_sendcommand; ser_dev->start = ps2_startstreaming; ser_dev->stop = ps2_stopstreaming; -- cgit v1.2.3-70-g09d2 From d3f862aec400dd831a4bdbea107fd85419bddab1 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:38 +0100 Subject: staging: nvec: Fix typo s/I2C_SL_NEWL/I2C_SL_NEWSL/ The constant I2C_SL_NEWL meant "new slave", but the S was missing. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index fafdfa25e13..b6108afb909 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -49,7 +49,7 @@ #define I2C_CNFG_DEBOUNCE_CNT_SHIFT 12 #define I2C_SL_CNFG 0x20 -#define I2C_SL_NEWL (1<<2) +#define I2C_SL_NEWSL (1<<2) #define I2C_SL_NACK (1<<1) #define I2C_SL_RESP (1<<0) #define I2C_SL_IRQ (1<<3) @@ -687,7 +687,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) clk_set_rate(nvec->i2c_clk, 8 * 80000); - writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG); + writel(I2C_SL_NEWSL, nvec->base + I2C_SL_CNFG); writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT); writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1); @@ -701,7 +701,7 @@ static void tegra_init_i2c_slave(struct nvec_chip *nvec) static void nvec_disable_i2c_slave(struct nvec_chip *nvec) { disable_irq(nvec->irq); - writel(I2C_SL_NEWL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); + writel(I2C_SL_NEWSL | I2C_SL_NACK, nvec->base + I2C_SL_CNFG); clk_disable(nvec->i2c_clk); } -- cgit v1.2.3-70-g09d2 From aed92bbcf4ce760c4d7848013a0db3bdd4ae9492 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:39 +0100 Subject: staging: nvec: Use gpio_request_one() instead of gpio_request() This saves us some calls and thus makes the code shorter and nicer. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/nvec.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index b6108afb909..3c60088871e 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -784,11 +784,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) nvec->i2c_clk = i2c_clk; nvec->rx = &nvec->msg_pool[0]; - /* Set the gpio to low when we've got something to say */ - err = gpio_request(nvec->gpio, "nvec gpio"); - if (err < 0) - dev_err(nvec->dev, "couldn't request gpio\n"); - ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list); init_completion(&nvec->sync_write); @@ -802,6 +797,12 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) INIT_WORK(&nvec->tx_work, nvec_request_master); nvec->wq = alloc_workqueue("nvec", WQ_NON_REENTRANT, 2); + err = gpio_request_one(nvec->gpio, GPIOF_OUT_INIT_HIGH, "nvec gpio"); + if (err < 0) { + dev_err(nvec->dev, "couldn't request gpio\n"); + goto failed; + } + err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec); if (err) { dev_err(nvec->dev, "couldn't request irq\n"); @@ -813,8 +814,6 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) clk_enable(i2c_clk); - gpio_direction_output(nvec->gpio, 1); - gpio_set_value(nvec->gpio, 1); /* enable event reporting */ nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, -- cgit v1.2.3-70-g09d2 From e96045a7c837200e65c9fa8f8a94020bc2107931 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 26 Dec 2011 17:57:40 +0100 Subject: staging: nvec: Fix Kconfig dependencies nvec modules do not require other stuff to be build in, nor does nvec_ps2 require mouse support, only generic serio support. Signed-off-by: Julian Andres Klode Signed-off-by: Greg Kroah-Hartman --- drivers/staging/nvec/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/nvec/Kconfig b/drivers/staging/nvec/Kconfig index 86a8b8c418c..731301f524a 100644 --- a/drivers/staging/nvec/Kconfig +++ b/drivers/staging/nvec/Kconfig @@ -7,21 +7,21 @@ config MFD_NVEC config KEYBOARD_NVEC bool "Keyboard on nVidia compliant EC" - depends on MFD_NVEC && INPUT=y + depends on MFD_NVEC && INPUT help Say Y here to enable support for a keyboard connected to a nVidia compliant embedded controller. config SERIO_NVEC_PS2 bool "PS2 on nVidia EC" - depends on MFD_NVEC && MOUSE_PS2 + depends on MFD_NVEC && SERIO help Say Y here to enable support for a Touchpad / Mouse connected to a nVidia compliant embedded controller. config NVEC_POWER bool "NVEC charger and battery" - depends on MFD_NVEC && POWER_SUPPLY=y + depends on MFD_NVEC && POWER_SUPPLY help Say Y to enable support for battery and charger interface for nVidia compliant embedded controllers. -- cgit v1.2.3-70-g09d2 From cca4d5adcff515b4bf5402dc23792f5123872906 Mon Sep 17 00:00:00 2001 From: Santosh Sajjan Date: Mon, 30 Jan 2012 22:02:26 +0200 Subject: ath6kl: Workaround to support Deep Sleep with MSM. Set the host pm flag MMC_PM_WAKE_SDIO_IRQ to allow host to disable the sdc2_clk and sdc2_h_clk,so that the MSM device enter into TCXO shutdown. Signed-off-by: Santosh Sajjan Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index 07dcf00ca1a..4febee72349 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -856,6 +856,19 @@ static int ath6kl_sdio_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow) if (ret) goto cut_pwr; + /* + * Workaround to support Deep Sleep with MSM, set the host pm + * flag as MMC_PM_WAKE_SDIO_IRQ to allow SDCC deiver to disable + * the sdc2_clock and internally allows MSM to enter + * TCXO shutdown properly. + */ + if ((flags & MMC_PM_WAKE_SDIO_IRQ)) { + ret = sdio_set_host_pm_flags(func, + MMC_PM_WAKE_SDIO_IRQ); + if (ret) + goto cut_pwr; + } + ret = ath6kl_cfg80211_suspend(ar, ATH6KL_CFG_SUSPEND_DEEPSLEEP, NULL); if (ret) -- cgit v1.2.3-70-g09d2 From 172975aa746e155533cb386c7159c2d6510e2bc8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 14 Dec 2011 13:57:25 +0100 Subject: drm/i915: Handle unmappable buffers during error state capture As the buffer is not necessarily accessible through the GTT at the time of a GPU hang, and capturing some of its contents is far more valuable than skipping it, provide a clflushed fallback read path. We still prefer to read through the GTT as that is more consistent with the GPU access of the same buffer. So example it will demonstrate any errorneous tiling or swizzling of the command buffer as seen by the GPU. This becomes necessary with use of CPU relocations and lazy GTT binding, but could potentially happen anyway as a result of a pathological error. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter Reviewed-by: Eugeni Dodonov Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 64bb2127911..8ea1ca4158a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -720,7 +720,6 @@ i915_error_object_create(struct drm_i915_private *dev_priv, reloc_offset = src->gtt_offset; for (page = 0; page < page_count; page++) { unsigned long flags; - void __iomem *s; void *d; d = kmalloc(PAGE_SIZE, GFP_ATOMIC); @@ -728,10 +727,29 @@ i915_error_object_create(struct drm_i915_private *dev_priv, goto unwind; local_irq_save(flags); - s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc_offset); - memcpy_fromio(d, s, PAGE_SIZE); - io_mapping_unmap_atomic(s); + if (reloc_offset < dev_priv->mm.gtt_mappable_end) { + void __iomem *s; + + /* Simply ignore tiling or any overlapping fence. + * It's part of the error state, and this hopefully + * captures what the GPU read. + */ + + s = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + reloc_offset); + memcpy_fromio(d, s, PAGE_SIZE); + io_mapping_unmap_atomic(s); + } else { + void *s; + + drm_clflush_pages(&src->pages[page], 1); + + s = kmap_atomic(src->pages[page]); + memcpy(d, s, PAGE_SIZE); + kunmap_atomic(s); + + drm_clflush_pages(&src->pages[page], 1); + } local_irq_restore(flags); dst->pages[page] = d; -- cgit v1.2.3-70-g09d2 From e404decb0fb017be80552adee894b35307b6c7b4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Jan 2012 12:56:23 +0000 Subject: drivers/net: Remove unnecessary k.alloc/v.alloc OOM messages alloc failures use dump_stack so emitting an additional out-of-memory message is an unnecessary duplication. Remove the allocation failure messages. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/bonding/bond_alb.c | 12 ++++-------- drivers/net/can/slcan.c | 4 +--- drivers/net/ethernet/amd/ni65.c | 4 +--- drivers/net/ethernet/apple/bmac.c | 4 +--- drivers/net/ethernet/apple/mace.c | 4 +--- drivers/net/ethernet/broadcom/bnx2.c | 4 +--- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +--- drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 21 +++------------------ drivers/net/ethernet/cisco/enic/enic_main.c | 1 - drivers/net/ethernet/cisco/enic/vnic_rq.c | 4 +--- drivers/net/ethernet/cisco/enic/vnic_wq.c | 4 +--- drivers/net/ethernet/i825xx/lp486e.c | 2 -- drivers/net/ethernet/ibm/emac/rgmii.c | 5 +---- drivers/net/ethernet/ibm/emac/tah.c | 5 +---- drivers/net/ethernet/ibm/emac/zmii.c | 5 +---- drivers/net/ethernet/intel/e1000/e1000_main.c | 4 +--- drivers/net/ethernet/intel/ixgb/ixgb_main.c | 4 +--- drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +----- drivers/net/ethernet/korina.c | 1 - drivers/net/ethernet/marvell/pxa168_eth.c | 10 ++++------ drivers/net/ethernet/mellanox/mlx4/en_rx.c | 5 ++--- drivers/net/ethernet/mellanox/mlx4/en_tx.c | 6 ++---- drivers/net/ethernet/micrel/ks8851_mll.c | 4 +--- .../net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 9 +++------ .../net/ethernet/qlogic/netxen/netxen_nic_init.c | 12 +++--------- drivers/net/ethernet/qlogic/qlge/qlge_dbg.c | 4 +--- drivers/net/ethernet/sis/sis900.c | 1 - drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 5 ++--- drivers/net/ethernet/sun/cassini.c | 1 - drivers/net/ethernet/sun/sunvnet.c | 9 +++------ drivers/net/ethernet/toshiba/ps3_gelic_wireless.c | 5 ++--- drivers/net/hamradio/yam.c | 1 - drivers/net/hippi/rrunner.c | 8 +------- drivers/net/irda/donauboe.c | 2 -- drivers/net/netconsole.c | 8 ++------ drivers/net/ppp/pptp.c | 4 +--- drivers/net/slip/slip.c | 4 +--- drivers/net/tokenring/3c359.c | 4 ---- drivers/net/tokenring/madgemc.c | 1 - drivers/net/vmxnet3/vmxnet3_drv.c | 15 +++------------ drivers/net/wan/c101.c | 4 +--- drivers/net/wan/dscc4.c | 8 ++------ drivers/net/wan/lmc/lmc_main.c | 1 - drivers/net/wan/n2.c | 4 +--- drivers/net/wan/pc300too.c | 1 - drivers/net/wan/pci200syn.c | 1 - drivers/net/wan/wanxl.c | 1 - drivers/net/wan/x25_asy.c | 4 +--- drivers/net/wireless/ath/ath9k/htc_hst.c | 5 +---- drivers/net/wireless/hostap/hostap_hw.c | 18 ++++++------------ drivers/net/wireless/ipw2x00/ipw2100.c | 5 +---- drivers/net/wireless/libertas/if_cs.c | 5 ++--- drivers/net/wireless/libertas/if_usb.c | 4 +--- drivers/net/wireless/libertas_tf/if_usb.c | 4 +--- drivers/net/wireless/mwifiex/pcie.c | 4 +--- drivers/net/wireless/mwifiex/sdio.c | 4 +--- drivers/net/wireless/orinoco/main.c | 6 ++---- drivers/net/wireless/prism54/islpci_mgt.c | 6 ++---- drivers/net/wireless/rtlwifi/rtl8192se/sw.c | 5 +---- drivers/net/xen-netback/netback.c | 4 +--- 60 files changed, 77 insertions(+), 233 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index f820b26b9db..9abfde47931 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c @@ -180,11 +180,9 @@ static int tlb_initialize(struct bonding *bond) int i; new_hashtbl = kzalloc(size, GFP_KERNEL); - if (!new_hashtbl) { - pr_err("%s: Error: Failed to allocate TLB hash table\n", - bond->dev->name); + if (!new_hashtbl) return -1; - } + _lock_tx_hashtbl_bh(bond); bond_info->tx_hashtbl = new_hashtbl; @@ -784,11 +782,9 @@ static int rlb_initialize(struct bonding *bond) int i; new_hashtbl = kmalloc(size, GFP_KERNEL); - if (!new_hashtbl) { - pr_err("%s: Error: Failed to allocate RLB hash table\n", - bond->dev->name); + if (!new_hashtbl) return -1; - } + _lock_rx_hashtbl_bh(bond); bond_info->rx_hashtbl = new_hashtbl; diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index 579e7fca644..98a5a7d867f 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c @@ -639,10 +639,8 @@ static int __init slcan_init(void) printk(KERN_INFO "slcan: %d dynamic interface channels.\n", maxdev); slcan_devs = kzalloc(sizeof(struct net_device *)*maxdev, GFP_KERNEL); - if (!slcan_devs) { - printk(KERN_ERR "slcan: can't allocate slcan device array!\n"); + if (!slcan_devs) return -ENOMEM; - } /* Fill in our line protocol discipline, and register it */ status = tty_register_ldisc(N_SLCAN, &slc_ldisc); diff --git a/drivers/net/ethernet/amd/ni65.c b/drivers/net/ethernet/amd/ni65.c index 6e6aa7213aa..735c213798b 100644 --- a/drivers/net/ethernet/amd/ni65.c +++ b/drivers/net/ethernet/amd/ni65.c @@ -621,10 +621,8 @@ static void *ni65_alloc_mem(struct net_device *dev,char *what,int size,int type) } else { ret = ptr = kmalloc(T_BUF_SIZE,GFP_KERNEL | GFP_DMA); - if(!ret) { - printk(KERN_WARNING "%s: unable to allocate %s memory.\n",dev->name,what); + if(!ret) return NULL; - } } if( (u32) virt_to_phys(ptr+size) > 0x1000000) { printk(KERN_WARNING "%s: unable to allocate %s memory in lower 16MB!\n",dev->name,what); diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index d070b229dbf..4108ac800cf 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1660,10 +1660,8 @@ static int __init bmac_init(void) { if (bmac_emergency_rxbuf == NULL) { bmac_emergency_rxbuf = kmalloc(RX_BUFLEN, GFP_KERNEL); - if (bmac_emergency_rxbuf == NULL) { - printk(KERN_ERR "BMAC: can't allocate emergency RX buffer\n"); + if (bmac_emergency_rxbuf == NULL) return -ENOMEM; - } } return macio_register_driver(&bmac_driver); diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index bec87bd9195..45ba18ee3d6 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -136,10 +136,8 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i */ if (dummy_buf == NULL) { dummy_buf = kmalloc(RX_BUFLEN+2, GFP_KERNEL); - if (dummy_buf == NULL) { - printk(KERN_ERR "MACE: couldn't allocate dummy buffer\n"); + if (dummy_buf == NULL) return -ENOMEM; - } } if (macio_request_resources(mdev, "mace")) { diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c index 021fb818007..0a4c5405dcf 100644 --- a/drivers/net/ethernet/broadcom/bnx2.c +++ b/drivers/net/ethernet/broadcom/bnx2.c @@ -2625,10 +2625,8 @@ bnx2_alloc_bad_rbuf(struct bnx2 *bp) u32 val; good_mbuf = kmalloc(512 * sizeof(u16), GFP_KERNEL); - if (good_mbuf == NULL) { - pr_err("Failed to allocate memory in %s\n", __func__); + if (good_mbuf == NULL) return -ENOMEM; - } REG_WR(bp, BNX2_MISC_ENABLE_SET_BITS, BNX2_MISC_ENABLE_SET_BITS_RX_MBUF_ENABLE); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index fea96150539..582cbcf5f9f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -10894,10 +10894,8 @@ static inline void be16_to_cpu_n(const u8 *_source, u8 *_target, u32 n) do { \ u32 len = be32_to_cpu(fw_hdr->arr.len); \ bp->arr = kmalloc(len, GFP_KERNEL); \ - if (!bp->arr) { \ - pr_err("Failed to allocate %d bytes for "#arr"\n", len); \ + if (!bp->arr) \ goto lbl; \ - } \ func(bp->firmware->data + be32_to_cpu(fw_hdr->arr.offset), \ (u8 *)bp->arr, len); \ } while (0) diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c index 592ad3929f5..c9fdceb135f 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c +++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c @@ -62,8 +62,6 @@ bnad_debugfs_open_fwtrc(struct inode *inode, struct file *file) if (!fw_debug->debug_buffer) { kfree(fw_debug); fw_debug = NULL; - pr_warn("bna %s: Failed to allocate fwtrc buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -105,8 +103,6 @@ bnad_debugfs_open_fwsave(struct inode *inode, struct file *file) if (!fw_debug->debug_buffer) { kfree(fw_debug); fw_debug = NULL; - pr_warn("bna %s: Failed to allocate fwsave buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -208,8 +204,6 @@ bnad_debugfs_open_drvinfo(struct inode *inode, struct file *file) if (!drv_info->debug_buffer) { kfree(drv_info); drv_info = NULL; - pr_warn("bna %s: Failed to allocate drv info buffer\n", - pci_name(bnad->pcidev)); return -ENOMEM; } @@ -348,11 +342,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, /* Allocate memory to store the user space buf */ kern_buf = kzalloc(nbytes, GFP_KERNEL); - if (!kern_buf) { - pr_warn("bna %s: Failed to allocate user buffer\n", - pci_name(bnad->pcidev)); + if (!kern_buf) return -ENOMEM; - } if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) { kfree(kern_buf); @@ -373,11 +364,8 @@ bnad_debugfs_write_regrd(struct file *file, const char __user *buf, bnad->reglen = 0; bnad->regdata = kzalloc(len << 2, GFP_KERNEL); - if (!bnad->regdata) { - pr_warn("bna %s: Failed to allocate regrd buffer\n", - pci_name(bnad->pcidev)); + if (!bnad->regdata) return -ENOMEM; - } bnad->reglen = len << 2; rb = bfa_ioc_bar0(ioc); @@ -421,11 +409,8 @@ bnad_debugfs_write_regwr(struct file *file, const char __user *buf, /* Allocate memory to store the user space buf */ kern_buf = kzalloc(nbytes, GFP_KERNEL); - if (!kern_buf) { - pr_warn("bna %s: Failed to allocate user buffer\n", - pci_name(bnad->pcidev)); + if (!kern_buf) return -ENOMEM; - } if (copy_from_user(kern_buf, (void __user *)buf, nbytes)) { kfree(kern_buf); diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index ab3f67f980d..07df13745c4 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2388,7 +2388,6 @@ static int __devinit enic_probe(struct pci_dev *pdev, /* Allocate structure for port profiles */ enic->pp = kcalloc(num_pps, sizeof(*enic->pp), GFP_KERNEL); if (!enic->pp) { - pr_err("port profile alloc failed, aborting\n"); err = -ENOMEM; goto err_out_disable_sriov_pp; } diff --git a/drivers/net/ethernet/cisco/enic/vnic_rq.c b/drivers/net/ethernet/cisco/enic/vnic_rq.c index 34105e0951a..7e1488fc8ab 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_rq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_rq.c @@ -38,10 +38,8 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq) for (i = 0; i < blks; i++) { rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!rq->bufs[i]) { - pr_err("Failed to alloc rq_bufs\n"); + if (!rq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c index df61bd932ea..5e0d7a2be9b 100644 --- a/drivers/net/ethernet/cisco/enic/vnic_wq.c +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c @@ -38,10 +38,8 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq) for (i = 0; i < blks; i++) { wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC); - if (!wq->bufs[i]) { - pr_err("Failed to alloc wq_bufs\n"); + if (!wq->bufs[i]) return -ENOMEM; - } } for (i = 0; i < blks; i++) { diff --git a/drivers/net/ethernet/i825xx/lp486e.c b/drivers/net/ethernet/i825xx/lp486e.c index 414044b3cb1..02df5f5accb 100644 --- a/drivers/net/ethernet/i825xx/lp486e.c +++ b/drivers/net/ethernet/i825xx/lp486e.c @@ -454,8 +454,6 @@ init_rx_bufs(struct net_device *dev, int num) { } rfd->rbd = rbd; - } else { - printk("Could not kmalloc rbd\n"); } } lp->rbd_tail->next = rfd->rbd; diff --git a/drivers/net/ethernet/ibm/emac/rgmii.c b/drivers/net/ethernet/ibm/emac/rgmii.c index 05484f918ee..d3123282e18 100644 --- a/drivers/net/ethernet/ibm/emac/rgmii.c +++ b/drivers/net/ethernet/ibm/emac/rgmii.c @@ -237,11 +237,8 @@ static int __devinit rgmii_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct rgmii_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate RGMII device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/emac/tah.c b/drivers/net/ethernet/ibm/emac/tah.c index 0d9881efe2f..872912ef518 100644 --- a/drivers/net/ethernet/ibm/emac/tah.c +++ b/drivers/net/ethernet/ibm/emac/tah.c @@ -96,11 +96,8 @@ static int __devinit tah_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct tah_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate TAH device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/emac/zmii.c b/drivers/net/ethernet/ibm/emac/zmii.c index e799a6116ba..415e9b4d540 100644 --- a/drivers/net/ethernet/ibm/emac/zmii.c +++ b/drivers/net/ethernet/ibm/emac/zmii.c @@ -240,11 +240,8 @@ static int __devinit zmii_probe(struct platform_device *ofdev) rc = -ENOMEM; dev = kzalloc(sizeof(struct zmii_instance), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "%s: could not allocate ZMII device!\n", - np->full_name); + if (dev == NULL) goto err_gone; - } mutex_init(&dev->lock); dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/intel/e1000/e1000_main.c b/drivers/net/ethernet/intel/e1000/e1000_main.c index 669ca3800c0..363fd395c75 100644 --- a/drivers/net/ethernet/intel/e1000/e1000_main.c +++ b/drivers/net/ethernet/intel/e1000/e1000_main.c @@ -730,10 +730,8 @@ static void e1000_dump_eeprom(struct e1000_adapter *adapter) eeprom.offset = 0; data = kmalloc(eeprom.len, GFP_KERNEL); - if (!data) { - pr_err("Unable to allocate memory to dump EEPROM data\n"); + if (!data) return; - } ops->get_eeprom(netdev, &eeprom, data); diff --git a/drivers/net/ethernet/intel/ixgb/ixgb_main.c b/drivers/net/ethernet/intel/ixgb/ixgb_main.c index 9bd5faf64a8..002478801a1 100644 --- a/drivers/net/ethernet/intel/ixgb/ixgb_main.c +++ b/drivers/net/ethernet/intel/ixgb/ixgb_main.c @@ -1136,10 +1136,8 @@ ixgb_set_multi(struct net_device *netdev) u8 *mta = kmalloc(IXGB_MAX_NUM_MULTICAST_ADDRESSES * ETH_ALEN, GFP_ATOMIC); u8 *addr; - if (!mta) { - pr_err("allocation of multicast memory failed\n"); + if (!mta) goto alloc_failed; - } IXGB_WRITE_REG(hw, RCTL, rctl); diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c index bed411bada2..f3bc9333a08 100644 --- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c +++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c @@ -2517,12 +2517,8 @@ int ixgbevf_setup_rx_resources(struct ixgbevf_adapter *adapter, size = sizeof(struct ixgbevf_rx_buffer) * rx_ring->count; rx_ring->rx_buffer_info = vzalloc(size); - if (!rx_ring->rx_buffer_info) { - hw_dbg(&adapter->hw, - "Unable to vmalloc buffer memory for " - "the receive descriptor ring\n"); + if (!rx_ring->rx_buffer_info) goto alloc_failed; - } /* Round up to nearest 4K */ rx_ring->size = rx_ring->count * sizeof(union ixgbe_adv_rx_desc); diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 6ad094f176f..341d10130dc 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1150,7 +1150,6 @@ static int korina_probe(struct platform_device *pdev) lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL); if (!lp->td_ring) { - printk(KERN_ERR DRV_NAME ": cannot allocate descriptors\n"); rc = -ENXIO; goto probe_err_td_ring; } diff --git a/drivers/net/ethernet/marvell/pxa168_eth.c b/drivers/net/ethernet/marvell/pxa168_eth.c index 953ba5851f7..92b4b4e68e3 100644 --- a/drivers/net/ethernet/marvell/pxa168_eth.c +++ b/drivers/net/ethernet/marvell/pxa168_eth.c @@ -1017,10 +1017,9 @@ static int rxq_init(struct net_device *dev) /* Allocate RX skb rings */ pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size, GFP_KERNEL); - if (!pep->rx_skb) { - printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name); + if (!pep->rx_skb) return -ENOMEM; - } + /* Allocate RX ring */ pep->rx_desc_count = 0; size = pep->rx_ring_size * sizeof(struct rx_desc); @@ -1081,10 +1080,9 @@ static int txq_init(struct net_device *dev) pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size, GFP_KERNEL); - if (!pep->tx_skb) { - printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name); + if (!pep->tx_skb) return -ENOMEM; - } + /* Allocate TX ring */ pep->tx_desc_count = 0; size = pep->tx_ring_size * sizeof(struct tx_desc); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_rx.c b/drivers/net/ethernet/mellanox/mlx4/en_rx.c index 971d4b6b8df..f61d0e08f52 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_rx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_rx.c @@ -281,10 +281,9 @@ int mlx4_en_create_rx_ring(struct mlx4_en_priv *priv, tmp = size * roundup_pow_of_two(MLX4_EN_MAX_RX_FRAGS * sizeof(struct skb_frag_struct)); ring->rx_info = vmalloc(tmp); - if (!ring->rx_info) { - en_err(priv, "Failed allocating rx_info ring\n"); + if (!ring->rx_info) return -ENOMEM; - } + en_dbg(DRV, priv, "Allocated rx_info ring at addr:%p size:%d\n", ring->rx_info, tmp); diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c index 9ef9038d062..ff325058658 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c @@ -71,16 +71,14 @@ int mlx4_en_create_tx_ring(struct mlx4_en_priv *priv, tmp = size * sizeof(struct mlx4_en_tx_info); ring->tx_info = vmalloc(tmp); - if (!ring->tx_info) { - en_err(priv, "Failed allocating tx_info ring\n"); + if (!ring->tx_info) return -ENOMEM; - } + en_dbg(DRV, priv, "Allocated tx_info ring at addr:%p size:%d\n", ring->tx_info, tmp); ring->bounce_buf = kmalloc(MAX_DESC_SIZE, GFP_KERNEL); if (!ring->bounce_buf) { - en_err(priv, "Failed allocating bounce buffer\n"); err = -ENOMEM; goto err_tx; } diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index a37264e61a2..4a9d57fb9fb 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -1501,10 +1501,8 @@ static int ks_hw_init(struct ks_net *ks) ks->mcast_lst_size = 0; ks->frame_head_info = kmalloc(MHEADER_SIZE, GFP_KERNEL); - if (!ks->frame_head_info) { - pr_err("Error: Fail to allocate frame memory\n"); + if (!ks->frame_head_info) return false; - } ks_set_mac(ks, KS_DEFAULT_MAC_ADDRESS); return true; diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 3ead111111e..0217991fede 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -1587,10 +1587,8 @@ int pch_gbe_setup_tx_resources(struct pch_gbe_adapter *adapter, size = (int)sizeof(struct pch_gbe_buffer) * tx_ring->count; tx_ring->buffer_info = vzalloc(size); - if (!tx_ring->buffer_info) { - pr_err("Unable to allocate memory for the buffer information\n"); + if (!tx_ring->buffer_info) return -ENOMEM; - } tx_ring->size = tx_ring->count * (int)sizeof(struct pch_gbe_tx_desc); @@ -1636,10 +1634,9 @@ int pch_gbe_setup_rx_resources(struct pch_gbe_adapter *adapter, size = (int)sizeof(struct pch_gbe_buffer) * rx_ring->count; rx_ring->buffer_info = vzalloc(size); - if (!rx_ring->buffer_info) { - pr_err("Unable to allocate memory for the receive descriptor ring\n"); + if (!rx_ring->buffer_info) return -ENOMEM; - } + rx_ring->size = rx_ring->count * (int)sizeof(struct pch_gbe_rx_desc); rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size, &rx_ring->dma, GFP_KERNEL); diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c index a8259cc19a6..094d26c5181 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_init.c @@ -280,13 +280,10 @@ int netxen_alloc_sw_resources(struct netxen_adapter *adapter) } rds_ring->rx_buf_arr = vzalloc(RCV_BUFF_RINGSIZE(rds_ring)); - if (rds_ring->rx_buf_arr == NULL) { - printk(KERN_ERR "%s: Failed to allocate " - "rx buffer ring %d\n", - netdev->name, ring); + if (rds_ring->rx_buf_arr == NULL) /* free whatever was already allocated */ goto err_out; - } + INIT_LIST_HEAD(&rds_ring->free_list); /* * Now go through all of them, set reference handles @@ -480,11 +477,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter) } buf = kcalloc(n, sizeof(struct crb_addr_pair), GFP_KERNEL); - if (buf == NULL) { - printk("%s: netxen_pinit_from_rom: Unable to calloc memory.\n", - netxen_nic_driver_name); + if (buf == NULL) return -ENOMEM; - } for (i = 0; i < n; i++) { if (netxen_rom_fast_read(adapter, 8*i + 4*offset, &val) != 0 || diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c index fca804f36d6..58185b604b7 100644 --- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c @@ -1824,10 +1824,8 @@ void ql_dump_hw_cb(struct ql_adapter *qdev, int size, u32 bit, u16 q_id) pr_err("%s: Enter\n", __func__); ptr = kmalloc(size, GFP_ATOMIC); - if (ptr == NULL) { - pr_err("%s: Couldn't allocate a buffer\n", __func__); + if (ptr == NULL) return; - } if (ql_write_cfg(qdev, ptr, size, bit, q_id)) { pr_err("%s: Failed to upload control block!\n", __func__); diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index c8efc708c79..91c44688bc3 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -619,7 +619,6 @@ static int __devinit sis900_mii_probe(struct net_device * net_dev) } if ((mii_phy = kmalloc(sizeof(struct mii_phy), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "Cannot allocate mem for struct mii_phy\n"); mii_phy = sis_priv->first_mii; while (mii_phy) { struct mii_phy *phy; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 96fa2da3076..ffc7581879b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -954,10 +954,9 @@ static int stmmac_open(struct net_device *dev) #ifdef CONFIG_STMMAC_TIMER priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); - if (unlikely(priv->tm == NULL)) { - pr_err("%s: ERROR: timer memory alloc failed\n", __func__); + if (unlikely(priv->tm == NULL)) return -ENOMEM; - } + priv->tm->freq = tmrate; /* Test if the external timer can be actually used. diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index f10665f594c..46d84abe553 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -835,7 +835,6 @@ static int cas_saturn_firmware_init(struct cas *cp) cp->fw_data = vmalloc(cp->fw_size); if (!cp->fw_data) { err = -ENOMEM; - pr_err("\"%s\" Failed %d\n", fw_name, err); goto out; } memcpy(cp->fw_data, &fw->data[2], cp->fw_size); diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 8c6c059f348..2896f6e9672 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -949,10 +949,9 @@ static int __devinit vnet_port_alloc_tx_bufs(struct vnet_port *port) int map_len = (ETH_FRAME_LEN + 7) & ~7; err = -ENOMEM; - if (!buf) { - pr_err("TX buffer allocation failure\n"); + if (!buf) goto err_out; - } + err = -EFAULT; if ((unsigned long)buf & (8UL - 1)) { pr_err("TX buffer misaligned\n"); @@ -1165,10 +1164,8 @@ static int __devinit vnet_port_probe(struct vio_dev *vdev, port = kzalloc(sizeof(*port), GFP_KERNEL); err = -ENOMEM; - if (!port) { - pr_err("Cannot allocate vnet_port\n"); + if (!port) goto err_out_put_mdesc; - } for (i = 0; i < ETH_ALEN; i++) port->raddr[i] = (*rmac >> (5 - i) * 8) & 0xff; diff --git a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c index fd4ed7f8cfa..5c14f82c495 100644 --- a/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c +++ b/drivers/net/ethernet/toshiba/ps3_gelic_wireless.c @@ -1621,10 +1621,9 @@ static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl) kfree(target->hwinfo); target->hwinfo = kzalloc(be16_to_cpu(scan_info->size), GFP_KERNEL); - if (!target->hwinfo) { - pr_info("%s: kzalloc failed\n", __func__); + if (!target->hwinfo) continue; - } + /* copy hw scan info */ memcpy(target->hwinfo, scan_info, scan_info->size); target->essid_len = strnlen(scan_info->essid, diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c index 96a98d2ff15..696327773fb 100644 --- a/drivers/net/hamradio/yam.c +++ b/drivers/net/hamradio/yam.c @@ -403,7 +403,6 @@ static unsigned char *add_mcs(unsigned char *bits, int bitrate, /* Allocate a new mcs */ if ((p = kmalloc(sizeof(struct yam_mcs), GFP_KERNEL)) == NULL) { - printk(KERN_WARNING "YAM: no memory to allocate mcs\n"); release_firmware(fw); return NULL; } diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c index e68c941926f..2a51363d9fe 100644 --- a/drivers/net/hippi/rrunner.c +++ b/drivers/net/hippi/rrunner.c @@ -1600,12 +1600,8 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); - if (!image){ - printk(KERN_ERR "%s: Unable to allocate memory " - "for EEPROM image\n", dev->name); + if (!image) return -ENOMEM; - } - if (rrpriv->fw_running){ printk("%s: Firmware already running\n", dev->name); @@ -1637,8 +1633,6 @@ static int rr_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) image = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); oldimage = kmalloc(EEPROM_WORDS * sizeof(u32), GFP_KERNEL); if (!image || !oldimage) { - printk(KERN_ERR "%s: Unable to allocate memory " - "for EEPROM image\n", dev->name); error = -ENOMEM; goto wf_out; } diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c index 64f403da101..617a446d126 100644 --- a/drivers/net/irda/donauboe.c +++ b/drivers/net/irda/donauboe.c @@ -1608,7 +1608,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) self->ringbuf = kmalloc(OBOE_RING_LEN << 1, GFP_KERNEL); if (!self->ringbuf) { - printk (KERN_ERR DRIVER_NAME ": can't allocate DMA buffers\n"); err = -ENOMEM; goto freeregion; } @@ -1647,7 +1646,6 @@ toshoboe_open (struct pci_dev *pci_dev, const struct pci_device_id *pdid) if (!ok) { - printk (KERN_ERR DRIVER_NAME ": can't allocate rx/tx buffers\n"); err = -ENOMEM; goto freebufs; } diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index e8882023576..f9347ea3d38 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -169,10 +169,8 @@ static struct netconsole_target *alloc_param_target(char *target_config) * Note that these targets get their config_item fields zeroed-out. */ nt = kzalloc(sizeof(*nt), GFP_KERNEL); - if (!nt) { - printk(KERN_ERR "netconsole: failed to allocate memory\n"); + if (!nt) goto fail; - } nt->np.name = "netconsole"; strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); @@ -551,10 +549,8 @@ static struct config_item *make_netconsole_target(struct config_group *group, * Target is disabled at creation (enabled == 0). */ nt = kzalloc(sizeof(*nt), GFP_KERNEL); - if (!nt) { - printk(KERN_ERR "netconsole: failed to allocate memory\n"); + if (!nt) return ERR_PTR(-ENOMEM); - } nt->np.name = "netconsole"; strlcpy(nt->np.dev_name, "eth0", IFNAMSIZ); diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index df884dde2a5..234cd9d87ed 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -670,10 +670,8 @@ static int __init pptp_init_module(void) pr_info("PPTP driver version " PPTP_DRIVER_VERSION "\n"); callid_sock = vzalloc((MAX_CALLID + 1) * sizeof(void *)); - if (!callid_sock) { - pr_err("PPTP: cann't allocate memory\n"); + if (!callid_sock) return -ENOMEM; - } err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); if (err) { diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index ba08341fb92..69345dfae0f 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c @@ -1296,10 +1296,8 @@ static int __init slip_init(void) slip_devs = kzalloc(sizeof(struct net_device *)*slip_maxdev, GFP_KERNEL); - if (!slip_devs) { - printk(KERN_ERR "SLIP: Can't allocate slip devices array.\n"); + if (!slip_devs) return -ENOMEM; - } /* Fill in our line protocol discipline, and register it */ status = tty_register_ldisc(N_SLIP, &sl_ldisc); diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c index ef9fdf3652f..d7c292aa76b 100644 --- a/drivers/net/tokenring/3c359.c +++ b/drivers/net/tokenring/3c359.c @@ -674,15 +674,11 @@ static int xl_open(struct net_device *dev) /* These MUST be on 8 byte boundaries */ xl_priv->xl_tx_ring = kzalloc((sizeof(struct xl_tx_desc) * XL_TX_RING_SIZE) + 7, GFP_DMA | GFP_KERNEL); if (xl_priv->xl_tx_ring == NULL) { - printk(KERN_WARNING "%s: Not enough memory to allocate tx buffers.\n", - dev->name); free_irq(dev->irq,dev); return -ENOMEM; } xl_priv->xl_rx_ring = kzalloc((sizeof(struct xl_rx_desc) * XL_RX_RING_SIZE) +7, GFP_DMA | GFP_KERNEL); if (xl_priv->xl_rx_ring == NULL) { - printk(KERN_WARNING "%s: Not enough memory to allocate rx buffers.\n", - dev->name); free_irq(dev->irq,dev); kfree(xl_priv->xl_tx_ring); return -ENOMEM; diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 6153cfd696b..1cdc034f6ae 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -171,7 +171,6 @@ static int __devinit madgemc_probe(struct device *device) card = kmalloc(sizeof(struct card_info), GFP_KERNEL); if (card==NULL) { - printk("madgemc: unable to allocate card struct\n"); ret = -ENOMEM; goto getout1; } diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index be6aa353f6a..87c0b586f11 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -537,11 +537,8 @@ vmxnet3_tq_create(struct vmxnet3_tx_queue *tq, tq->buf_info = kcalloc(tq->tx_ring.size, sizeof(tq->buf_info[0]), GFP_KERNEL); - if (!tq->buf_info) { - printk(KERN_ERR "%s: failed to allocate tx bufinfo\n", - adapter->netdev->name); + if (!tq->buf_info) goto err; - } return 0; @@ -1519,11 +1516,9 @@ vmxnet3_rq_create(struct vmxnet3_rx_queue *rq, struct vmxnet3_adapter *adapter) sz = sizeof(struct vmxnet3_rx_buf_info) * (rq->rx_ring[0].size + rq->rx_ring[1].size); bi = kzalloc(sz, GFP_KERNEL); - if (!bi) { - printk(KERN_ERR "%s: failed to allocate rx bufinfo\n", - adapter->netdev->name); + if (!bi) goto err; - } + rq->buf_info[0] = bi; rq->buf_info[1] = bi + rq->rx_ring[0].size; @@ -2964,8 +2959,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->pm_conf = kmalloc(sizeof(struct Vmxnet3_PMConf), GFP_KERNEL); if (adapter->pm_conf == NULL) { - printk(KERN_ERR "Failed to allocate memory for %s\n", - pci_name(pdev)); err = -ENOMEM; goto err_alloc_pm; } @@ -2974,8 +2967,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->rss_conf = kmalloc(sizeof(struct UPT1_RSSConf), GFP_KERNEL); if (adapter->rss_conf == NULL) { - printk(KERN_ERR "Failed to allocate memory for %s\n", - pci_name(pdev)); err = -ENOMEM; goto err_alloc_rss; } diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c index 54f995f4a5a..09a50751763 100644 --- a/drivers/net/wan/c101.c +++ b/drivers/net/wan/c101.c @@ -325,10 +325,8 @@ static int __init c101_run(unsigned long irq, unsigned long winbase) } card = kzalloc(sizeof(card_t), GFP_KERNEL); - if (card == NULL) { - pr_err("unable to allocate memory\n"); + if (card == NULL) return -ENOBUFS; - } card->dev = alloc_hdlcdev(card); if (!card->dev) { diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 058e1697c17..fe8d060d8ff 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -903,10 +903,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) int i, ret = -ENOMEM; root = kcalloc(dev_per_card, sizeof(*root), GFP_KERNEL); - if (!root) { - pr_err("can't allocate data\n"); + if (!root) goto err_out; - } for (i = 0; i < dev_per_card; i++) { root[i].dev = alloc_hdlcdev(root + i); @@ -915,10 +913,8 @@ static int dscc4_found1(struct pci_dev *pdev, void __iomem *ioaddr) } ppriv = kzalloc(sizeof(*ppriv), GFP_KERNEL); - if (!ppriv) { - pr_err("can't allocate private data\n"); + if (!ppriv) goto err_free_dev; - } ppriv->root = root; spin_lock_init(&ppriv->lock); diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c index b7f2358d23b..76a8a4a522e 100644 --- a/drivers/net/wan/lmc/lmc_main.c +++ b/drivers/net/wan/lmc/lmc_main.c @@ -497,7 +497,6 @@ int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/ data = kmalloc(xc.len, GFP_KERNEL); if (!data) { - printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name); ret = -ENOMEM; break; } diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c index 5129ad514d2..315bf09d6a2 100644 --- a/drivers/net/wan/n2.c +++ b/drivers/net/wan/n2.c @@ -358,10 +358,8 @@ static int __init n2_run(unsigned long io, unsigned long irq, } card = kzalloc(sizeof(card_t), GFP_KERNEL); - if (card == NULL) { - pr_err("unable to allocate memory\n"); + if (card == NULL) return -ENOBUFS; - } card->ports[0].dev = alloc_hdlcdev(&card->ports[0]); card->ports[1].dev = alloc_hdlcdev(&card->ports[1]); diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c index c49c1b3c7aa..5fe246e060d 100644 --- a/drivers/net/wan/pc300too.c +++ b/drivers/net/wan/pc300too.c @@ -320,7 +320,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c index 1ce21163c77..9659fcaa34e 100644 --- a/drivers/net/wan/pci200syn.c +++ b/drivers/net/wan/pci200syn.c @@ -299,7 +299,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev, card = kzalloc(sizeof(card_t), GFP_KERNEL); if (card == NULL) { - pr_err("unable to allocate memory\n"); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/wanxl.c b/drivers/net/wan/wanxl.c index 44b70719725..feb7541b33f 100644 --- a/drivers/net/wan/wanxl.c +++ b/drivers/net/wan/wanxl.c @@ -604,7 +604,6 @@ static int __devinit wanxl_pci_init_one(struct pci_dev *pdev, alloc_size = sizeof(card_t) + ports * sizeof(port_t); card = kzalloc(alloc_size, GFP_KERNEL); if (card == NULL) { - pr_err("%s: unable to allocate memory\n", pci_name(pdev)); pci_release_regions(pdev); pci_disable_device(pdev); return -ENOBUFS; diff --git a/drivers/net/wan/x25_asy.c b/drivers/net/wan/x25_asy.c index 8a10bb730d5..e862369b4a6 100644 --- a/drivers/net/wan/x25_asy.c +++ b/drivers/net/wan/x25_asy.c @@ -786,10 +786,8 @@ static int __init init_x25_asy(void) x25_asy_devs = kcalloc(x25_asy_maxdev, sizeof(struct net_device *), GFP_KERNEL); - if (!x25_asy_devs) { - pr_warn("Can't allocate x25_asy_ctrls[] array! Uaargh! (-> No X.25 available)\n"); + if (!x25_asy_devs) return -ENOMEM; - } return tty_register_ldisc(N_X25, &x25_ldisc); } diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c index 1b90ed8795c..c25226a32dd 100644 --- a/drivers/net/wireless/ath/ath9k/htc_hst.c +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c @@ -431,11 +431,8 @@ struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, struct htc_target *target; target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); - if (!target) { - printk(KERN_ERR "Unable to allocate memory for" - "target device\n"); + if (!target) return NULL; - } init_completion(&target->target_wait); init_completion(&target->cmd_wait); diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c index a8bddd81b4d..aa15cc4269a 100644 --- a/drivers/net/wireless/hostap/hostap_hw.c +++ b/drivers/net/wireless/hostap/hostap_hw.c @@ -347,11 +347,9 @@ static int hfa384x_cmd(struct net_device *dev, u16 cmd, u16 param0, return -EINTR; entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd - kmalloc failed\n", - dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_SLEEP; entry->cmd = cmd; @@ -515,11 +513,9 @@ static int hfa384x_cmd_callback(struct net_device *dev, u16 cmd, u16 param0, } entry = kzalloc(sizeof(*entry), GFP_ATOMIC); - if (entry == NULL) { - printk(KERN_DEBUG "%s: hfa384x_cmd_callback - kmalloc " - "failed\n", dev->name); + if (entry == NULL) return -ENOMEM; - } + atomic_set(&entry->usecnt, 1); entry->type = CMD_CALLBACK; entry->cmd = cmd; @@ -2978,11 +2974,9 @@ static int prism2_set_tim(struct net_device *dev, int aid, int set) local = iface->local; new_entry = kzalloc(sizeof(*new_entry), GFP_ATOMIC); - if (new_entry == NULL) { - printk(KERN_DEBUG "%s: prism2_set_tim: kmalloc failed\n", - local->dev->name); + if (new_entry == NULL) return -ENOMEM; - } + new_entry->aid = aid; new_entry->set = set; diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c index a0e5c21d365..e847737ccc9 100644 --- a/drivers/net/wireless/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/ipw2x00/ipw2100.c @@ -3464,11 +3464,8 @@ static int ipw2100_msg_allocate(struct ipw2100_priv *priv) priv->msg_buffers = kmalloc(IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet), GFP_KERNEL); - if (!priv->msg_buffers) { - printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg " - "buffers.\n", priv->net_dev->name); + if (!priv->msg_buffers) return -ENOMEM; - } for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) { v = pci_alloc_consistent(priv->pci_dev, diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c index 3f7bf4d912b..234ee88dec9 100644 --- a/drivers/net/wireless/libertas/if_cs.c +++ b/drivers/net/wireless/libertas/if_cs.c @@ -815,10 +815,9 @@ static int if_cs_probe(struct pcmcia_device *p_dev) lbs_deb_enter(LBS_DEB_CS); card = kzalloc(sizeof(struct if_cs_card), GFP_KERNEL); - if (!card) { - pr_err("error in kzalloc\n"); + if (!card) goto out; - } + card->p_dev = p_dev; p_dev->priv = card; diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index b5fbbc7947d..74da5f1ea24 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c @@ -261,10 +261,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c index aff8b5743af..7ced130f4f9 100644 --- a/drivers/net/wireless/libertas_tf/if_usb.c +++ b/drivers/net/wireless/libertas_tf/if_usb.c @@ -153,10 +153,8 @@ static int if_usb_probe(struct usb_interface *intf, udev = interface_to_usbdev(intf); cardp = kzalloc(sizeof(struct if_usb_card), GFP_KERNEL); - if (!cardp) { - pr_err("Out of memory allocating private data.\n"); + if (!cardp) goto error; - } setup_timer(&cardp->fw_timeout, if_usb_fw_timeo, (unsigned long)cardp); init_waitqueue_head(&cardp->fw_wq); diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 405350940a4..f4fbad95d3e 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -86,10 +86,8 @@ static int mwifiex_pcie_probe(struct pci_dev *pdev, pdev->vendor, pdev->device, pdev->revision); card = kzalloc(sizeof(struct pcie_service_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->dev = pdev; diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c index d39d8457f25..83590275023 100644 --- a/drivers/net/wireless/mwifiex/sdio.c +++ b/drivers/net/wireless/mwifiex/sdio.c @@ -70,10 +70,8 @@ mwifiex_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) func->vendor, func->device, func->class, func->num); card = kzalloc(sizeof(struct sdio_mmc_card), GFP_KERNEL); - if (!card) { - pr_err("%s: failed to alloc memory\n", __func__); + if (!card) return -ENOMEM; - } card->func = func; diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 9fb77d0319f..dd6c64ac406 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c @@ -941,11 +941,9 @@ void __orinoco_ev_rx(struct net_device *dev, struct hermes *hw) /* Add desc and skb to rx queue */ rx_data = kzalloc(sizeof(*rx_data), GFP_ATOMIC); - if (!rx_data) { - printk(KERN_WARNING "%s: Can't allocate RX packet\n", - dev->name); + if (!rx_data) goto drop; - } + rx_data->desc = desc; rx_data->skb = skb; list_add_tail(&rx_data->list, &priv->rx_list); diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c index a5224f6160e..851fa10241e 100644 --- a/drivers/net/wireless/prism54/islpci_mgt.c +++ b/drivers/net/wireless/prism54/islpci_mgt.c @@ -192,11 +192,9 @@ islpci_mgt_transmit(struct net_device *ndev, int operation, unsigned long oid, err = -ENOMEM; p = buf.mem = kmalloc(frag_len, GFP_KERNEL); - if (!buf.mem) { - printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n", - ndev->name); + if (!buf.mem) goto error; - } + buf.size = frag_len; /* create the header directly in the fragment data area */ diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c index 78723cf5949..36140ccf2ab 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c @@ -186,11 +186,8 @@ static int rtl92s_init_sw_vars(struct ieee80211_hw *hw) /* for firmware buf */ rtlpriv->rtlhal.pfirmware = vzalloc(sizeof(struct rt_firmware)); - if (!rtlpriv->rtlhal.pfirmware) { - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - ("Can't alloc buffer for fw.\n")); + if (!rtlpriv->rtlhal.pfirmware) return 1; - } pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n" "Loading firmware %s\n", rtlpriv->cfg->fw_name); diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 59effac15f3..2596401308a 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c @@ -1639,10 +1639,8 @@ static int __init netback_init(void) xen_netbk_group_nr = num_online_cpus(); xen_netbk = vzalloc(sizeof(struct xen_netbk) * xen_netbk_group_nr); - if (!xen_netbk) { - printk(KERN_ALERT "%s: out of memory\n", __func__); + if (!xen_netbk) return -ENOMEM; - } for (group = 0; group < xen_netbk_group_nr; group++) { struct xen_netbk *netbk = &xen_netbk[group]; -- cgit v1.2.3-70-g09d2 From 41de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 29 Jan 2012 13:47:52 +0000 Subject: drivers/net: Remove alloc_etherdev error messages alloc_etherdev has a generic OOM/unable to alloc message. Remove the duplicative messages after alloc_etherdev calls. Signed-off-by: Joe Perches Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 5 ++--- drivers/net/ethernet/adaptec/starfire.c | 5 ++--- drivers/net/ethernet/adi/bfin_mac.c | 4 +--- drivers/net/ethernet/alteon/acenic.c | 5 +---- drivers/net/ethernet/amd/amd8111e.c | 1 - drivers/net/ethernet/amd/au1000_eth.c | 1 - drivers/net/ethernet/amd/declance.c | 2 -- drivers/net/ethernet/amd/pcnet32.c | 2 -- drivers/net/ethernet/apple/bmac.c | 4 +--- drivers/net/ethernet/apple/mace.c | 1 - drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 1 - drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 1 - drivers/net/ethernet/broadcom/b44.c | 1 - drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 4 +--- drivers/net/ethernet/broadcom/sb1250-mac.c | 2 -- drivers/net/ethernet/broadcom/tg3.c | 1 - drivers/net/ethernet/brocade/bna/bnad.c | 1 - drivers/net/ethernet/cadence/macb.c | 4 +--- drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 2 -- drivers/net/ethernet/cisco/enic/enic_main.c | 4 +--- drivers/net/ethernet/davicom/dm9000.c | 4 +--- drivers/net/ethernet/dec/tulip/tulip_core.c | 4 +--- drivers/net/ethernet/dec/tulip/xircom_cb.c | 5 ++--- drivers/net/ethernet/dnet.c | 4 +--- drivers/net/ethernet/ethoc.c | 1 - drivers/net/ethernet/hp/hp100.c | 1 - drivers/net/ethernet/ibm/ehea/ehea_main.c | 1 - drivers/net/ethernet/ibm/emac/core.c | 6 ++---- drivers/net/ethernet/ibm/iseries_veth.c | 4 +--- drivers/net/ethernet/icplus/ipg.c | 1 - drivers/net/ethernet/intel/e100.c | 5 +---- drivers/net/ethernet/jme.c | 1 - drivers/net/ethernet/korina.c | 5 ++--- drivers/net/ethernet/lantiq_etop.c | 4 ++++ drivers/net/ethernet/marvell/skge.c | 4 +--- drivers/net/ethernet/marvell/sky2.c | 4 +--- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 +--- drivers/net/ethernet/micrel/ks8695net.c | 4 +--- drivers/net/ethernet/micrel/ks8851.c | 4 +--- drivers/net/ethernet/microchip/enc28j60.c | 3 --- drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 4 +--- drivers/net/ethernet/neterion/s2io.c | 1 - drivers/net/ethernet/netx-eth.c | 1 - drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c | 2 -- drivers/net/ethernet/packetengines/yellowfin.c | 5 ++--- drivers/net/ethernet/pasemi/pasemi_mac.c | 2 -- drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c | 1 - drivers/net/ethernet/qlogic/qla3xxx.c | 1 - drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 1 - drivers/net/ethernet/rdc/r6040.c | 1 - drivers/net/ethernet/realtek/8139too.c | 5 ++--- drivers/net/ethernet/realtek/r8169.c | 2 -- drivers/net/ethernet/renesas/sh_eth.c | 1 - drivers/net/ethernet/s6gmac.c | 6 +++--- drivers/net/ethernet/seeq/sgiseeq.c | 1 - drivers/net/ethernet/sis/sis190.c | 2 -- drivers/net/ethernet/smsc/epic100.c | 5 ++--- drivers/net/ethernet/smsc/smc911x.c | 1 - drivers/net/ethernet/smsc/smc91x.c | 1 - drivers/net/ethernet/smsc/smsc911x.c | 1 - drivers/net/ethernet/smsc/smsc9420.c | 4 +--- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 4 +--- drivers/net/ethernet/sun/cassini.c | 1 - drivers/net/ethernet/sun/niu.c | 4 +--- drivers/net/ethernet/sun/sungem.c | 1 - drivers/net/ethernet/sun/sunvnet.c | 4 +--- drivers/net/ethernet/tehuti/tehuti.c | 1 - drivers/net/ethernet/ti/cpmac.c | 5 +---- drivers/net/ethernet/ti/davinci_emac.c | 1 - drivers/net/ethernet/ti/tlan.c | 1 - drivers/net/ethernet/toshiba/tc35815.c | 5 ++--- drivers/net/ethernet/tundra/tsi108_eth.c | 4 +--- drivers/net/ethernet/via/via-rhine.c | 1 - drivers/net/ethernet/via/via-velocity.c | 4 +--- drivers/net/ethernet/xilinx/ll_temac_main.c | 5 ++--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 4 +--- drivers/net/ethernet/xilinx/xilinx_emaclite.c | 4 +--- drivers/net/plip/plip.c | 4 +--- drivers/net/rionet.c | 2 -- drivers/net/usb/pegasus.c | 4 +--- drivers/net/usb/rtl8150.c | 4 +--- drivers/net/usb/usbnet.c | 4 +--- drivers/net/vmxnet3/vmxnet3_drv.c | 5 +---- drivers/net/wireless/atmel.c | 5 ++--- drivers/net/wireless/ipw2x00/libipw_module.c | 5 ++--- drivers/net/xen-netfront.c | 5 +---- 86 files changed, 63 insertions(+), 192 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 8153a3e0a1a..dc51d9218e6 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1121,10 +1121,9 @@ static int __devinit vortex_probe1(struct device *gendev, dev = alloc_etherdev(sizeof(*vp)); retval = -ENOMEM; - if (!dev) { - pr_err(PFX "unable to allocate etherdev, aborting\n"); + if (!dev) goto out; - } + SET_NETDEV_DEV(dev, gendev); vp = netdev_priv(dev); diff --git a/drivers/net/ethernet/adaptec/starfire.c b/drivers/net/ethernet/adaptec/starfire.c index cb4f38a17f2..11fc2eccb0f 100644 --- a/drivers/net/ethernet/adaptec/starfire.c +++ b/drivers/net/ethernet/adaptec/starfire.c @@ -686,10 +686,9 @@ static int __devinit starfire_init_one(struct pci_dev *pdev, } dev = alloc_etherdev(sizeof(*np)); - if (!dev) { - printk(KERN_ERR DRV_NAME " %d: cannot alloc etherdev, aborting\n", card_idx); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); irq = pdev->irq; diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index d812a103e03..525a9768bb5 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -1467,10 +1467,8 @@ static int __devinit bfin_mac_probe(struct platform_device *pdev) int rc; ndev = alloc_etherdev(sizeof(struct bfin_mac_local)); - if (!ndev) { - dev_err(&pdev->dev, "Cannot allocate net device!\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); platform_set_drvdata(pdev, ndev); diff --git a/drivers/net/ethernet/alteon/acenic.c b/drivers/net/ethernet/alteon/acenic.c index f872748ab4e..6c3b1c0adaa 100644 --- a/drivers/net/ethernet/alteon/acenic.c +++ b/drivers/net/ethernet/alteon/acenic.c @@ -463,11 +463,8 @@ static int __devinit acenic_probe_one(struct pci_dev *pdev, static int boards_found; dev = alloc_etherdev(sizeof(struct ace_private)); - if (dev == NULL) { - printk(KERN_ERR "acenic: Unable to allocate " - "net_device structure!\n"); + if (dev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/amd/amd8111e.c b/drivers/net/ethernet/amd/amd8111e.c index 33e0a8c20f6..b8306a58955 100644 --- a/drivers/net/ethernet/amd/amd8111e.c +++ b/drivers/net/ethernet/amd/amd8111e.c @@ -1859,7 +1859,6 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct amd8111e_priv)); if (!dev) { - printk(KERN_ERR "amd8111e: Etherdev alloc failed, exiting.\n"); err = -ENOMEM; goto err_free_reg; } diff --git a/drivers/net/ethernet/amd/au1000_eth.c b/drivers/net/ethernet/amd/au1000_eth.c index 8b95dd31425..a81c871aeac 100644 --- a/drivers/net/ethernet/amd/au1000_eth.c +++ b/drivers/net/ethernet/amd/au1000_eth.c @@ -1077,7 +1077,6 @@ static int __devinit au1000_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(struct au1000_private)); if (!dev) { - dev_err(&pdev->dev, "alloc_etherdev failed\n"); err = -ENOMEM; goto err_alloc; } diff --git a/drivers/net/ethernet/amd/declance.c b/drivers/net/ethernet/amd/declance.c index 73f8d4fa682..dd82ee2f8d2 100644 --- a/drivers/net/ethernet/amd/declance.c +++ b/drivers/net/ethernet/amd/declance.c @@ -1052,8 +1052,6 @@ static int __devinit dec_lance_probe(struct device *bdev, const int type) dev = alloc_etherdev(sizeof(struct lance_private)); if (!dev) { - printk(KERN_ERR "%s: Unable to allocate etherdev, aborting.\n", - name); ret = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/amd/pcnet32.c b/drivers/net/ethernet/amd/pcnet32.c index 20e6dab0186..1bb388f62e5 100644 --- a/drivers/net/ethernet/amd/pcnet32.c +++ b/drivers/net/ethernet/amd/pcnet32.c @@ -1649,8 +1649,6 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev) dev = alloc_etherdev(sizeof(*lp)); if (!dev) { - if (pcnet32_debug & NETIF_MSG_PROBE) - pr_err("Memory allocation failed\n"); ret = -ENOMEM; goto err_release_region; } diff --git a/drivers/net/ethernet/apple/bmac.c b/drivers/net/ethernet/apple/bmac.c index 4108ac800cf..ebc0dba5ba3 100644 --- a/drivers/net/ethernet/apple/bmac.c +++ b/drivers/net/ethernet/apple/bmac.c @@ -1269,10 +1269,8 @@ static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_i memcpy(addr, prop_addr, sizeof(addr)); dev = alloc_etherdev(PRIV_BYTES); - if (!dev) { - printk(KERN_ERR "BMAC: alloc_etherdev failed, out of memory\n"); + if (!dev) return -ENOMEM; - } bp = netdev_priv(dev); SET_NETDEV_DEV(dev, &mdev->ofdev.dev); diff --git a/drivers/net/ethernet/apple/mace.c b/drivers/net/ethernet/apple/mace.c index 45ba18ee3d6..bd5555dbe02 100644 --- a/drivers/net/ethernet/apple/mace.c +++ b/drivers/net/ethernet/apple/mace.c @@ -147,7 +147,6 @@ static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_i dev = alloc_etherdev(PRIV_BYTES); if (!dev) { - printk(KERN_ERR "MACE: can't allocate ethernet device !\n"); rc = -ENOMEM; goto err_release; } diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c index b8591246eb4..7ee4aacb01a 100644 --- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c +++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c @@ -2689,7 +2689,6 @@ static int __devinit atl1c_probe(struct pci_dev *pdev, netdev = alloc_etherdev(sizeof(struct atl1c_adapter)); if (netdev == NULL) { err = -ENOMEM; - dev_err(&pdev->dev, "etherdev alloc failed\n"); goto err_alloc_etherdev; } diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index c915c087381..93ff2b23128 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c @@ -2300,7 +2300,6 @@ static int __devinit atl1e_probe(struct pci_dev *pdev, netdev = alloc_etherdev(sizeof(struct atl1e_adapter)); if (netdev == NULL) { err = -ENOMEM; - dev_err(&pdev->dev, "etherdev alloc failed\n"); goto err_alloc_etherdev; } diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c index 3fb66d09ece..66f53c797e3 100644 --- a/drivers/net/ethernet/broadcom/b44.c +++ b/drivers/net/ethernet/broadcom/b44.c @@ -2138,7 +2138,6 @@ static int __devinit b44_init_one(struct ssb_device *sdev, dev = alloc_etherdev(sizeof(*bp)); if (!dev) { - dev_err(sdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 582cbcf5f9f..ff19c3cf440 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -11133,10 +11133,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev, /* dev zeroed in init_etherdev */ dev = alloc_etherdev_mqs(sizeof(*bp), tx_count, rx_count); - if (!dev) { - dev_err(&pdev->dev, "Cannot allocate net device\n"); + if (!dev) return -ENOMEM; - } bp = netdev_priv(dev); diff --git a/drivers/net/ethernet/broadcom/sb1250-mac.c b/drivers/net/ethernet/broadcom/sb1250-mac.c index 084904ceaa3..49e7a258da8 100644 --- a/drivers/net/ethernet/broadcom/sb1250-mac.c +++ b/drivers/net/ethernet/broadcom/sb1250-mac.c @@ -2623,8 +2623,6 @@ static int __devinit sbmac_probe(struct platform_device *pldev) */ dev = alloc_etherdev(sizeof(struct sbmac_softc)); if (!dev) { - printk(KERN_ERR "%s: unable to allocate etherdev\n", - dev_name(&pldev->dev)); err = -ENOMEM; goto out_unmap; } diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index a1f2e0fed78..3bf3adca369 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -15471,7 +15471,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, dev = alloc_etherdev_mq(sizeof(*tp), TG3_IRQ_MAX_VECS); if (!dev) { - dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_out_power_down; } diff --git a/drivers/net/ethernet/brocade/bna/bnad.c b/drivers/net/ethernet/brocade/bna/bnad.c index be7d91e4b78..ff78f770dec 100644 --- a/drivers/net/ethernet/brocade/bna/bnad.c +++ b/drivers/net/ethernet/brocade/bna/bnad.c @@ -3284,7 +3284,6 @@ bnad_pci_probe(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(struct bnad)); if (!netdev) { - dev_err(&pdev->dev, "netdev allocation failed\n"); err = -ENOMEM; return err; } diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 23200680d4c..3c315f46859 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1308,10 +1308,8 @@ static int __init macb_probe(struct platform_device *pdev) err = -ENOMEM; dev = alloc_etherdev(sizeof(*bp)); - if (!dev) { - dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); + if (!dev) goto err_out; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c index e53365a7148..9045a451d4a 100644 --- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c @@ -2596,8 +2596,6 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev, netdev = alloc_etherdev_mq(sizeof(struct port_info), MAX_PORT_QSETS); if (netdev == NULL) { - dev_err(&pdev->dev, "cannot allocate netdev for" - " port %d\n", port_id); t4vf_free_vi(adapter, viid); err = -ENOMEM; goto err_free_dev; diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c index 07df13745c4..2838891a94e 100644 --- a/drivers/net/ethernet/cisco/enic/enic_main.c +++ b/drivers/net/ethernet/cisco/enic/enic_main.c @@ -2280,10 +2280,8 @@ static int __devinit enic_probe(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(struct enic)); - if (!netdev) { - pr_err("Etherdev alloc failed, aborting\n"); + if (!netdev) return -ENOMEM; - } pci_set_drvdata(pdev, netdev); diff --git a/drivers/net/ethernet/davicom/dm9000.c b/drivers/net/ethernet/davicom/dm9000.c index f801754c71a..493cc620208 100644 --- a/drivers/net/ethernet/davicom/dm9000.c +++ b/drivers/net/ethernet/davicom/dm9000.c @@ -1373,10 +1373,8 @@ dm9000_probe(struct platform_device *pdev) /* Init network device */ ndev = alloc_etherdev(sizeof(struct board_info)); - if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); diff --git a/drivers/net/ethernet/dec/tulip/tulip_core.c b/drivers/net/ethernet/dec/tulip/tulip_core.c index 4eb0d76145c..17ecb18341c 100644 --- a/drivers/net/ethernet/dec/tulip/tulip_core.c +++ b/drivers/net/ethernet/dec/tulip/tulip_core.c @@ -1424,10 +1424,8 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, /* alloc_etherdev ensures aligned and zeroed private structures */ dev = alloc_etherdev (sizeof (*tp)); - if (!dev) { - pr_err("ether device alloc failed, aborting\n"); + if (!dev) return -ENOMEM; - } SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { diff --git a/drivers/net/ethernet/dec/tulip/xircom_cb.c b/drivers/net/ethernet/dec/tulip/xircom_cb.c index 988b8eb24d3..b7c73eefb54 100644 --- a/drivers/net/ethernet/dec/tulip/xircom_cb.c +++ b/drivers/net/ethernet/dec/tulip/xircom_cb.c @@ -222,10 +222,9 @@ static int __devinit xircom_probe(struct pci_dev *pdev, const struct pci_device_ is available. */ dev = alloc_etherdev(sizeof(struct xircom_private)); - if (!dev) { - pr_err("%s: failed to allocate etherdev\n", __func__); + if (!dev) goto device_fail; - } + private = netdev_priv(dev); /* Allocate the send/receive buffers */ diff --git a/drivers/net/ethernet/dnet.c b/drivers/net/ethernet/dnet.c index 925c9bafc9b..fe48cb7dde2 100644 --- a/drivers/net/ethernet/dnet.c +++ b/drivers/net/ethernet/dnet.c @@ -854,10 +854,8 @@ static int __devinit dnet_probe(struct platform_device *pdev) err = -ENOMEM; dev = alloc_etherdev(sizeof(*bp)); - if (!dev) { - dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n"); + if (!dev) goto err_out_release_mem; - } /* TODO: Actually, we have some interesting features... */ dev->features |= 0; diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c index 388c592b5ef..0b723ff2294 100644 --- a/drivers/net/ethernet/ethoc.c +++ b/drivers/net/ethernet/ethoc.c @@ -913,7 +913,6 @@ static int __devinit ethoc_probe(struct platform_device *pdev) /* allocate networking device */ netdev = alloc_etherdev(sizeof(struct ethoc)); if (!netdev) { - dev_err(&pdev->dev, "cannot allocate network device\n"); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/hp/hp100.c b/drivers/net/ethernet/hp/hp100.c index 6a5ee0776b2..3598c5408e7 100644 --- a/drivers/net/ethernet/hp/hp100.c +++ b/drivers/net/ethernet/hp/hp100.c @@ -2992,7 +2992,6 @@ static int __init hp100_isa_init(void) for (i = 0; i < HP100_DEVICES && hp100_port[i] != -1; ++i) { dev = alloc_etherdev(sizeof(struct hp100_private)); if (!dev) { - printk(KERN_WARNING "hp100: no memory for network device\n"); while (cards > 0) cleanup_dev(hp100_devlist[--cards]); diff --git a/drivers/net/ethernet/ibm/ehea/ehea_main.c b/drivers/net/ethernet/ibm/ehea/ehea_main.c index 14507d1e78c..8b73dd47247 100644 --- a/drivers/net/ethernet/ibm/ehea/ehea_main.c +++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c @@ -2980,7 +2980,6 @@ static struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, dev = alloc_etherdev_mq(sizeof(struct ehea_port), EHEA_MAX_PORT_RES); if (!dev) { - pr_err("no mem for net_device\n"); ret = -ENOMEM; goto out_err; } diff --git a/drivers/net/ethernet/ibm/emac/core.c b/drivers/net/ethernet/ibm/emac/core.c index d47c16e02d0..dac7ffb4eaf 100644 --- a/drivers/net/ethernet/ibm/emac/core.c +++ b/drivers/net/ethernet/ibm/emac/core.c @@ -2706,11 +2706,9 @@ static int __devinit emac_probe(struct platform_device *ofdev) /* Allocate our net_device structure */ err = -ENOMEM; ndev = alloc_etherdev(sizeof(struct emac_instance)); - if (!ndev) { - printk(KERN_ERR "%s: could not allocate ethernet device!\n", - np->full_name); + if (!ndev) goto err_gone; - } + dev = netdev_priv(ndev); dev->ndev = ndev; dev->ofdev = ofdev; diff --git a/drivers/net/ethernet/ibm/iseries_veth.c b/drivers/net/ethernet/ibm/iseries_veth.c index acc31af6594..1cafa6562a0 100644 --- a/drivers/net/ethernet/ibm/iseries_veth.c +++ b/drivers/net/ethernet/ibm/iseries_veth.c @@ -1032,10 +1032,8 @@ static struct net_device *veth_probe_one(int vlan, } dev = alloc_etherdev(sizeof (struct veth_port)); - if (! dev) { - veth_error("Unable to allocate net_device structure!\n"); + if (!dev) return NULL; - } port = netdev_priv(dev); diff --git a/drivers/net/ethernet/icplus/ipg.c b/drivers/net/ethernet/icplus/ipg.c index 075451d0207..3c636f16a3c 100644 --- a/drivers/net/ethernet/icplus/ipg.c +++ b/drivers/net/ethernet/icplus/ipg.c @@ -2233,7 +2233,6 @@ static int __devinit ipg_probe(struct pci_dev *pdev, */ dev = alloc_etherdev(sizeof(struct ipg_nic_private)); if (!dev) { - pr_err("%s: alloc_etherdev failed\n", pci_name(pdev)); rc = -ENOMEM; goto err_disable_0; } diff --git a/drivers/net/ethernet/intel/e100.c b/drivers/net/ethernet/intel/e100.c index 9436397e572..485ab8cdac4 100644 --- a/drivers/net/ethernet/intel/e100.c +++ b/drivers/net/ethernet/intel/e100.c @@ -2751,11 +2751,8 @@ static int __devinit e100_probe(struct pci_dev *pdev, struct nic *nic; int err; - if (!(netdev = alloc_etherdev(sizeof(struct nic)))) { - if (((1 << debug) - 1) & NETIF_MSG_PROBE) - pr_err("Etherdev alloc failed, aborting\n"); + if (!(netdev = alloc_etherdev(sizeof(struct nic)))) return -ENOMEM; - } netdev->netdev_ops = &e100_netdev_ops; SET_ETHTOOL_OPS(netdev, &e100_ethtool_ops); diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c index 27d651a80f3..1b86d0b45f3 100644 --- a/drivers/net/ethernet/jme.c +++ b/drivers/net/ethernet/jme.c @@ -2999,7 +2999,6 @@ jme_init_one(struct pci_dev *pdev, */ netdev = alloc_etherdev(sizeof(*jme)); if (!netdev) { - pr_err("Cannot allocate netdev structure\n"); rc = -ENOMEM; goto err_out_release_regions; } diff --git a/drivers/net/ethernet/korina.c b/drivers/net/ethernet/korina.c index 341d10130dc..f30db1c4660 100644 --- a/drivers/net/ethernet/korina.c +++ b/drivers/net/ethernet/korina.c @@ -1108,10 +1108,9 @@ static int korina_probe(struct platform_device *pdev) int rc; dev = alloc_etherdev(sizeof(struct korina_private)); - if (!dev) { - printk(KERN_ERR DRV_NAME ": alloc_etherdev failed\n"); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); diff --git a/drivers/net/ethernet/lantiq_etop.c b/drivers/net/ethernet/lantiq_etop.c index 85e2c6cd970..86d2fe6e053 100644 --- a/drivers/net/ethernet/lantiq_etop.c +++ b/drivers/net/ethernet/lantiq_etop.c @@ -731,6 +731,10 @@ ltq_etop_probe(struct platform_device *pdev) } dev = alloc_etherdev_mq(sizeof(struct ltq_etop_priv), 4); + if (!dev) { + err = -ENOMEM; + goto err_out; + } strcpy(dev->name, "eth%d"); dev->netdev_ops = <q_eth_netdev_ops; dev->ethtool_ops = <q_etop_ethtool_ops; diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index edb9bda55d5..1d61eaac858 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -3852,10 +3852,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, struct skge_port *skge; struct net_device *dev = alloc_etherdev(sizeof(*skge)); - if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->netdev_ops = &skge_netdev_ops; diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 760c2b17dfd..82c2c86a195 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -4700,10 +4700,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, struct sky2_port *sky2; struct net_device *dev = alloc_etherdev(sizeof(*sky2)); - if (!dev) { - dev_err(&hw->pdev->dev, "etherdev alloc failed\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, &hw->pdev->dev); dev->irq = hw->pdev->irq; diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c index 467ae582487..25e6480479d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1047,10 +1047,8 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, dev = alloc_etherdev_mqs(sizeof(struct mlx4_en_priv), prof->tx_ring_num, prof->rx_ring_num); - if (dev == NULL) { - mlx4_err(mdev, "Net device allocation failed\n"); + if (dev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(dev, &mdev->dev->pdev->dev); dev->dev_id = port - 1; diff --git a/drivers/net/ethernet/micrel/ks8695net.c b/drivers/net/ethernet/micrel/ks8695net.c index ab81c0dc96e..7c717276502 100644 --- a/drivers/net/ethernet/micrel/ks8695net.c +++ b/drivers/net/ethernet/micrel/ks8695net.c @@ -1362,10 +1362,8 @@ ks8695_probe(struct platform_device *pdev) /* Initialise a net_device */ ndev = alloc_etherdev(sizeof(struct ks8695_priv)); - if (!ndev) { - dev_err(&pdev->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } SET_NETDEV_DEV(ndev, &pdev->dev); diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 134c4d07936..4b551feae4c 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -1419,10 +1419,8 @@ static int __devinit ks8851_probe(struct spi_device *spi) int ret; ndev = alloc_etherdev(sizeof(struct ks8851_net)); - if (!ndev) { - dev_err(&spi->dev, "failed to alloc ethernet device\n"); + if (!ndev) return -ENOMEM; - } spi->bits_per_word = 8; diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index 50055e0282e..c813e5d8db9 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c @@ -1553,9 +1553,6 @@ static int __devinit enc28j60_probe(struct spi_device *spi) dev = alloc_etherdev(sizeof(struct enc28j60_net)); if (!dev) { - if (netif_msg_drv(&debug)) - dev_err(&spi->dev, DRV_NAME - ": unable to alloc new ethernet\n"); ret = -ENOMEM; goto error_alloc; } diff --git a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c index 20b72ecb020..27273ae1a6e 100644 --- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c @@ -3910,10 +3910,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) static int board_number; netdev = alloc_etherdev_mq(sizeof(*mgp), MYRI10GE_MAX_SLICES); - if (netdev == NULL) { - dev_err(dev, "Could not allocate ethernet device\n"); + if (netdev == NULL) return -ENOMEM; - } SET_NETDEV_DEV(netdev, &pdev->dev); diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 97f63e12d86..13858460880 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -7760,7 +7760,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) else dev = alloc_etherdev(sizeof(struct s2io_nic)); if (dev == NULL) { - DBG_PRINT(ERR_DBG, "Device allocation failed\n"); pci_disable_device(pdev); pci_release_regions(pdev); return -ENODEV; diff --git a/drivers/net/ethernet/netx-eth.c b/drivers/net/ethernet/netx-eth.c index a18bb10b4f0..5a12276f810 100644 --- a/drivers/net/ethernet/netx-eth.c +++ b/drivers/net/ethernet/netx-eth.c @@ -383,7 +383,6 @@ static int netx_eth_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof (struct netx_eth_priv)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto exit; } diff --git a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c index 0217991fede..bdbec7e04a4 100644 --- a/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c +++ b/drivers/net/ethernet/oki-semi/pch_gbe/pch_gbe_main.c @@ -2419,8 +2419,6 @@ static int pch_gbe_probe(struct pci_dev *pdev, netdev = alloc_etherdev((int)sizeof(struct pch_gbe_adapter)); if (!netdev) { ret = -ENOMEM; - dev_err(&pdev->dev, - "ERR: Can't allocate and set up an Ethernet device\n"); goto err_release_pci; } SET_NETDEV_DEV(netdev, &pdev->dev); diff --git a/drivers/net/ethernet/packetengines/yellowfin.c b/drivers/net/ethernet/packetengines/yellowfin.c index db44e9af03c..4a5774271bd 100644 --- a/drivers/net/ethernet/packetengines/yellowfin.c +++ b/drivers/net/ethernet/packetengines/yellowfin.c @@ -397,10 +397,9 @@ static int __devinit yellowfin_init_one(struct pci_dev *pdev, if (i) return i; dev = alloc_etherdev(sizeof(*np)); - if (!dev) { - pr_err("cannot allocate ethernet device\n"); + if (!dev) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); np = netdev_priv(dev); diff --git a/drivers/net/ethernet/pasemi/pasemi_mac.c b/drivers/net/ethernet/pasemi/pasemi_mac.c index 49b549ff2c7..3bb725ed270 100644 --- a/drivers/net/ethernet/pasemi/pasemi_mac.c +++ b/drivers/net/ethernet/pasemi/pasemi_mac.c @@ -1740,8 +1740,6 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof(struct pasemi_mac)); if (dev == NULL) { - dev_err(&pdev->dev, - "pasemi_mac: Could not allocate ethernet device.\n"); err = -ENOMEM; goto out_disable_device; } diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c index 7dd9a4b107e..64aa44d5dab 100644 --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c @@ -1403,7 +1403,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev = alloc_etherdev(sizeof(struct netxen_adapter)); if(!netdev) { - dev_err(&pdev->dev, "failed to allocate net_device\n"); err = -ENOMEM; goto err_out_free_res; } diff --git a/drivers/net/ethernet/qlogic/qla3xxx.c b/drivers/net/ethernet/qlogic/qla3xxx.c index 7931531c3a4..d49f6dac51f 100644 --- a/drivers/net/ethernet/qlogic/qla3xxx.c +++ b/drivers/net/ethernet/qlogic/qla3xxx.c @@ -3805,7 +3805,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev, ndev = alloc_etherdev(sizeof(struct ql3_adapter)); if (!ndev) { - pr_err("%s could not alloc etherdev\n", pci_name(pdev)); err = -ENOMEM; goto err_out_free_regions; } diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index 69b8e4ef14d..7bfdf57f4b7 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c @@ -1576,7 +1576,6 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) netdev = alloc_etherdev(sizeof(struct qlcnic_adapter)); if (!netdev) { - dev_err(&pdev->dev, "failed to allocate net_device\n"); err = -ENOMEM; goto err_out_free_res; } diff --git a/drivers/net/ethernet/rdc/r6040.c b/drivers/net/ethernet/rdc/r6040.c index cb0eca80785..76cab284876 100644 --- a/drivers/net/ethernet/rdc/r6040.c +++ b/drivers/net/ethernet/rdc/r6040.c @@ -1107,7 +1107,6 @@ static int __devinit r6040_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct r6040_private)); if (!dev) { - dev_err(&pdev->dev, "Failed to allocate etherdev\n"); err = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/realtek/8139too.c b/drivers/net/ethernet/realtek/8139too.c index a8779bedb3d..1c3feb0116b 100644 --- a/drivers/net/ethernet/realtek/8139too.c +++ b/drivers/net/ethernet/realtek/8139too.c @@ -754,10 +754,9 @@ static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev) /* dev and priv zeroed in alloc_etherdev */ dev = alloc_etherdev (sizeof (*tp)); - if (dev == NULL) { - dev_err(&pdev->dev, "Unable to alloc new net device\n"); + if (dev == NULL) return ERR_PTR(-ENOMEM); - } + SET_NETDEV_DEV(dev, &pdev->dev); tp = netdev_priv(dev); diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 707742207c7..5eb6858ed0a 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -4008,8 +4008,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev = alloc_etherdev(sizeof (*tp)); if (!dev) { - if (netif_msg_drv(&debug)) - dev_err(&pdev->dev, "unable to alloc new ethernet\n"); rc = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 813d41c4a84..1cb5a34d577 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1792,7 +1792,6 @@ static int sh_eth_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct sh_eth_private)); if (!ndev) { - dev_err(&pdev->dev, "Could not allocate device.\n"); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/s6gmac.c b/drivers/net/ethernet/s6gmac.c index 22e9c0181ce..bee97033167 100644 --- a/drivers/net/ethernet/s6gmac.c +++ b/drivers/net/ethernet/s6gmac.c @@ -960,11 +960,11 @@ static int __devinit s6gmac_probe(struct platform_device *pdev) int res; unsigned long i; struct mii_bus *mb; + dev = alloc_etherdev(sizeof(*pd)); - if (!dev) { - printk(KERN_ERR DRV_PRMT "etherdev alloc failed, aborting.\n"); + if (!dev) return -ENOMEM; - } + dev->open = s6gmac_open; dev->stop = s6gmac_stop; dev->hard_start_xmit = s6gmac_tx; diff --git a/drivers/net/ethernet/seeq/sgiseeq.c b/drivers/net/ethernet/seeq/sgiseeq.c index f955a19eb22..bb8c8222122 100644 --- a/drivers/net/ethernet/seeq/sgiseeq.c +++ b/drivers/net/ethernet/seeq/sgiseeq.c @@ -733,7 +733,6 @@ static int __devinit sgiseeq_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof (struct sgiseeq_private)); if (!dev) { - printk(KERN_ERR "Sgiseeq: Etherdev alloc failed, aborting.\n"); err = -ENOMEM; goto err_out; } diff --git a/drivers/net/ethernet/sis/sis190.c b/drivers/net/ethernet/sis/sis190.c index 5b118cd5bf9..a9deda8eaf6 100644 --- a/drivers/net/ethernet/sis/sis190.c +++ b/drivers/net/ethernet/sis/sis190.c @@ -1462,8 +1462,6 @@ static struct net_device * __devinit sis190_init_board(struct pci_dev *pdev) dev = alloc_etherdev(sizeof(*tp)); if (!dev) { - if (netif_msg_drv(&debug)) - pr_err("unable to alloc new ethernet\n"); rc = -ENOMEM; goto err_out_0; } diff --git a/drivers/net/ethernet/smsc/epic100.c b/drivers/net/ethernet/smsc/epic100.c index 2c077ce0b6d..11dcb38b99f 100644 --- a/drivers/net/ethernet/smsc/epic100.c +++ b/drivers/net/ethernet/smsc/epic100.c @@ -363,10 +363,9 @@ static int __devinit epic_init_one (struct pci_dev *pdev, ret = -ENOMEM; dev = alloc_etherdev(sizeof (*ep)); - if (!dev) { - dev_err(&pdev->dev, "no memory for eth device\n"); + if (!dev) goto err_out_free_res; - } + SET_NETDEV_DEV(dev, &pdev->dev); #ifdef USE_IO_OPS diff --git a/drivers/net/ethernet/smsc/smc911x.c b/drivers/net/ethernet/smsc/smc911x.c index 313ba3b32ab..c28230148ef 100644 --- a/drivers/net/ethernet/smsc/smc911x.c +++ b/drivers/net/ethernet/smsc/smc911x.c @@ -2065,7 +2065,6 @@ static int __devinit smc911x_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct smc911x_local)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto release_1; } diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index 64ad3ed7449..24104a1ee6a 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c @@ -2223,7 +2223,6 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct smc_local)); if (!ndev) { - printk("%s: could not allocate device.\n", CARDNAME); ret = -ENOMEM; goto out; } diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c index 24d2df068d7..6a1cd236081 100644 --- a/drivers/net/ethernet/smsc/smsc911x.c +++ b/drivers/net/ethernet/smsc/smsc911x.c @@ -2374,7 +2374,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev) dev = alloc_etherdev(sizeof(struct smsc911x_data)); if (!dev) { - pr_warn("Could not allocate device\n"); retval = -ENOMEM; goto out_release_io_1; } diff --git a/drivers/net/ethernet/smsc/smsc9420.c b/drivers/net/ethernet/smsc/smsc9420.c index a9efbdfe530..595f9881e09 100644 --- a/drivers/net/ethernet/smsc/smsc9420.c +++ b/drivers/net/ethernet/smsc/smsc9420.c @@ -1598,10 +1598,8 @@ smsc9420_probe(struct pci_dev *pdev, const struct pci_device_id *id) pci_set_master(pdev); dev = alloc_etherdev(sizeof(*pd)); - if (!dev) { - printk(KERN_ERR "ether device alloc failed\n"); + if (!dev) goto out_disable_pci_device_1; - } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index ffc7581879b..166fc95e5ba 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1801,10 +1801,8 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, struct stmmac_priv *priv; ndev = alloc_etherdev(sizeof(struct stmmac_priv)); - if (!ndev) { - pr_err("%s: ERROR: allocating the device\n", __func__); + if (!ndev) return NULL; - } SET_NETDEV_DEV(ndev, device); diff --git a/drivers/net/ethernet/sun/cassini.c b/drivers/net/ethernet/sun/cassini.c index 46d84abe553..45292760fce 100644 --- a/drivers/net/ethernet/sun/cassini.c +++ b/drivers/net/ethernet/sun/cassini.c @@ -4946,7 +4946,6 @@ static int __devinit cas_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*cp)); if (!dev) { - dev_err(&pdev->dev, "Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_out_disable_pdev; } diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index cf433931304..d83c5081671 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9685,10 +9685,8 @@ static struct net_device * __devinit niu_alloc_and_init( struct niu *np; dev = alloc_etherdev_mq(sizeof(struct niu), NIU_NUM_TXCHAN); - if (!dev) { - dev_err(gen_dev, "Etherdev alloc failed, aborting\n"); + if (!dev) return NULL; - } SET_NETDEV_DEV(dev, gen_dev); diff --git a/drivers/net/ethernet/sun/sungem.c b/drivers/net/ethernet/sun/sungem.c index 31441a870b0..ba041596e04 100644 --- a/drivers/net/ethernet/sun/sungem.c +++ b/drivers/net/ethernet/sun/sungem.c @@ -2885,7 +2885,6 @@ static int __devinit gem_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(*gp)); if (!dev) { - pr_err("Etherdev alloc failed, aborting\n"); err = -ENOMEM; goto err_disable_device; } diff --git a/drivers/net/ethernet/sun/sunvnet.c b/drivers/net/ethernet/sun/sunvnet.c index 2896f6e9672..92a037a8228 100644 --- a/drivers/net/ethernet/sun/sunvnet.c +++ b/drivers/net/ethernet/sun/sunvnet.c @@ -1026,10 +1026,8 @@ static struct vnet * __devinit vnet_new(const u64 *local_mac) int err, i; dev = alloc_etherdev(sizeof(*vp)); - if (!dev) { - pr_err("Etherdev alloc failed, aborting\n"); + if (!dev) return ERR_PTR(-ENOMEM); - } for (i = 0; i < ETH_ALEN; i++) dev->dev_addr[i] = (*local_mac >> (5 - i) * 8) & 0xff; diff --git a/drivers/net/ethernet/tehuti/tehuti.c b/drivers/net/ethernet/tehuti/tehuti.c index 4b19e9b0606..df7febba9ea 100644 --- a/drivers/net/ethernet/tehuti/tehuti.c +++ b/drivers/net/ethernet/tehuti/tehuti.c @@ -1978,7 +1978,6 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ndev = alloc_etherdev(sizeof(struct bdx_priv)); if (!ndev) { err = -ENOMEM; - pr_err("alloc_etherdev failed\n"); goto err_out_iomap; } diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c index 4d9a28ffd3c..97e1df330a1 100644 --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c @@ -1143,11 +1143,8 @@ static int __devinit cpmac_probe(struct platform_device *pdev) } dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES); - - if (!dev) { - printk(KERN_ERR "cpmac: Unable to allocate net_device\n"); + if (!dev) return -ENOMEM; - } platform_set_drvdata(pdev, dev); priv = netdev_priv(dev); diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c index 794ac30a577..efd4f3ee1a2 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1789,7 +1789,6 @@ static int __devinit davinci_emac_probe(struct platform_device *pdev) ndev = alloc_etherdev(sizeof(struct emac_priv)); if (!ndev) { - dev_err(&pdev->dev, "error allocating net_device\n"); rc = -ENOMEM; goto free_clk; } diff --git a/drivers/net/ethernet/ti/tlan.c b/drivers/net/ethernet/ti/tlan.c index 9c0dd6b8d6c..817ad3bc495 100644 --- a/drivers/net/ethernet/ti/tlan.c +++ b/drivers/net/ethernet/ti/tlan.c @@ -486,7 +486,6 @@ static int __devinit tlan_probe1(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct tlan_priv)); if (dev == NULL) { - pr_err("Could not allocate memory for device\n"); rc = -ENOMEM; goto err_out_regions; } diff --git a/drivers/net/ethernet/toshiba/tc35815.c b/drivers/net/ethernet/toshiba/tc35815.c index 71b785cd756..f5ac603d560 100644 --- a/drivers/net/ethernet/toshiba/tc35815.c +++ b/drivers/net/ethernet/toshiba/tc35815.c @@ -808,10 +808,9 @@ static int __devinit tc35815_init_one(struct pci_dev *pdev, /* dev zeroed in alloc_etherdev */ dev = alloc_etherdev(sizeof(*lp)); - if (dev == NULL) { - dev_err(&pdev->dev, "unable to alloc new ethernet\n"); + if (dev == NULL) return -ENOMEM; - } + SET_NETDEV_DEV(dev, &pdev->dev); lp = netdev_priv(dev); lp->dev = dev; diff --git a/drivers/net/ethernet/tundra/tsi108_eth.c b/drivers/net/ethernet/tundra/tsi108_eth.c index 164fb775d7b..fc5521c9c08 100644 --- a/drivers/net/ethernet/tundra/tsi108_eth.c +++ b/drivers/net/ethernet/tundra/tsi108_eth.c @@ -1582,10 +1582,8 @@ tsi108_init_one(struct platform_device *pdev) /* Create an ethernet device instance */ dev = alloc_etherdev(sizeof(struct tsi108_prv_data)); - if (!dev) { - printk("tsi108_eth: Could not allocate a device structure\n"); + if (!dev) return -ENOMEM; - } printk("tsi108_eth%d: probe...\n", pdev->id); data = netdev_priv(dev); diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c index 10b18eb63d2..1b95daa372c 100644 --- a/drivers/net/ethernet/via/via-rhine.c +++ b/drivers/net/ethernet/via/via-rhine.c @@ -927,7 +927,6 @@ static int __devinit rhine_init_one(struct pci_dev *pdev, dev = alloc_etherdev(sizeof(struct rhine_private)); if (!dev) { rc = -ENOMEM; - dev_err(&pdev->dev, "alloc_etherdev failed\n"); goto err_out; } SET_NETDEV_DEV(dev, &pdev->dev); diff --git a/drivers/net/ethernet/via/via-velocity.c b/drivers/net/ethernet/via/via-velocity.c index 4128d6b8cc2..2776bbc6793 100644 --- a/drivers/net/ethernet/via/via-velocity.c +++ b/drivers/net/ethernet/via/via-velocity.c @@ -2733,10 +2733,8 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi } dev = alloc_etherdev(sizeof(struct velocity_info)); - if (!dev) { - dev_err(&pdev->dev, "allocate net device failed.\n"); + if (!dev) goto out; - } /* Chain it all together */ diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c index f21addb1db9..d8eb9c9e3ee 100644 --- a/drivers/net/ethernet/xilinx/ll_temac_main.c +++ b/drivers/net/ethernet/xilinx/ll_temac_main.c @@ -1011,10 +1011,9 @@ static int __devinit temac_of_probe(struct platform_device *op) /* Init network device structure */ ndev = alloc_etherdev(sizeof(*lp)); - if (!ndev) { - dev_err(&op->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } + ether_setup(ndev); dev_set_drvdata(&op->dev, ndev); SET_NETDEV_DEV(ndev, &op->dev); diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c index ea50caf8925..a7cf00438a3 100644 --- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c +++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c @@ -1486,10 +1486,8 @@ static int __devinit axienet_of_probe(struct platform_device *op) const void *addr; ndev = alloc_etherdev(sizeof(*lp)); - if (!ndev) { - dev_err(&op->dev, "could not allocate device.\n"); + if (!ndev) return -ENOMEM; - } ether_setup(ndev); dev_set_drvdata(&op->dev, ndev); diff --git a/drivers/net/ethernet/xilinx/xilinx_emaclite.c b/drivers/net/ethernet/xilinx/xilinx_emaclite.c index 79013e5731a..90e611a6f6c 100644 --- a/drivers/net/ethernet/xilinx/xilinx_emaclite.c +++ b/drivers/net/ethernet/xilinx/xilinx_emaclite.c @@ -1136,10 +1136,8 @@ static int __devinit xemaclite_of_probe(struct platform_device *ofdev) /* Create an ethernet device instance */ ndev = alloc_etherdev(sizeof(struct net_local)); - if (!ndev) { - dev_err(dev, "Could not allocate network device\n"); + if (!ndev) return -ENOMEM; - } dev_set_drvdata(dev, ndev); SET_NETDEV_DEV(ndev, &ofdev->dev); diff --git a/drivers/net/plip/plip.c b/drivers/net/plip/plip.c index a9e9ca8a86e..1a5a316cc96 100644 --- a/drivers/net/plip/plip.c +++ b/drivers/net/plip/plip.c @@ -1260,10 +1260,8 @@ static void plip_attach (struct parport *port) sprintf(name, "plip%d", unit); dev = alloc_etherdev(sizeof(struct net_local)); - if (!dev) { - printk(KERN_ERR "plip: memory squeeze\n"); + if (!dev) return; - } strcpy(dev->name, name); diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 7145714a5ec..a57f05726b5 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -497,8 +497,6 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) /* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); if (ndev == NULL) { - printk(KERN_INFO "%s: could not allocate ethernet device.\n", - DRV_NAME); rc = -ENOMEM; goto out; } diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c index 5d99b8cacd7..75239309232 100644 --- a/drivers/net/usb/pegasus.c +++ b/drivers/net/usb/pegasus.c @@ -1332,10 +1332,8 @@ static int pegasus_probe(struct usb_interface *intf, usb_get_dev(dev); net = alloc_etherdev(sizeof(struct pegasus)); - if (!net) { - dev_err(&intf->dev, "can't allocate %s\n", "device"); + if (!net) goto out; - } pegasus = netdev_priv(net); pegasus->dev_index = dev_index; diff --git a/drivers/net/usb/rtl8150.c b/drivers/net/usb/rtl8150.c index 0710b4ca925..6dda2fe5b15 100644 --- a/drivers/net/usb/rtl8150.c +++ b/drivers/net/usb/rtl8150.c @@ -894,10 +894,8 @@ static int rtl8150_probe(struct usb_interface *intf, struct net_device *netdev; netdev = alloc_etherdev(sizeof(rtl8150_t)); - if (!netdev) { - err("Out of memory"); + if (!netdev) return -ENOMEM; - } dev = netdev_priv(netdev); diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index fae0fbd8bc8..b924f46c963 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c @@ -1334,10 +1334,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) // set up our own records net = alloc_etherdev(sizeof(*dev)); - if (!net) { - dbg ("can't kmalloc dev"); + if (!net) goto out; - } /* netdev_printk() needs this so do it as early as possible */ SET_NETDEV_DEV(net, &udev->dev); diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 87c0b586f11..482cfa891f8 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2918,11 +2918,8 @@ vmxnet3_probe_device(struct pci_dev *pdev, printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", num_tx_queues, num_rx_queues); - if (!netdev) { - printk(KERN_ERR "Failed to alloc ethernet device for adapter " - "%s\n", pci_name(pdev)); + if (!netdev) return -ENOMEM; - } pci_set_drvdata(pdev, netdev); adapter = netdev_priv(netdev); diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 7e45ca2e78e..3010cee7b95 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c @@ -1533,10 +1533,9 @@ struct net_device *init_atmel_card(unsigned short irq, unsigned long port, /* Create the network device object. */ dev = alloc_etherdev(sizeof(*priv)); - if (!dev) { - printk(KERN_ERR "atmel: Couldn't alloc_etherdev\n"); + if (!dev) return NULL; - } + if (dev_alloc_name(dev, dev->name) < 0) { printk(KERN_ERR "atmel: Couldn't get name!\n"); goto err_out_free; diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c index d5ef696298e..3adb24021a2 100644 --- a/drivers/net/wireless/ipw2x00/libipw_module.c +++ b/drivers/net/wireless/ipw2x00/libipw_module.c @@ -150,10 +150,9 @@ struct net_device *alloc_libipw(int sizeof_priv, int monitor) LIBIPW_DEBUG_INFO("Initializing...\n"); dev = alloc_etherdev(sizeof(struct libipw_device) + sizeof_priv); - if (!dev) { - LIBIPW_ERROR("Unable to allocate network device.\n"); + if (!dev) goto failed; - } + ieee = netdev_priv(dev); ieee->dev = dev; diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index db638b4454e..168102e6ff6 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -1279,11 +1279,8 @@ static struct net_device * __devinit xennet_create_dev(struct xenbus_device *dev struct netfront_info *np; netdev = alloc_etherdev(sizeof(struct netfront_info)); - if (!netdev) { - printk(KERN_WARNING "%s> alloc_etherdev failed.\n", - __func__); + if (!netdev) return ERR_PTR(-ENOMEM); - } np = netdev_priv(netdev); np->xbdev = dev; -- cgit v1.2.3-70-g09d2 From 6c2abcdd4f8e21ce686a26697de0ce198a16eaed Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 31 Jan 2012 14:19:00 +0200 Subject: usb: musb: debugfs: fix error check debugfs will return NULL on failure, so we must check for !ptr instead of IS_ERR(ptr). Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_debugfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_debugfs.c b/drivers/usb/musb/musb_debugfs.c index 219d0fba584..40a37c91cc1 100644 --- a/drivers/usb/musb/musb_debugfs.c +++ b/drivers/usb/musb/musb_debugfs.c @@ -242,22 +242,22 @@ int __devinit musb_init_debugfs(struct musb *musb) int ret; root = debugfs_create_dir("musb", NULL); - if (IS_ERR(root)) { - ret = PTR_ERR(root); + if (!root) { + ret = -ENOMEM; goto err0; } file = debugfs_create_file("regdump", S_IRUGO, root, musb, &musb_regdump_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } file = debugfs_create_file("testmode", S_IRUGO | S_IWUSR, root, musb, &musb_test_mode_fops); - if (IS_ERR(file)) { - ret = PTR_ERR(file); + if (!file) { + ret = -ENOMEM; goto err1; } -- cgit v1.2.3-70-g09d2 From ef5ca193ca9ecbcfa41c0d258c4f4c344c157202 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 15 Nov 2011 14:48:06 +0800 Subject: serial: imx: add clk_prepare/clk_unprepare It's for migrating to generic clk framework API. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- drivers/tty/serial/imx.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 0b7fed746b2..e7feceeebc2 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -1508,7 +1508,7 @@ static int serial_imx_probe(struct platform_device *pdev) ret = PTR_ERR(sport->clk); goto unmap; } - clk_enable(sport->clk); + clk_prepare_enable(sport->clk); sport->port.uartclk = clk_get_rate(sport->clk); @@ -1531,8 +1531,8 @@ deinit: if (pdata && pdata->exit) pdata->exit(pdev); clkput: + clk_disable_unprepare(sport->clk); clk_put(sport->clk); - clk_disable(sport->clk); unmap: iounmap(sport->port.membase); free: @@ -1552,11 +1552,10 @@ static int serial_imx_remove(struct platform_device *pdev) if (sport) { uart_remove_one_port(&imx_reg, &sport->port); + clk_disable_unprepare(sport->clk); clk_put(sport->clk); } - clk_disable(sport->clk); - if (pdata && pdata->exit) pdata->exit(pdev); -- cgit v1.2.3-70-g09d2 From 83914337d117ac6537c2fff6c32e2c3a9810f7d4 Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 15 Nov 2011 14:48:08 +0800 Subject: i2c: imx: add clk_prepare/clk_unprepare It's for migrating to generic clk framework API. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- drivers/i2c/busses/i2c-imx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index 58832e578ff..8d1ab6fa88e 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -196,7 +196,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx) dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__); - clk_enable(i2c_imx->clk); + clk_prepare_enable(i2c_imx->clk); writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR); /* Enable I2C controller */ writeb(0, i2c_imx->base + IMX_I2C_I2SR); @@ -245,7 +245,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx) /* Disable I2C controller */ writeb(0, i2c_imx->base + IMX_I2C_I2CR); - clk_disable(i2c_imx->clk); + clk_disable_unprepare(i2c_imx->clk); } static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx, -- cgit v1.2.3-70-g09d2 From 5ef97faa31ccf34d6fef0964aea3c924f9d534fe Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Tue, 15 Nov 2011 14:48:09 +0800 Subject: mmc: sdhci-esdhc-imx: add clk_prepare/clk_unprepare It's for migrating to generic clk framework API. Signed-off-by: Richard Zhao Signed-off-by: Sascha Hauer --- drivers/mmc/host/sdhci-esdhc-imx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c index d601e41af28..f4e82d45caf 100644 --- a/drivers/mmc/host/sdhci-esdhc-imx.c +++ b/drivers/mmc/host/sdhci-esdhc-imx.c @@ -463,7 +463,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev) err = PTR_ERR(clk); goto err_clk_get; } - clk_enable(clk); + clk_prepare_enable(clk); pltfm_host->clk = clk; if (!is_imx25_esdhc(imx_data)) @@ -558,7 +558,7 @@ no_card_detect_irq: gpio_free(boarddata->wp_gpio); no_card_detect_pin: no_board_data: - clk_disable(pltfm_host->clk); + clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); err_clk_get: kfree(imx_data); @@ -585,7 +585,7 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev) gpio_free(boarddata->cd_gpio); } - clk_disable(pltfm_host->clk); + clk_disable_unprepare(pltfm_host->clk); clk_put(pltfm_host->clk); kfree(imx_data); -- cgit v1.2.3-70-g09d2 From e9460a9e811dddd9ea1ae9838d9b53bfaf78cd2c Mon Sep 17 00:00:00 2001 From: Jaccon Bastiaansen Date: Thu, 26 Jan 2012 21:46:15 +0100 Subject: CS89x0 : add platform driver support The CS89x0 ethernet controller is used on a number of evaluation boards, such as the MX31ADS. The current driver has memory address and IRQ settings for each board on which this controller is used. Driver updates are therefore required to support other boards that also use the CS89x0. To avoid these driver updates, a better mechanism (platform driver support) is added to communicate the board dependent settings to the driver. Signed-off-by: Jaccon Bastiaansen Acked-by: David S. Miller Signed-off-by: Sascha Hauer --- drivers/net/Space.c | 2 + drivers/net/ethernet/cirrus/Kconfig | 19 +++-- drivers/net/ethernet/cirrus/cs89x0.c | 137 +++++++++++++++++++++++++++++++---- 3 files changed, 137 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 068c3563e00..88bbd8ffa7f 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -190,8 +190,10 @@ static struct devprobe2 isa_probes[] __initdata = { {seeq8005_probe, 0}, #endif #ifdef CONFIG_CS89x0 +#ifndef CONFIG_CS89x0_PLATFORM {cs89x0_probe, 0}, #endif +#endif #ifdef CONFIG_AT1700 {at1700_probe, 0}, #endif diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig index 1f8648f099c..8388e36cf08 100644 --- a/drivers/net/ethernet/cirrus/Kconfig +++ b/drivers/net/ethernet/cirrus/Kconfig @@ -5,8 +5,7 @@ config NET_VENDOR_CIRRUS bool "Cirrus devices" default y - depends on ISA || EISA || MACH_IXDP2351 || ARCH_IXDP2X01 \ - || MACH_MX31ADS || MACH_QQ2440 || (ARM && ARCH_EP93XX) || MAC + depends on ISA || EISA || ARM || MAC ---help--- If you have a network (Ethernet) card belonging to this class, say Y and read the Ethernet-HOWTO, available from @@ -21,8 +20,7 @@ if NET_VENDOR_CIRRUS config CS89x0 tristate "CS89x0 support" - depends on (ISA || EISA || MACH_IXDP2351 \ - || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440) + depends on ISA || EISA || ARM ---help--- Support for CS89x0 chipset based Ethernet cards. If you have a network (Ethernet) card of this type, say Y and read the @@ -33,10 +31,15 @@ config CS89x0 To compile this driver as a module, choose M here. The module will be called cs89x0. -config CS89x0_NONISA_IRQ - def_bool y - depends on CS89x0 != n - depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440 +config CS89x0_PLATFORM + bool "CS89x0 platform driver support" + depends on CS89x0 + help + Say Y to compile the cs89x0 driver as a platform driver. This + makes this driver suitable for use on certain evaluation boards + such as the iMX21ADS. + + If you are unsure, say N. config EP93XX_ETH tristate "EP93xx Ethernet support" diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index f328da24c8f..6b3cd24eb45 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -100,9 +100,6 @@ */ -/* Always include 'config.h' first in case the user wants to turn on - or override something. */ -#include /* * Set this to zero to disable DMA code @@ -131,9 +128,12 @@ */ +#include +#include #include #include #include +#include #include #include #include @@ -151,6 +151,7 @@ #include #include #include +#include #if ALLOW_DMA #include #endif @@ -174,26 +175,32 @@ static char version[] __initdata = them to system IRQ numbers. This mapping is card specific and is set to the configuration of the Cirrus Eval board for this chip. */ #if defined(CONFIG_MACH_IXDP2351) +#define CS89x0_NONISA_IRQ static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #elif defined(CONFIG_ARCH_IXDP2X01) +#define CS89x0_NONISA_IRQ static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; #elif defined(CONFIG_MACH_QQ2440) +#define CS89x0_NONISA_IRQ #include static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 }; static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 }; #elif defined(CONFIG_MACH_MX31ADS) +#define CS89x0_NONISA_IRQ #include static unsigned int netcard_portlist[] __used __initdata = { PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0 }; static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0}; #else +#ifndef CONFIG_CS89x0_PLATFORM static unsigned int netcard_portlist[] __used __initdata = { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0}; static unsigned int cs8900_irq_map[] = {10,11,12,5}; #endif +#endif #if DEBUGGING static unsigned int net_debug = DEBUGGING; @@ -236,11 +243,16 @@ struct net_local { unsigned char *end_dma_buff; /* points to the end of the buffer */ unsigned char *rx_dma_ptr; /* points to the next packet */ #endif +#ifdef CONFIG_CS89x0_PLATFORM + void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */ + unsigned long phys_addr;/* Physical address for accessing the CS89x0. */ + unsigned long size; /* Length of CS89x0 memory region. */ +#endif }; /* Index to functions, as function prototypes. */ -static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular); +static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular); static int net_open(struct net_device *dev); static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev); static irqreturn_t net_interrupt(int irq, void *dev_id); @@ -294,6 +306,7 @@ static int __init media_fn(char *str) __setup("cs89x0_media=", media_fn); +#ifndef CONFIG_CS89x0_PLATFORM /* Check for a network adaptor of this type, and return '0' iff one exists. If dev->base_addr == 0, probe all likely locations. If dev->base_addr == 1, always return failure. @@ -343,6 +356,7 @@ out: return ERR_PTR(err); } #endif +#endif #if defined(CONFIG_MACH_IXDP2351) static u16 @@ -504,7 +518,7 @@ static const struct net_device_ops net_ops = { */ static int __init -cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) +cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) { struct net_local *lp = netdev_priv(dev); static unsigned version_printed; @@ -537,7 +551,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) /* Grab the region so we can find another board if autoIRQ fails. */ /* WTF is going on here? */ if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) { - printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n", + printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n", DRV_NAME, ioaddr, NETCARD_IO_EXTENT); retval = -EBUSY; goto out1; @@ -549,7 +563,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) will skip the test for the ADD_PORT. */ if (ioaddr & 1) { if (net_debug > 1) - printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr); + printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr); if ((ioaddr & 2) != 2) if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) { printk(KERN_ERR "%s: bad signature 0x%x\n", @@ -560,13 +574,13 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) } ioaddr &= ~3; - printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n", + printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n", ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT)); writeword(ioaddr, ADD_PORT, PP_ChipID); tmp = readword(ioaddr, DATA_PORT); if (tmp != CHIP_EISA_ID_SIG) { - printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!=" + printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!=" CHIP_EISA_ID_SIG_STR "\n", dev->name, ioaddr, DATA_PORT, tmp); retval = -ENODEV; @@ -736,8 +750,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) dev->irq = i; } else { i = lp->isa_config & INT_NO_MASK; +#ifndef CONFIG_CS89x0_PLATFORM if (lp->chip_type == CS8900) { -#ifdef CONFIG_CS89x0_NONISA_IRQ +#ifdef CS89x0_NONISA_IRQ i = cs8900_irq_map[0]; #else /* Translate the IRQ using the IRQ mapping table. */ @@ -758,6 +773,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular) } #endif } +#endif if (!dev->irq) dev->irq = i; } @@ -1168,6 +1184,7 @@ write_irq(struct net_device *dev, int chip_type, int irq) int i; if (chip_type == CS8900) { +#ifndef CONFIG_CS89x0_PLATFORM /* Search the mapping table for the corresponding IRQ pin. */ for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++) if (cs8900_irq_map[i] == irq) @@ -1175,6 +1192,10 @@ write_irq(struct net_device *dev, int chip_type, int irq) /* Not found */ if (i == ARRAY_SIZE(cs8900_irq_map)) i = 3; +#else + /* INTRQ0 pin is used for interrupt generation. */ + i = 0; +#endif writereg(dev, PP_CS8900_ISAINT, i); } else { writereg(dev, PP_CS8920_ISAINT, irq); @@ -1228,7 +1249,7 @@ net_open(struct net_device *dev) } else { -#ifndef CONFIG_CS89x0_NONISA_IRQ +#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM) if (((1 << dev->irq) & lp->irq_map) == 0) { printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n", dev->name, dev->irq, lp->irq_map); @@ -1746,7 +1767,7 @@ static int set_mac_address(struct net_device *dev, void *p) return 0; } -#ifdef MODULE +#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM) static struct net_device *dev_cs89x0; @@ -1900,7 +1921,97 @@ cleanup_module(void) release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT); free_netdev(dev_cs89x0); } -#endif /* MODULE */ +#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */ + +#ifdef CONFIG_CS89x0_PLATFORM +static int __init cs89x0_platform_probe(struct platform_device *pdev) +{ + struct net_device *dev = alloc_etherdev(sizeof(struct net_local)); + struct net_local *lp; + struct resource *mem_res; + int err; + + if (!dev) + return -ENOMEM; + + lp = netdev_priv(dev); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + dev->irq = platform_get_irq(pdev, 0); + if (mem_res == NULL || dev->irq <= 0) { + dev_warn(&dev->dev, "memory/interrupt resource missing.\n"); + err = -ENXIO; + goto free; + } + + lp->phys_addr = mem_res->start; + lp->size = resource_size(mem_res); + if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) { + dev_warn(&dev->dev, "request_mem_region() failed.\n"); + err = -EBUSY; + goto free; + } + + lp->virt_addr = ioremap(lp->phys_addr, lp->size); + if (!lp->virt_addr) { + dev_warn(&dev->dev, "ioremap() failed.\n"); + err = -ENOMEM; + goto release; + } + + err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0); + if (err) { + dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n"); + goto unmap; + } + + platform_set_drvdata(pdev, dev); + return 0; + +unmap: + iounmap(lp->virt_addr); +release: + release_mem_region(lp->phys_addr, lp->size); +free: + free_netdev(dev); + return err; +} + +static int cs89x0_platform_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + struct net_local *lp = netdev_priv(dev); + + unregister_netdev(dev); + iounmap(lp->virt_addr); + release_mem_region(lp->phys_addr, lp->size); + free_netdev(dev); + return 0; +} + +static struct platform_driver cs89x0_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .remove = cs89x0_platform_remove, +}; + +static int __init cs89x0_init(void) +{ + return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe); +} + +module_init(cs89x0_init); + +static void __exit cs89x0_cleanup(void) +{ + platform_driver_unregister(&cs89x0_driver); +} + +module_exit(cs89x0_cleanup); + +#endif /* CONFIG_CS89x0_PLATFORM */ /* * Local variables: -- cgit v1.2.3-70-g09d2 From 69c311fd604a01db3ab26c3f16d6c9cb0b2d5de6 Mon Sep 17 00:00:00 2001 From: Jaccon Bastiaansen Date: Thu, 26 Jan 2012 21:47:11 +0100 Subject: CS89x0 : remove QQ2440 board support from the CS89x0 driver The QQ2440 board isn't supported anymore in the kernel, so support for this board can be removed from the CS89x0 driver. Signed-off-by: Jaccon Bastiaansen Acked-by: David S. Miller Signed-off-by: Sascha Hauer --- drivers/net/ethernet/cirrus/cs89x0.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index 6b3cd24eb45..f7449bdd2cc 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -182,11 +182,6 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #define CS89x0_NONISA_IRQ static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; -#elif defined(CONFIG_MACH_QQ2440) -#define CS89x0_NONISA_IRQ -#include -static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 }; -static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 }; #elif defined(CONFIG_MACH_MX31ADS) #define CS89x0_NONISA_IRQ #include @@ -543,9 +538,6 @@ cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular) lp->force = g_cs89x0_media__force; #endif -#if defined(CONFIG_MACH_QQ2440) - lp->force |= FORCE_RJ45 | FORCE_FULL; -#endif } /* Grab the region so we can find another board if autoIRQ fails. */ -- cgit v1.2.3-70-g09d2 From 64a38516ff50c3f6c1ef563c2f410db3239d9302 Mon Sep 17 00:00:00 2001 From: Jaccon Bastiaansen Date: Thu, 26 Jan 2012 21:47:27 +0100 Subject: CS89x0 : add CS89x0 platform device to the iMX31ADS board Add CS89x0 networking support to the iMX31ADS board by using the platform driver support in the CS89x0 driver. Signed-off-by: Jaccon Bastiaansen Acked-by: David S. Miller Signed-off-by: Sascha Hauer --- arch/arm/configs/imx_v6_v7_defconfig | 4 +-- arch/arm/mach-imx/mach-mx31ads.c | 35 +++++++++++++++++++++++--- arch/arm/plat-mxc/include/mach/board-mx31ads.h | 33 ------------------------ drivers/net/ethernet/cirrus/cs89x0.c | 7 ------ 4 files changed, 34 insertions(+), 45 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/board-mx31ads.h (limited to 'drivers') diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 3a4fb2e5fc6..c032fe8d3e0 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig @@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y CONFIG_MACH_KZM_ARM11_01=y CONFIG_MACH_PCM043=y CONFIG_MACH_MX35_3DS=y -CONFIG_MACH_EUKREA_CPUIMX35=y CONFIG_MACH_VPR200=y CONFIG_MACH_IMX51_DT=y CONFIG_MACH_MX51_3DS=y @@ -82,8 +81,9 @@ CONFIG_PATA_IMX=y CONFIG_NETDEVICES=y # CONFIG_NET_VENDOR_BROADCOM is not set # CONFIG_NET_VENDOR_CHELSIO is not set +CONFIG_CS89x0=y +CONFIG_CS89x0_PLATFORM=y # CONFIG_NET_VENDOR_FARADAY is not set -CONFIG_FEC=y # CONFIG_NET_VENDOR_INTEL is not set # CONFIG_NET_VENDOR_MARVELL is not set # CONFIG_NET_VENDOR_MICREL is not set diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c index 4917aab0e25..4518e544822 100644 --- a/arch/arm/mach-imx/mach-mx31ads.c +++ b/arch/arm/mach-imx/mach-mx31ads.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1 @@ -39,6 +38,9 @@ #include "devices-imx31.h" +/* Base address of PBC controller */ +#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT + /* PBC Board interrupt status register */ #define PBC_INTSTATUS 0x000016 @@ -62,6 +64,7 @@ #define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS) #define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4) +#define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START #define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE) #define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10) @@ -69,6 +72,10 @@ #define MXC_MAX_EXP_IO_LINES 16 +/* CS8900 */ +#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) +#define CS4_CS8900_MMIO_START 0x20000 + /* * The serial port definition structure. */ @@ -101,11 +108,29 @@ static struct platform_device serial_device = { }, }; +static const struct resource mx31ads_cs8900_resources[] __initconst = { + DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K), + DEFINE_RES_IRQ(EXPIO_INT_ENET_INT), +}; + +static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = { + .name = "cs89x0", + .id = 0, + .res = mx31ads_cs8900_resources, + .num_res = ARRAY_SIZE(mx31ads_cs8900_resources), +}; + static int __init mxc_init_extuart(void) { return platform_device_register(&serial_device); } +static void __init mxc_init_ext_ethernet(void) +{ + platform_device_register_full( + (struct platform_device_info *)&mx31ads_cs8900_devinfo); +} + static const struct imxuart_platform_data uart_pdata __initconst = { .flags = IMXUART_HAVE_RTSCTS, }; @@ -492,12 +517,15 @@ static void __init mxc_init_audio(void) mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi"); } -/* static mappings */ +/* + * Static mappings, starting from the CS4 start address up to the start address + * of the CS8900. + */ static struct map_desc mx31ads_io_desc[] __initdata = { { .virtual = MX31_CS4_BASE_ADDR_VIRT, .pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR), - .length = MX31_CS4_SIZE / 2, + .length = CS4_CS8900_MMIO_START, .type = MT_DEVICE }, }; @@ -522,6 +550,7 @@ static void __init mx31ads_init(void) mxc_init_imx_uart(); mxc_init_i2c(); mxc_init_audio(); + mxc_init_ext_ethernet(); } static void __init mx31ads_timer_init(void) diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h deleted file mode 100644 index 94b60dd4713..00000000000 --- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ -#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ - -#include - -/* - * These symbols are used by drivers/net/cs89x0.c. - * This is ugly as hell, but we have to provide them until - * someone fixed the driver. - */ - -/* Base address of PBC controller */ -#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT -/* Offsets for the PBC Controller register */ - -/* Ethernet Controller IO base address */ -#define PBC_CS8900A_IOBASE 0x020000 - -#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START) - -#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8) - -#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */ diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c index f7449bdd2cc..7202ca951bf 100644 --- a/drivers/net/ethernet/cirrus/cs89x0.c +++ b/drivers/net/ethernet/cirrus/cs89x0.c @@ -182,13 +182,6 @@ static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0}; #define CS89x0_NONISA_IRQ static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0}; static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0}; -#elif defined(CONFIG_MACH_MX31ADS) -#define CS89x0_NONISA_IRQ -#include -static unsigned int netcard_portlist[] __used __initdata = { - PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0 -}; -static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0}; #else #ifndef CONFIG_CS89x0_PLATFORM static unsigned int netcard_portlist[] __used __initdata = -- cgit v1.2.3-70-g09d2 From 9dfac4fd7f8cdcdf734dff2ccc7ca467f53f1cfd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 18:02:47 +0100 Subject: pinctrl: delete raw device pointers in pinmux maps After discussion with Mark Brown in an unrelated thread about ADC lookups, it came to my knowledge that the ability to pass a struct device * in the regulator consumers is just a historical artifact, and not really recommended. Since there are no in-kernel users of these pointers, we just kill them right now, before someone starts to use them. Reviewed-by: Mark Brown Signed-off-by: Linus Walleij --- Documentation/pinctrl.txt | 5 +---- drivers/pinctrl/core.c | 22 +++++++--------------- drivers/pinctrl/core.h | 3 +-- drivers/pinctrl/pinconf.c | 8 ++++---- drivers/pinctrl/pinmux.c | 27 ++++++++------------------- include/linux/pinctrl/machine.h | 12 ++---------- 6 files changed, 23 insertions(+), 54 deletions(-) (limited to 'drivers') diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 150fd3833d0..14aecd2b2db 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -805,10 +805,7 @@ must match a function provided by the pinmux driver handling this pin range. As you can see we may have several pin controllers on the system and thus we need to specify which one of them that contain the functions we wish -to map. The map can also use struct device * directly, so there is no -inherent need to use strings to specify .dev_name or .ctrl_dev_name, these -are for the situation where you do not have a handle to the struct device *, -for example if they are not yet instantiated or cumbersome to obtain. +to map. You register this pinmux mapping to the pinmux subsystem by simply: diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 894cd5e103d..4f10476cc1f 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -48,31 +48,23 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); /** - * get_pinctrl_dev_from_dev() - look up pin controller device - * @dev: a device pointer, this may be NULL but then devname needs to be - * defined instead - * @devname: the name of a device instance, as returned by dev_name(), this - * may be NULL but then dev needs to be defined instead + * get_pinctrl_dev_from_devname() - look up pin controller device + * @devname: the name of a device instance, as returned by dev_name() * * Looks up a pin control device matching a certain device name or pure device * pointer, the pure device pointer will take precedence. */ -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *devname) +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) { struct pinctrl_dev *pctldev = NULL; bool found = false; + if (!devname) + return NULL; + mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { - if (dev && pctldev->dev == dev) { - /* Matched on device pointer */ - found = true; - break; - } - - if (devname && - !strcmp(dev_name(pctldev->dev), devname)) { + if (!strcmp(dev_name(pctldev->dev), devname)) { /* Matched on device name */ found = true; break; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index cfa86da6b4b..8a8b02e9c18 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -72,8 +72,7 @@ struct pin_desc { #endif }; -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *dev_name); +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); int pinctrl_get_device_gpio_range(unsigned gpio, diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 9fb75456824..b74f64af192 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -51,7 +51,7 @@ int pin_config_get(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -99,7 +99,7 @@ int pin_config_set(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -118,7 +118,7 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, const struct pinconf_ops *ops; int selector; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; @@ -151,7 +151,7 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, int ret; int i; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 7c3193f7a04..1311f1d2200 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -354,7 +354,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { + if (!maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): no pin control device given\n", maps[i].name, i); return -EINVAL; @@ -366,7 +366,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].dev && !maps[i].dev_name) + if (!maps[i].dev_name) pr_debug("add system map %s function %s with no device\n", maps[i].name, maps[i].function); @@ -721,20 +721,12 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) /* * First, try to find the pctldev given in the map */ - pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev, - map->ctrl_dev_name); + pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (!pctldev) { - const char *devname = NULL; - - if (map->ctrl_dev) - devname = dev_name(map->ctrl_dev); - else if (map->ctrl_dev_name) - devname = map->ctrl_dev_name; - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", map->function); pr_warning("given pinctrl device name: %s", - devname ? devname : "UNDEFINED"); + map->ctrl_dev_name); /* Continue to check the other mappings anyway... */ continue; @@ -925,7 +917,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, struct pinmux *pmx; int ret; - if (map->dev || map->dev_name) { + if (map->dev_name) { /* * TODO: the day we have device tree support, we can * traverse the device tree and hog to specific device nodes @@ -996,9 +988,8 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) if (!map->hog_on_boot) continue; - if ((map->ctrl_dev == dev) || - (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname))) { + if (map->ctrl_dev_name && + !strcmp(map->ctrl_dev_name, devname)) { /* OK time to hog! */ ret = pinmux_hog_map(pctldev, map); if (ret) @@ -1156,14 +1147,12 @@ static int pinmux_maps_show(struct seq_file *s, void *what) struct pinmux_map const *map = &pinmux_maps[i]; seq_printf(s, "%s:\n", map->name); - if (map->dev || map->dev_name) + if (map->dev_name) seq_printf(s, " device: %s\n", - map->dev ? dev_name(map->dev) : map->dev_name); else seq_printf(s, " SYSTEM MUX\n"); seq_printf(s, " controlling device %s\n", - map->ctrl_dev ? dev_name(map->ctrl_dev) : map->ctrl_dev_name); seq_printf(s, " function: %s\n", map->function); seq_printf(s, " group: %s\n", map->group ? map->group : diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index d0aecb7f6fb..f8593fdc646 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -17,22 +17,16 @@ * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device - * @ctrl_dev: the pin control device to be used by this mapping, may be NULL - * if you provide .ctrl_dev_name instead (this is more common) * @ctrl_dev_name: the name of the device controlling this specific mapping, - * the name must be the same as in your struct device*, may be NULL if - * you provide .ctrl_dev instead + * the name must be the same as in your struct device* * @function: a function in the driver to use for this mapping, the driver * will lookup the function referenced by this ID on the specified * pin control device * @group: sometimes a function can map to different pin groups, so this * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used - * @dev: the device using this specific mapping, may be NULL if you provide - * .dev_name instead (this is more common) * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device*, may be NULL if you - * provide .dev instead + * must be the same as in your struct device* * @hog_on_boot: if this is set to true, the pin control subsystem will itself * hog the mappings as the pinmux device drivers are attached, so this is * typically used with system maps (mux mappings without an assigned @@ -42,11 +36,9 @@ */ struct pinmux_map { const char *name; - struct device *ctrl_dev; const char *ctrl_dev_name; const char *function; const char *group; - struct device *dev; const char *dev_name; bool hog_on_boot; }; -- cgit v1.2.3-70-g09d2 From f4e66983293f78e177bb210d19a46f083f5e8197 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 4 Jan 2012 10:26:33 +0800 Subject: pinctrl: enable pinmux for mmp series Support PXA168/PXA910/MMP2 pinmux. Now only support function switch. Signed-off-by: Haojian Zhuang [Rebase and fix some whitespace issues] Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 22 + drivers/pinctrl/Makefile | 4 + drivers/pinctrl/pinctrl-mmp2.c | 722 +++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-pxa168.c | 651 ++++++++++++++++++++++++ drivers/pinctrl/pinctrl-pxa3xx.c | 244 +++++++++ drivers/pinctrl/pinctrl-pxa3xx.h | 264 ++++++++++ drivers/pinctrl/pinctrl-pxa910.c | 1007 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 2914 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-mmp2.c create mode 100644 drivers/pinctrl/pinctrl-pxa168.c create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.c create mode 100644 drivers/pinctrl/pinctrl-pxa3xx.h create mode 100644 drivers/pinctrl/pinctrl-pxa910.c (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index afaf8855812..3bea79fc35d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -23,6 +23,28 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. +config PINCTRL_PXA3xx + bool + select PINMUX + +config PINCTRL_MMP2 + bool "MMP2 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA168 + bool "PXA168 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA910 + bool "PXA910 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + config PINCTRL_SIRF bool "CSR SiRFprimaII pin controller driver" depends on ARCH_PRIMA2 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 827601cc68f..c95d91e87b5 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,6 +5,10 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o +obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o +obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o +obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o +obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c new file mode 100644 index 00000000000..2cfed552bbe --- /dev/null +++ b/drivers/pinctrl/pinctrl-mmp2.c @@ -0,0 +1,722 @@ +/* + * linux/drivers/pinctrl/pinmux-mmp2.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define MMP2_DS_MASK 0x1800 +#define MMP2_DS_SHIFT 11 +#define MMP2_SLEEP_MASK 0x38 +#define MMP2_SLEEP_SELECT (1 << 9) +#define MMP2_SLEEP_DATA (1 << 8) +#define MMP2_SLEEP_DIR (1 << 7) + +#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + MMP2_MUX_##f0, \ + MMP2_MUX_##f1, \ + MMP2_MUX_##f2, \ + MMP2_MUX_##f3, \ + MMP2_MUX_##f4, \ + MMP2_MUX_##f5, \ + MMP2_MUX_##f6, \ + MMP2_MUX_##f7, \ + }, \ + } + +#define GRP_MMP2(a, m, p) \ + { .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 174 pins */ +enum mmp2_pin_list { + /* 0~168: GPIO0~GPIO168 */ + TWSI4_SCL = 169, + TWSI4_SDA, /* 170 */ + G_CLKREQ, + VCXO_REQ, + VCXO_OUT, +}; + +enum mmp2_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + MMP2_MUX_GPIO = 0, + MMP2_MUX_G_CLKREQ, + MMP2_MUX_VCXO_REQ, + MMP2_MUX_VCXO_OUT, + MMP2_MUX_KP_MK, + MMP2_MUX_KP_DK, + MMP2_MUX_CCIC1, + MMP2_MUX_CCIC2, + MMP2_MUX_SPI, + MMP2_MUX_SSPA2, + MMP2_MUX_ROT, + MMP2_MUX_I2S, + MMP2_MUX_TB, + MMP2_MUX_CAM2, + MMP2_MUX_HDMI, + MMP2_MUX_TWSI2, + MMP2_MUX_TWSI3, + MMP2_MUX_TWSI4, + MMP2_MUX_TWSI5, + MMP2_MUX_TWSI6, + MMP2_MUX_UART1, + MMP2_MUX_UART2, + MMP2_MUX_UART3, + MMP2_MUX_UART4, + MMP2_MUX_SSP1_RX, + MMP2_MUX_SSP1_FRM, + MMP2_MUX_SSP1_TXRX, + MMP2_MUX_SSP2_RX, + MMP2_MUX_SSP2_FRM, + MMP2_MUX_SSP1, + MMP2_MUX_SSP2, + MMP2_MUX_SSP3, + MMP2_MUX_SSP4, + MMP2_MUX_MMC1, + MMP2_MUX_MMC2, + MMP2_MUX_MMC3, + MMP2_MUX_MMC4, + MMP2_MUX_ULPI, + MMP2_MUX_AC, + MMP2_MUX_CA, + MMP2_MUX_PWM, + MMP2_MUX_USIM, + MMP2_MUX_TIPU, + MMP2_MUX_PLL, + MMP2_MUX_NAND, + MMP2_MUX_FSIC, + MMP2_MUX_SLEEP_IND, + MMP2_MUX_EXT_DMA, + MMP2_MUX_ONE_WIRE, + MMP2_MUX_LCD, + MMP2_MUX_SMC, + MMP2_MUX_SMC_INT, + MMP2_MUX_MSP, + MMP2_MUX_G_CLKOUT, + MMP2_MUX_32K_CLKOUT, + MMP2_MUX_PRI_JTAG, + MMP2_MUX_AAS_JTAG, + MMP2_MUX_AAS_GPIO, + MMP2_MUX_AAS_SPI, + MMP2_MUX_AAS_TWSI, + MMP2_MUX_AAS_DEU_EX, + MMP2_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc mmp2_pads[] = { + /* + * The name indicates function 0 of this pin. + * After reset, function 0 is the default function of pin. + */ + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(GPIO128, "GPIO128"), + PINCTRL_PIN(GPIO129, "GPIO129"), + PINCTRL_PIN(GPIO130, "GPIO130"), + PINCTRL_PIN(GPIO131, "GPIO131"), + PINCTRL_PIN(GPIO132, "GPIO132"), + PINCTRL_PIN(GPIO133, "GPIO133"), + PINCTRL_PIN(GPIO134, "GPIO134"), + PINCTRL_PIN(GPIO135, "GPIO135"), + PINCTRL_PIN(GPIO136, "GPIO136"), + PINCTRL_PIN(GPIO137, "GPIO137"), + PINCTRL_PIN(GPIO138, "GPIO138"), + PINCTRL_PIN(GPIO139, "GPIO139"), + PINCTRL_PIN(GPIO140, "GPIO140"), + PINCTRL_PIN(GPIO141, "GPIO141"), + PINCTRL_PIN(GPIO142, "GPIO142"), + PINCTRL_PIN(GPIO143, "GPIO143"), + PINCTRL_PIN(GPIO144, "GPIO144"), + PINCTRL_PIN(GPIO145, "GPIO145"), + PINCTRL_PIN(GPIO146, "GPIO146"), + PINCTRL_PIN(GPIO147, "GPIO147"), + PINCTRL_PIN(GPIO148, "GPIO148"), + PINCTRL_PIN(GPIO149, "GPIO149"), + PINCTRL_PIN(GPIO150, "GPIO150"), + PINCTRL_PIN(GPIO151, "GPIO151"), + PINCTRL_PIN(GPIO152, "GPIO152"), + PINCTRL_PIN(GPIO153, "GPIO153"), + PINCTRL_PIN(GPIO154, "GPIO154"), + PINCTRL_PIN(GPIO155, "GPIO155"), + PINCTRL_PIN(GPIO156, "GPIO156"), + PINCTRL_PIN(GPIO157, "GPIO157"), + PINCTRL_PIN(GPIO158, "GPIO158"), + PINCTRL_PIN(GPIO159, "GPIO159"), + PINCTRL_PIN(GPIO160, "GPIO160"), + PINCTRL_PIN(GPIO161, "GPIO161"), + PINCTRL_PIN(GPIO162, "GPIO162"), + PINCTRL_PIN(GPIO163, "GPIO163"), + PINCTRL_PIN(GPIO164, "GPIO164"), + PINCTRL_PIN(GPIO165, "GPIO165"), + PINCTRL_PIN(GPIO166, "GPIO166"), + PINCTRL_PIN(GPIO167, "GPIO167"), + PINCTRL_PIN(GPIO168, "GPIO168"), + PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"), + PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"), + PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"), + PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin mmp2_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_MMP2(GPIO0, 0x054, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO1, 0x058, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO2, 0x05C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO3, 0x060, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO4, 0x064, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO5, 0x068, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO6, 0x06C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO7, 0x070, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO8, 0x074, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO9, 0x078, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO10, 0x07C, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO11, 0x080, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO12, 0x084, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO13, 0x088, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO14, 0x08C, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO15, 0x090, GPIO, KP_MK, KP_DK, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO16, 0x094, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO17, 0x098, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO18, 0x09C, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO19, 0x0A0, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO20, 0x0A4, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO21, 0x0A8, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO22, 0x0AC, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO23, 0x0B0, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO24, 0x0B4, GPIO, I2S, VCXO_OUT, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO25, 0x0B8, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO26, 0x0BC, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO27, 0x0C0, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO28, 0x0C4, GPIO, I2S, NONE, SSPA2, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO29, 0x0C8, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO30, 0x0CC, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO31, 0x0D0, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO32, 0x0D4, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE), + MFPR_MMP2(GPIO33, 0x0D8, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO34, 0x0DC, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO35, 0x0E0, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO36, 0x0E4, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO37, 0x0E8, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO38, 0x0EC, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO39, 0x0F0, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO40, 0x0F4, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI), + MFPR_MMP2(GPIO41, 0x0F8, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO42, 0x0FC, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO43, 0x100, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO44, 0x104, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI), + MFPR_MMP2(GPIO45, 0x108, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO46, 0x10C, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE), + MFPR_MMP2(GPIO47, 0x110, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO48, 0x114, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE), + MFPR_MMP2(GPIO49, 0x118, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO50, 0x11C, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE), + MFPR_MMP2(GPIO51, 0x120, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO52, 0x124, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE), + MFPR_MMP2(GPIO53, 0x128, GPIO, UART3, TWSI2, VCXO_REQ, NONE, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO54, 0x12C, GPIO, UART3, TWSI2, VCXO_OUT, HDMI, PWM, NONE, AAS_TWSI), + MFPR_MMP2(GPIO55, 0x130, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, SSP3, AAS_TWSI), + MFPR_MMP2(GPIO56, 0x134, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, KP_DK, AAS_TWSI), + MFPR_MMP2(GPIO57, 0x138, GPIO, SSP2_RX, SSP1_TXRX, SSP2_FRM, SSP1_RX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO58, 0x13C, GPIO, SSP2, SSP1_RX, SSP1_FRM, SSP1_TXRX, VCXO_REQ, KP_DK, NONE), + MFPR_MMP2(GPIO59, 0x280, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO60, 0x284, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE), + MFPR_MMP2(GPIO61, 0x288, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, HDMI, NONE), + MFPR_MMP2(GPIO62, 0x28C, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, NONE, NONE), + MFPR_MMP2(GPIO63, 0x290, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO64, 0x294, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO65, 0x298, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO66, 0x29C, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE), + MFPR_MMP2(GPIO67, 0x2A0, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, NONE, NONE), + MFPR_MMP2(GPIO68, 0x2A4, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO69, 0x2A8, GPIO, CCIC1, ULPI, MMC3, CCIC2, NONE, LCD, NONE), + MFPR_MMP2(GPIO70, 0x2AC, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE), + MFPR_MMP2(GPIO71, 0x2B0, GPIO, TWSI3, NONE, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO72, 0x2B4, GPIO, TWSI3, HDMI, PWM, NONE, NONE, LCD, AAS_TWSI), + MFPR_MMP2(GPIO73, 0x2B8, GPIO, VCXO_REQ, 32K_CLKOUT, PWM, VCXO_OUT, NONE, LCD, NONE), + MFPR_MMP2(GPIO74, 0x170, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO75, 0x174, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO76, 0x178, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO77, 0x17C, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU), + MFPR_MMP2(GPIO78, 0x180, GPIO, LCD, HDMI, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO79, 0x184, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO80, 0x188, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO81, 0x18C, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU), + MFPR_MMP2(GPIO82, 0x190, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO83, 0x194, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO84, 0x198, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO85, 0x19C, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU), + MFPR_MMP2(GPIO86, 0x1A0, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO87, 0x1A4, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU), + MFPR_MMP2(GPIO88, 0x1A8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO89, 0x1AC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO90, 0x1B0, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO91, 0x1B4, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO92, 0x1B8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO93, 0x1BC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU), + MFPR_MMP2(GPIO94, 0x1C0, GPIO, LCD, AAS_GPIO, SPI, NONE, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO95, 0x1C4, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, CCIC2, TIPU), + MFPR_MMP2(GPIO96, 0x1C8, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO97, 0x1CC, GPIO, LCD, TWSI6, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU), + MFPR_MMP2(GPIO98, 0x1D0, GPIO, LCD, TWSI6, SPI, ONE_WIRE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO99, 0x1D4, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO100, 0x1D8, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU), + MFPR_MMP2(GPIO101, 0x1DC, GPIO, LCD, SMC, SPI, NONE, NONE, NONE, TIPU), + MFPR_MMP2(GPIO102, 0x000, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO103, 0x004, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE), + MFPR_MMP2(GPIO104, 0x1FC, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO105, 0x1F8, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO106, 0x1F4, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO107, 0x1F0, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO108, 0x21C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO109, 0x218, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO110, 0x214, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO111, 0x200, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO112, 0x244, NAND, GPIO, MMC3, SMC, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO113, 0x25C, SMC, GPIO, EXT_DMA, MMC3, SMC, HDMI, NONE, NONE), + MFPR_MMP2(GPIO114, 0x164, G_CLKOUT, 32K_CLKOUT, HDMI, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO115, 0x260, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO116, 0x264, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO117, 0x268, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO118, 0x26C, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE), + MFPR_MMP2(GPIO119, 0x270, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO120, 0x274, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO121, 0x278, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO122, 0x27C, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO123, 0x148, GPIO, SLEEP_IND, ONE_WIRE, 32K_CLKOUT, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO124, 0x00C, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO125, 0x010, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO126, 0x014, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO127, 0x018, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO128, 0x01C, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO129, 0x020, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO130, 0x024, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO131, 0x028, GPIO, MMC1, NONE, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO132, 0x02C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO133, 0x030, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO134, 0x034, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO135, 0x038, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO136, 0x03C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO137, 0x040, GPIO, HDMI, LCD, MSP, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO138, 0x044, GPIO, NONE, LCD, MMC3, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO139, 0x048, GPIO, MMC1, PRI_JTAG, MSP, NONE, AAS_JTAG, NONE, NONE), + MFPR_MMP2(GPIO140, 0x04C, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO141, 0x050, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE), + MFPR_MMP2(GPIO142, 0x008, USIM, GPIO, FSIC, KP_DK, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO143, 0x220, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO144, 0x224, NAND, GPIO, SMC_INT, SMC, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO145, 0x228, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO146, 0x22C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO147, 0x230, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO148, 0x234, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO149, 0x238, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO150, 0x23C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO151, 0x240, SMC, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO152, 0x248, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO153, 0x24C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE), + MFPR_MMP2(GPIO154, 0x254, SMC_INT, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO155, 0x258, EXT_DMA, GPIO, SMC, NONE, EXT_DMA, NONE, NONE, NONE), + MFPR_MMP2(GPIO156, 0x14C, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO157, 0x150, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO158, 0x154, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO159, 0x158, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO160, 0x250, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO161, 0x210, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE), + MFPR_MMP2(GPIO162, 0x20C, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO163, 0x208, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO164, 0x204, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO165, 0x1EC, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO166, 0x1E8, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO167, 0x1E4, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(GPIO168, 0x1E0, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(G_CLKREQ, 0x160, G_CLKREQ, ONE_WIRE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_REQ, 0x168, VCXO_REQ, ONE_WIRE, PLL, NONE, NONE, NONE, NONE, NONE), + MFPR_MMP2(VCXO_OUT, 0x16C, VCXO_OUT, 32K_CLKOUT, NONE, NONE, NONE, NONE, NONE, NONE), +}; + +static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46}; +static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141}; +static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62}; +static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52}; +static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66}; +static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77}; +static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60}; +static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17}; +static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38}; +static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40}; +static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44}; +static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54}; +static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56}; +static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72}; +static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96}; +static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA}; +static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42}; +static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85}; +static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100}; +static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48}; +static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87}; +static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98}; +static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23}; +static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87, + GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95}; +static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62, + GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70}; +static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17}; +static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19}; +static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52}; +static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56}; +static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27, + GPIO28}; +static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40}; +static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118}; +static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122}; +static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136}; +static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134, + GPIO136, GPIO139, GPIO140, GPIO141}; +static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162, + GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168}; + +static struct pxa3xx_pin_group mmp2_grps[] = { + GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1), + GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2), + GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3), + GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1), + GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2), + GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3), + GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4), + GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5), + GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6), + GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1), + GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2), + GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3), + GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4), + GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5), + GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6), + GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1), + GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2), + GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3), + GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4), + GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5), + GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1), + GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2), + GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1), + GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2), + GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3), + GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4), + GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5), + GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1), + GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2), + GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1), + GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1), + GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2), + GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3), + GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1), + GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2), + GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3), + GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1), + GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1), + GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2), + GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1), + GRP_MMP2("ro-1", ROT, mmp2_ro_pin1), + GRP_MMP2("ro-2", ROT, mmp2_ro_pin2), + GRP_MMP2("ro-3", ROT, mmp2_ro_pin3), + GRP_MMP2("ro-4", ROT, mmp2_ro_pin4), + GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1), + GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2), + GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1), + GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2), + GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3), + GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1), + GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1), + GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2), + GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1), + GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2), + GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1), + GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1), + GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1), +}; + +static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2", + "uart1 2p3"}; +static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2", + "uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"}; +static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2", + "uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"}; +static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2", + "uart4 4p3", "uart4 4p4", "uart4 2p5"}; +static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"}; +static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2", + "twsi2-3", "twsi2-4", "twsi2-5"}; +static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"}; +static const char * const mmp2_twsi4_grps[] = {"twsi4"}; +static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2", + "twsi5-3"}; +static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2", + "twsi6-3"}; +static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"}; +static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"}; +static const char * const mmp2_ulpi_grps[] = {"ulpi"}; +static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"}; +static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"}; +static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2", + "ssp1 4p3"}; +static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"}; +static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"}; +static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"}; +static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"}; +static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"}; + +static struct pxa3xx_pmx_func mmp2_funcs[] = { + {"uart1", ARRAY_AND_SIZE(mmp2_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(mmp2_uart2_grps)}, + {"uart3", ARRAY_AND_SIZE(mmp2_uart3_grps)}, + {"uart4", ARRAY_AND_SIZE(mmp2_uart4_grps)}, + {"kpdk", ARRAY_AND_SIZE(mmp2_kpdk_grps)}, + {"twsi2", ARRAY_AND_SIZE(mmp2_twsi2_grps)}, + {"twsi3", ARRAY_AND_SIZE(mmp2_twsi3_grps)}, + {"twsi4", ARRAY_AND_SIZE(mmp2_twsi4_grps)}, + {"twsi5", ARRAY_AND_SIZE(mmp2_twsi5_grps)}, + {"twsi6", ARRAY_AND_SIZE(mmp2_twsi6_grps)}, + {"ccic1", ARRAY_AND_SIZE(mmp2_ccic1_grps)}, + {"ccic2", ARRAY_AND_SIZE(mmp2_ccic2_grps)}, + {"ulpi", ARRAY_AND_SIZE(mmp2_ulpi_grps)}, + {"ro", ARRAY_AND_SIZE(mmp2_ro_grps)}, + {"i2s", ARRAY_AND_SIZE(mmp2_i2s_grps)}, + {"ssp1", ARRAY_AND_SIZE(mmp2_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(mmp2_ssp2_grps)}, + {"ssp3", ARRAY_AND_SIZE(mmp2_ssp3_grps)}, + {"sspa2", ARRAY_AND_SIZE(mmp2_sspa2_grps)}, + {"mmc1", ARRAY_AND_SIZE(mmp2_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(mmp2_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(mmp2_mmc3_grps)}, +}; + +static struct pinctrl_desc mmp2_pctrl_desc = { + .name = "mmp2-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info mmp2_info = { + .mfp = mmp2_mfp, + .num_mfp = ARRAY_SIZE(mmp2_mfp), + .grps = mmp2_grps, + .num_grps = ARRAY_SIZE(mmp2_grps), + .funcs = mmp2_funcs, + .num_funcs = ARRAY_SIZE(mmp2_funcs), + .num_gpio = 169, + .desc = &mmp2_pctrl_desc, + .pads = mmp2_pads, + .num_pads = ARRAY_SIZE(mmp2_pads), + + .cputype = PINCTRL_MMP2, + .ds_mask = MMP2_DS_MASK, + .ds_shift = MMP2_DS_SHIFT, +}; + +static int __devinit mmp2_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &mmp2_info); +} + +static int __devexit mmp2_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver mmp2_pinmux_driver = { + .driver = { + .name = "mmp2-pinmux", + .owner = THIS_MODULE, + }, + .probe = mmp2_pinmux_probe, + .remove = __devexit_p(mmp2_pinmux_remove), +}; + +static int __init mmp2_pinmux_init(void) +{ + return platform_driver_register(&mmp2_pinmux_driver); +} +core_initcall_sync(mmp2_pinmux_init); + +static void __exit mmp2_pinmux_exit(void) +{ + platform_driver_unregister(&mmp2_pinmux_driver); +} +module_exit(mmp2_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c new file mode 100644 index 00000000000..c1997fa7f28 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa168.c @@ -0,0 +1,651 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa168.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA168_DS_MASK 0x1800 +#define PXA168_DS_SHIFT 11 +#define PXA168_SLEEP_MASK 0x38 +#define PXA168_SLEEP_SELECT (1 << 9) +#define PXA168_SLEEP_DATA (1 << 8) +#define PXA168_SLEEP_DIR (1 << 7) + +#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA168_MUX_##f0, \ + PXA168_MUX_##f1, \ + PXA168_MUX_##f2, \ + PXA168_MUX_##f3, \ + PXA168_MUX_##f4, \ + PXA168_MUX_##f5, \ + PXA168_MUX_##f6, \ + PXA168_MUX_##f7, \ + }, \ + } + +#define GRP_168(a, m, p) \ + { .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 131 pins */ +enum pxa168_pin_list { + /* 0~122: GPIO0~GPIO122 */ + PWR_SCL = 123, + PWR_SDA, + TDI, + TMS, + TCK, + TDO, + TRST, + WAKEUP = 130, +}; + +enum pxa168_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA168_MUX_GPIO = 0, + PXA168_MUX_DFIO, + PXA168_MUX_NAND, + PXA168_MUX_SMC, + PXA168_MUX_SMC_CS0, + PXA168_MUX_SMC_CS1, + PXA168_MUX_SMC_INT, + PXA168_MUX_SMC_RDY, + PXA168_MUX_MMC1, + PXA168_MUX_MMC2, + PXA168_MUX_MMC2_CMD, + PXA168_MUX_MMC2_CLK, + PXA168_MUX_MMC3, + PXA168_MUX_MMC3_CMD, + PXA168_MUX_MMC3_CLK, + PXA168_MUX_MMC4, + PXA168_MUX_MSP, + PXA168_MUX_MSP_DAT3, + PXA168_MUX_MSP_INS, + PXA168_MUX_I2C, + PXA168_MUX_PWRI2C, + PXA168_MUX_AC97, + PXA168_MUX_AC97_SYSCLK, + PXA168_MUX_PWM, + PXA168_MUX_PWM1, + PXA168_MUX_XD, + PXA168_MUX_XP, + PXA168_MUX_LCD, + PXA168_MUX_CCIC, + PXA168_MUX_CF, + PXA168_MUX_CF_RDY, + PXA168_MUX_CF_nINPACK, + PXA168_MUX_CF_nWAIT, + PXA168_MUX_KP_MKOUT, + PXA168_MUX_KP_MKIN, + PXA168_MUX_KP_DK, + PXA168_MUX_ETH, + PXA168_MUX_ETH_TX, + PXA168_MUX_ETH_RX, + PXA168_MUX_ONE_WIRE, + PXA168_MUX_UART1, + PXA168_MUX_UART1_TX, + PXA168_MUX_UART1_CTS, + PXA168_MUX_UART1_nRI, + PXA168_MUX_UART1_DTR, + PXA168_MUX_UART2, + PXA168_MUX_UART2_TX, + PXA168_MUX_UART3, + PXA168_MUX_UART3_TX, + PXA168_MUX_UART3_CTS, + PXA168_MUX_SSP1, + PXA168_MUX_SSP1_TX, + PXA168_MUX_SSP2, + PXA168_MUX_SSP2_TX, + PXA168_MUX_SSP3, + PXA168_MUX_SSP3_TX, + PXA168_MUX_SSP4, + PXA168_MUX_SSP4_TX, + PXA168_MUX_SSP5, + PXA168_MUX_SSP5_TX, + PXA168_MUX_USB, + PXA168_MUX_JTAG, + PXA168_MUX_RESET, + PXA168_MUX_WAKEUP, + PXA168_MUX_EXT_32K_IN, + PXA168_MUX_NONE = 0xffff, +}; + +static struct pinctrl_pin_desc pxa168_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(PWR_SCL, "PWR_SCL"), + PINCTRL_PIN(PWR_SDA, "PWR_SDA"), + PINCTRL_PIN(TDI, "TDI"), + PINCTRL_PIN(TMS, "TMS"), + PINCTRL_PIN(TCK, "TCK"), + PINCTRL_PIN(TDO, "TDO"), + PINCTRL_PIN(TRST, "TRST"), + PINCTRL_PIN(WAKEUP, "WAKEUP"), +}; + +struct pxa3xx_mfp_pin pxa168_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_168(GPIO0, 0x04C, DFIO, NONE, NONE, MSP, MMC3_CMD, GPIO, MMC3, NONE), + MFPR_168(GPIO1, 0x050, DFIO, NONE, NONE, MSP, MMC3_CLK, GPIO, MMC3, NONE), + MFPR_168(GPIO2, 0x054, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO3, 0x058, DFIO, NONE, NONE, NONE, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO4, 0x05C, DFIO, NONE, NONE, MSP_DAT3, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO5, 0x060, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO6, 0x064, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO7, 0x068, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE), + MFPR_168(GPIO8, 0x06C, DFIO, MMC2, UART3_TX, NONE, MMC2_CMD, GPIO, MMC3_CLK, NONE), + MFPR_168(GPIO9, 0x070, DFIO, MMC2, UART3, NONE, MMC2_CLK, GPIO, MMC3_CMD, NONE), + MFPR_168(GPIO10, 0x074, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP_DAT3, NONE), + MFPR_168(GPIO11, 0x078, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO12, 0x07C, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO13, 0x080, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO14, 0x084, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO15, 0x088, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO16, 0x08C, GPIO, NAND, SMC_CS0, SMC_CS1, NONE, NONE, MMC3, NONE), + MFPR_168(GPIO17, 0x090, NAND, NONE, NONE, NONE, NONE, GPIO, MSP, NONE), + MFPR_168(GPIO18, 0x094, GPIO, NAND, SMC_CS1, SMC_CS0, NONE, NONE, NONE, NONE), + MFPR_168(GPIO19, 0x098, SMC_CS0, NONE, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO20, 0x09C, GPIO, NONE, SMC_CS1, CF, CF_RDY, NONE, NONE, NONE), + MFPR_168(GPIO21, 0x0A0, NAND, MMC2_CLK, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO22, 0x0A4, NAND, MMC2_CMD, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO23, 0x0A8, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO24, 0x0AC, NAND, NONE, NONE, NONE, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO25, 0x0B0, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE), + MFPR_168(GPIO26, 0x0B4, GPIO, NAND, NONE, NONE, CF, NONE, NONE, NONE), + MFPR_168(GPIO27, 0x0B8, SMC_INT, NAND, SMC, NONE, SMC_RDY, GPIO, NONE, NONE), + MFPR_168(GPIO28, 0x0BC, SMC_RDY, MMC4, SMC, CF_RDY, NONE, GPIO, MMC2_CMD, NONE), + MFPR_168(GPIO29, 0x0C0, SMC, MMC4, NONE, CF, NONE, GPIO, MMC2_CLK, KP_DK), + MFPR_168(GPIO30, 0x0C4, SMC, MMC4, UART3_TX, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO31, 0x0C8, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO32, 0x0CC, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK), + MFPR_168(GPIO33, 0x0D0, SMC, MMC4, UART3, CF, CF_nINPACK, GPIO, MMC2, KP_DK), + MFPR_168(GPIO34, 0x0D4, GPIO, NONE, SMC_CS1, CF, CF_nWAIT, NONE, MMC3, KP_DK), + MFPR_168(GPIO35, 0x0D8, GPIO, NONE, SMC, CF_nINPACK, NONE, NONE, MMC3_CMD, KP_DK), + MFPR_168(GPIO36, 0x0DC, GPIO, NONE, SMC, CF_nWAIT, NONE, NONE, MMC3_CLK, KP_DK), + MFPR_168(GPIO37, 0x000, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO38, 0x004, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO39, 0x008, GPIO, NONE, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO40, 0x00C, GPIO, MMC1, MSP, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO41, 0x010, GPIO, MMC1, MSP, NONE, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO42, 0x014, GPIO, I2C, NONE, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO43, 0x018, GPIO, MMC1, MSP, MSP_INS, NONE, NONE, KP_MKIN, KP_DK), + MFPR_168(GPIO44, 0x01C, GPIO, MMC1, MSP_DAT3, MSP, CCIC, XP, KP_MKIN, KP_DK), + MFPR_168(GPIO45, 0x020, GPIO, NONE, NONE, MSP, CCIC, XP, NONE, KP_DK), + MFPR_168(GPIO46, 0x024, GPIO, MMC1, MSP_INS, MSP, CCIC, NONE, KP_MKOUT, KP_DK), + MFPR_168(GPIO47, 0x028, GPIO, NONE, NONE, MSP_INS, NONE, XP, NONE, KP_DK), + MFPR_168(GPIO48, 0x02C, GPIO, MMC1, NONE, MSP_DAT3, CCIC, NONE, NONE, KP_DK), + MFPR_168(GPIO49, 0x030, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO50, 0x034, GPIO, I2C, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO51, 0x038, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO52, 0x03C, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO53, 0x040, GPIO, MMC1, NONE, NONE, NONE, XD, KP_MKOUT, NONE), + MFPR_168(GPIO54, 0x044, GPIO, MMC1, NONE, NONE, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO55, 0x048, GPIO, NONE, NONE, MSP, CCIC, XD, KP_MKOUT, NONE), + MFPR_168(GPIO56, 0x0E0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO57, 0x0E4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO58, 0x0E8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO59, 0x0EC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO60, 0x0F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO61, 0x0F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO62, 0x0F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO63, 0x0FC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO64, 0x100, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO65, 0x104, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO66, 0x108, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO67, 0x10C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_168(GPIO68, 0x110, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO69, 0x114, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO70, 0x118, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO71, 0x11C, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO72, 0x120, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO73, 0x124, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO74, 0x128, GPIO, LCD, PWM, XD, NONE, NONE, NONE, NONE), + MFPR_168(GPIO75, 0x12C, GPIO, LCD, PWM, XD, ONE_WIRE, NONE, NONE, NONE), + MFPR_168(GPIO76, 0x130, GPIO, LCD, PWM, I2C, NONE, NONE, MSP_INS, NONE), + MFPR_168(GPIO77, 0x134, GPIO, LCD, PWM1, I2C, ONE_WIRE, NONE, XD, NONE), + MFPR_168(GPIO78, 0x138, GPIO, LCD, NONE, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO79, 0x13C, GPIO, LCD, NONE, NONE, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO80, 0x140, GPIO, LCD, NONE, I2C, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO81, 0x144, GPIO, LCD, NONE, I2C, ONE_WIRE, MMC4, NONE, NONE), + MFPR_168(GPIO82, 0x148, GPIO, LCD, PWM, NONE, NONE, MMC4, NONE, NONE), + MFPR_168(GPIO83, 0x14C, GPIO, LCD, PWM, NONE, RESET, MMC4, NONE, NONE), + MFPR_168(GPIO84, 0x150, GPIO, NONE, PWM, ONE_WIRE, PWM1, NONE, NONE, EXT_32K_IN), + MFPR_168(GPIO85, 0x154, GPIO, NONE, PWM1, NONE, NONE, NONE, NONE, USB), + MFPR_168(GPIO86, 0x158, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5_TX, SSP5), + MFPR_168(GPIO87, 0x15C, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5, SSP5_TX), + MFPR_168(GPIO88, 0x160, GPIO, MMC2, UART2, UART2_TX, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO89, 0x164, GPIO, MMC2, UART2_TX, UART2, JTAG, ETH_TX, ETH_RX, SSP5), + MFPR_168(GPIO90, 0x168, GPIO, MMC2, NONE, SSP3, JTAG, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO91, 0x16C, GPIO, MMC2, NONE, SSP3, SSP4, ETH_TX, ETH_RX, NONE), + MFPR_168(GPIO92, 0x170, GPIO, MMC2, NONE, SSP3, SSP3_TX, ETH, NONE, NONE), + MFPR_168(GPIO93, 0x174, GPIO, MMC2, NONE, SSP3_TX, SSP3, ETH, NONE, NONE), + MFPR_168(GPIO94, 0x178, GPIO, MMC2_CMD, SSP3, AC97_SYSCLK, AC97, ETH, NONE, NONE), + MFPR_168(GPIO95, 0x17C, GPIO, MMC2_CLK, NONE, NONE, AC97, ETH, NONE, NONE), + MFPR_168(GPIO96, 0x180, GPIO, PWM, NONE, MMC2, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO97, 0x184, GPIO, PWM, ONE_WIRE, NONE, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO98, 0x188, GPIO, PWM1, UART3_TX, UART3, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO99, 0x18C, GPIO, ONE_WIRE, UART3, UART3_TX, NONE, ETH_RX, ETH_TX, NONE), + MFPR_168(GPIO100, 0x190, GPIO, NONE, UART3_CTS, UART3, NONE, ETH, NONE, NONE), + MFPR_168(GPIO101, 0x194, GPIO, NONE, UART3, UART3_CTS, NONE, ETH, NONE, NONE), + MFPR_168(GPIO102, 0x198, GPIO, I2C, UART3, SSP4, NONE, NONE, NONE, NONE), + MFPR_168(GPIO103, 0x19C, GPIO, I2C, UART3, SSP4, SSP2, ETH, NONE, NONE), + MFPR_168(GPIO104, 0x1A0, GPIO, PWM, UART1, SSP4, SSP4_TX, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO105, 0x1A4, GPIO, I2C, UART1, SSP4_TX, SSP4, AC97, KP_MKOUT, NONE), + MFPR_168(GPIO106, 0x1A8, GPIO, I2C, PWM1, AC97_SYSCLK, MMC2, NONE, KP_MKOUT, NONE), + MFPR_168(GPIO107, 0x1AC, GPIO, UART1_TX, UART1, NONE, SSP2, MSP_DAT3, NONE, KP_MKIN), + MFPR_168(GPIO108, 0x1B0, GPIO, UART1, UART1_TX, NONE, SSP2_TX, MSP, NONE, KP_MKIN), + MFPR_168(GPIO109, 0x1B4, GPIO, UART1_CTS, UART1, NONE, AC97_SYSCLK, MSP, NONE, KP_MKIN), + MFPR_168(GPIO110, 0x1B8, GPIO, UART1, UART1_CTS, NONE, SMC_RDY, MSP, NONE, KP_MKIN), + MFPR_168(GPIO111, 0x1BC, GPIO, UART1_nRI, UART1, SSP3, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO112, 0x1C0, GPIO, UART1_DTR, UART1, ONE_WIRE, SSP2, MSP, XD, KP_MKOUT), + MFPR_168(GPIO113, 0x1C4, GPIO, NONE, NONE, NONE, NONE, NONE, AC97_SYSCLK, NONE), + MFPR_168(GPIO114, 0x1C8, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO115, 0x1CC, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO116, 0x1D0, GPIO, SSP1_TX, SSP1, NONE, NONE, NONE, AC97, NONE), + MFPR_168(GPIO117, 0x1D4, GPIO, SSP1, SSP1_TX, NONE, MMC2_CMD, NONE, AC97, NONE), + MFPR_168(GPIO118, 0x1D8, GPIO, SSP2, NONE, NONE, MMC2_CLK, NONE, AC97, KP_MKIN), + MFPR_168(GPIO119, 0x1DC, GPIO, SSP2, NONE, NONE, MMC2, NONE, AC97, KP_MKIN), + MFPR_168(GPIO120, 0x1E0, GPIO, SSP2, SSP2_TX, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO121, 0x1E4, GPIO, SSP2_TX, SSP2, NONE, MMC2, NONE, NONE, KP_MKIN), + MFPR_168(GPIO122, 0x1E8, GPIO, AC97_SYSCLK, SSP2, PWM, MMC2, NONE, NONE, NONE), + MFPR_168(PWR_SCL, 0x1EC, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, MMC4), + MFPR_168(PWR_SDA, 0x1F0, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, NONE), + MFPR_168(TDI, 0x1F4, JTAG, PWM1, UART2, MMC4, SSP5, NONE, XD, MMC4), + MFPR_168(TMS, 0x1F8, JTAG, PWM, UART2, NONE, SSP5, NONE, XD, MMC4), + MFPR_168(TCK, 0x1FC, JTAG, PWM, UART2, UART2_TX, SSP5, NONE, XD, MMC4), + MFPR_168(TDO, 0x200, JTAG, PWM, UART2_TX, UART2, SSP5_TX, NONE, XD, MMC4), + MFPR_168(TRST, 0x204, JTAG, ONE_WIRE, SSP2, SSP3, AC97_SYSCLK, NONE, XD, MMC4), + MFPR_168(WAKEUP, 0x208, WAKEUP, ONE_WIRE, PWM1, PWM, SSP2, NONE, GPIO, MMC4), +}; + +static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST}; +static const unsigned p168_wakeup_pin1[] = {WAKEUP}; +static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p168_ssp1tx_pin1[] = {GPIO117}; +static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104}; +static const unsigned p168_ssp4tx_pin1[] = {GPIO105}; +static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89}; +static const unsigned p168_ssp5tx_pin1[] = {GPIO87}; +static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106}; +static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA}; +static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46, + GPIO49, GPIO51, GPIO52, GPIO53}; +static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93}; +static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94}; +static const unsigned p168_mmc2_clk_pin1[] = {GPIO95}; +static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7}; +static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9}; +static const unsigned p168_mmc3_clk_pin1[] = {GPIO8}; +static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101, + GPIO103}; +static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89, + GPIO90, GPIO91}; +static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97, + GPIO98, GPIO99}; +static const unsigned p168_uart1rx_pin1[] = {GPIO107}; +static const unsigned p168_uart1tx_pin1[] = {GPIO108}; +static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101}; +static const unsigned p168_uart3tx_pin1[] = {GPIO99}; +static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43, + GPIO44, GPIO50}; +static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55}; +static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50, + GPIO51, GPIO52}; +static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59, + GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, + GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, + GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83}; +static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, + GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, + GPIO13, GPIO14, GPIO15}; +static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22, + GPIO24, GPIO26}; +static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35, + GPIO36}; +static const unsigned p168_smccs0_pin1[] = {GPIO18}; +static const unsigned p168_smccs1_pin1[] = {GPIO34}; +static const unsigned p168_smcrdy_pin1[] = {GPIO28}; +static const unsigned p168_ac97sysclk_pin1[] = {GPIO113}; +static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118, + GPIO119}; +static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25, + GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35, + GPIO36}; +static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121}; +static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112}; +static const unsigned p168_gpio86_pin1[] = {WAKEUP}; +static const unsigned p168_gpio86_pin2[] = {GPIO86}; +static const unsigned p168_gpio87_pin1[] = {GPIO87}; +static const unsigned p168_gpio87_pin2[] = {PWR_SDA}; +static const unsigned p168_gpio88_pin1[] = {GPIO88}; +static const unsigned p168_gpio88_pin2[] = {PWR_SCL}; + +static struct pxa3xx_pin_group pxa168_grps[] = { + GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1), + GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1), + GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1), + GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1), + GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1), + GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1), + GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1), + GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1), + GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1), + GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1), + GRP_168("jtag", JTAG, p168_jtag_pin1), + GRP_168("wakeup", WAKEUP, p168_wakeup_pin1), + GRP_168("i2c", I2C, p168_i2c_pin1), + GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1), + GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1), + GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1), + GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1), + GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1), + GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1), + GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1), + GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1), + GRP_168("eth", ETH, p168_eth_pin1), + GRP_168("eth rx", ETH_RX, p168_ethrx_pin1), + GRP_168("eth tx", ETH_TX, p168_ethtx_pin1), + GRP_168("msp", MSP, p168_msp_pin1), + GRP_168("ccic", CCIC, p168_ccic_pin1), + GRP_168("xd", XD, p168_xd_pin1), + GRP_168("lcd", LCD, p168_lcd_pin1), + GRP_168("dfio", DFIO, p168_dfio_pin1), + GRP_168("nand", NAND, p168_nand_pin1), + GRP_168("smc", SMC, p168_smc_pin1), + GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1), + GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1), + GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1), + GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1), + GRP_168("ac97", AC97, p168_ac97_pin1), + GRP_168("cf", CF, p168_cf_pin1), + GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1), + GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1), + GRP_168("gpio86-1", GPIO, p168_gpio86_pin1), + GRP_168("gpio86-2", GPIO, p168_gpio86_pin2), + GRP_168("gpio87-1", GPIO, p168_gpio87_pin1), + GRP_168("gpio87-2", GPIO, p168_gpio87_pin2), + GRP_168("gpio88-1", GPIO, p168_gpio88_pin1), + GRP_168("gpio88-2", GPIO, p168_gpio88_pin2), +}; + +static const char * const p168_uart1rx_grps[] = {"uart1rx-1"}; +static const char * const p168_uart1tx_grps[] = {"uart1tx-1"}; +static const char * const p168_uart3rx_grps[] = {"uart3rx-1"}; +static const char * const p168_uart3tx_grps[] = {"uart3tx-1"}; +static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"}; +static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"}; +static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"}; +static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"}; +static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"}; +static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"}; +static const char * const p168_i2c_grps[] = {"i2c"}; +static const char * const p168_pwri2c_grps[] = {"pwri2c"}; +static const char * const p168_mmc1_grps[] = {"mmc1 8p1"}; +static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"}; +static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"}; +static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"}; +static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"}; +static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"}; +static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"}; +static const char * const p168_eth_grps[] = {"eth"}; +static const char * const p168_ethrx_grps[] = {"eth rx"}; +static const char * const p168_ethtx_grps[] = {"eth tx"}; +static const char * const p168_msp_grps[] = {"msp"}; +static const char * const p168_ccic_grps[] = {"ccic"}; +static const char * const p168_xd_grps[] = {"xd"}; +static const char * const p168_lcd_grps[] = {"lcd"}; +static const char * const p168_dfio_grps[] = {"dfio"}; +static const char * const p168_nand_grps[] = {"nand"}; +static const char * const p168_smc_grps[] = {"smc"}; +static const char * const p168_smccs0_grps[] = {"smc cs0"}; +static const char * const p168_smccs1_grps[] = {"smc cs1"}; +static const char * const p168_smcrdy_grps[] = {"smc rdy"}; +static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"}; +static const char * const p168_ac97_grps[] = {"ac97"}; +static const char * const p168_cf_grps[] = {"cf"}; +static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"}; +static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"}; +static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; + +static struct pxa3xx_pmx_func pxa168_funcs[] = { + {"uart1 rx", ARRAY_AND_SIZE(p168_uart1rx_grps)}, + {"uart1 tx", ARRAY_AND_SIZE(p168_uart1tx_grps)}, + {"uart3 rx", ARRAY_AND_SIZE(p168_uart3rx_grps)}, + {"uart3 tx", ARRAY_AND_SIZE(p168_uart3tx_grps)}, + {"ssp1 rx", ARRAY_AND_SIZE(p168_ssp1rx_grps)}, + {"ssp1 tx", ARRAY_AND_SIZE(p168_ssp1tx_grps)}, + {"ssp4 rx", ARRAY_AND_SIZE(p168_ssp4rx_grps)}, + {"ssp4 tx", ARRAY_AND_SIZE(p168_ssp4tx_grps)}, + {"ssp5 rx", ARRAY_AND_SIZE(p168_ssp5rx_grps)}, + {"ssp5 tx", ARRAY_AND_SIZE(p168_ssp5tx_grps)}, + {"i2c", ARRAY_AND_SIZE(p168_i2c_grps)}, + {"pwri2c", ARRAY_AND_SIZE(p168_pwri2c_grps)}, + {"mmc1", ARRAY_AND_SIZE(p168_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p168_mmc2_data_grps)}, + {"mmc2 cmd", ARRAY_AND_SIZE(p168_mmc2_cmd_grps)}, + {"mmc2 clk", ARRAY_AND_SIZE(p168_mmc2_clk_grps)}, + {"mmc3", ARRAY_AND_SIZE(p168_mmc3_data_grps)}, + {"mmc3 cmd", ARRAY_AND_SIZE(p168_mmc3_cmd_grps)}, + {"mmc3 clk", ARRAY_AND_SIZE(p168_mmc3_clk_grps)}, + {"eth", ARRAY_AND_SIZE(p168_eth_grps)}, + {"eth rx", ARRAY_AND_SIZE(p168_ethrx_grps)}, + {"eth tx", ARRAY_AND_SIZE(p168_ethtx_grps)}, + {"msp", ARRAY_AND_SIZE(p168_msp_grps)}, + {"ccic", ARRAY_AND_SIZE(p168_ccic_grps)}, + {"xd", ARRAY_AND_SIZE(p168_xd_grps)}, + {"lcd", ARRAY_AND_SIZE(p168_lcd_grps)}, + {"dfio", ARRAY_AND_SIZE(p168_dfio_grps)}, + {"nand", ARRAY_AND_SIZE(p168_nand_grps)}, + {"smc", ARRAY_AND_SIZE(p168_smc_grps)}, + {"smc cs0", ARRAY_AND_SIZE(p168_smccs0_grps)}, + {"smc cs1", ARRAY_AND_SIZE(p168_smccs1_grps)}, + {"smc rdy", ARRAY_AND_SIZE(p168_smcrdy_grps)}, + {"ac97", ARRAY_AND_SIZE(p168_ac97_grps)}, + {"ac97 sysclk", ARRAY_AND_SIZE(p168_ac97sysclk_grps)}, + {"cf", ARRAY_AND_SIZE(p168_cf_grps)}, + {"kpmkin", ARRAY_AND_SIZE(p168_kpmkin_grps)}, + {"kpmkout", ARRAY_AND_SIZE(p168_kpmkout_grps)}, + {"gpio86", ARRAY_AND_SIZE(p168_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p168_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p168_gpio88_grps)}, +}; + +static struct pinctrl_desc pxa168_pctrl_desc = { + .name = "pxa168-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa168_info = { + .mfp = pxa168_mfp, + .num_mfp = ARRAY_SIZE(pxa168_mfp), + .grps = pxa168_grps, + .num_grps = ARRAY_SIZE(pxa168_grps), + .funcs = pxa168_funcs, + .num_funcs = ARRAY_SIZE(pxa168_funcs), + .num_gpio = 128, + .desc = &pxa168_pctrl_desc, + .pads = pxa168_pads, + .num_pads = ARRAY_SIZE(pxa168_pads), + + .cputype = PINCTRL_PXA168, + .ds_mask = PXA168_DS_MASK, + .ds_shift = PXA168_DS_SHIFT, +}; + +static int __devinit pxa168_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa168_info); +} + +static int __devexit pxa168_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa168_pinmux_driver = { + .driver = { + .name = "pxa168-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa168_pinmux_probe, + .remove = __devexit_p(pxa168_pinmux_remove), +}; + +static int __init pxa168_pinmux_init(void) +{ + return platform_driver_register(&pxa168_pinmux_driver); +} +core_initcall_sync(pxa168_pinmux_init); + +static void __exit pxa168_pinmux_exit(void) +{ + platform_driver_unregister(&pxa168_pinmux_driver); +} +module_exit(pxa168_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c new file mode 100644 index 00000000000..079dce0e93e --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -0,0 +1,244 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = { + .name = "PXA3xx GPIO", + .id = 0, + .base = 0, + .pin_base = 0, +}; + +static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return -EINVAL; + return 0; +} + +static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev, + unsigned selector) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return NULL; + return info->grps[selector].name; +} + +static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev, + unsigned selector, + const unsigned **pins, + unsigned *num_pins) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (selector >= info->num_grps) + return -EINVAL; + *pins = info->grps[selector].pins; + *num_pins = info->grps[selector].npins; + return 0; +} + +static struct pinctrl_ops pxa3xx_pctrl_ops = { + .list_groups = pxa3xx_list_groups, + .get_group_name = pxa3xx_get_group_name, + .get_group_pins = pxa3xx_get_group_pins, +}; + +static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + if (func >= info->num_funcs) + return -EINVAL; + return 0; +} + +static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev, + unsigned func) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + return info->funcs[func].name; +} + +static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func, + const char * const **groups, + unsigned * const num_groups) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + *groups = info->funcs[func].groups; + *num_groups = info->funcs[func].num_groups; + return 0; +} + +/* Return function number. If failure, return negative value. */ +static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux) +{ + int i; + for (i = 0; i < PXA3xx_MAX_MUX; i++) { + if (mfp->func[i] == mux) + break; + } + if (i >= PXA3xx_MAX_MUX) + return -EINVAL; + return i; +} + +/* check whether current pin configuration is valid. Negative for failure */ +static int match_group_mux(struct pxa3xx_pin_group *grp, + struct pxa3xx_pinmux_info *info, + unsigned mux) +{ + int i, pin, ret = 0; + for (i = 0; i < grp->npins; i++) { + pin = grp->pins[i]; + ret = match_mux(&info->mfp[pin], mux); + if (ret < 0) { + dev_err(info->dev, "Can't find mux %d on pin%d\n", + mux, pin); + break; + } + } + return ret; +} + +static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + struct pxa3xx_pin_group *pin_grp = &info->grps[group]; + unsigned int data; + int i, mfpr, pin, pin_func; + + if (!pin_grp->npins || + (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) { + dev_err(info->dev, "Failed to set the pin group: %d\n", group); + return -EINVAL; + } + for (i = 0; i < pin_grp->npins; i++) { + pin = pin_grp->pins[i]; + pin_func = match_mux(&info->mfp[pin], pin_grp->mux); + mfpr = info->mfp[pin].mfpr; + data = readl_relaxed(info->virt_base + mfpr); + data &= ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + } + return 0; +} + +static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func, + unsigned group) +{ +} + +static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev, + struct pinctrl_gpio_range *range, + unsigned pin) +{ + struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev); + unsigned int data; + int pin_func, mfpr; + + pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO); + if (pin_func < 0) { + dev_err(info->dev, "No GPIO function on pin%d (%s)\n", + pin, info->pads[pin].name); + return -EINVAL; + } + mfpr = info->mfp[pin].mfpr; + /* write gpio function into mfpr register */ + data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK; + data |= pin_func; + writel_relaxed(data, info->virt_base + mfpr); + return 0; +} + +static struct pinmux_ops pxa3xx_pmx_ops = { + .list_functions = pxa3xx_pmx_list_func, + .get_function_name = pxa3xx_pmx_get_func_name, + .get_function_groups = pxa3xx_pmx_get_groups, + .enable = pxa3xx_pmx_enable, + .disable = pxa3xx_pmx_disable, + .gpio_request_enable = pxa3xx_pmx_request_gpio, +}; + +int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info) +{ + struct pinctrl_desc *desc; + struct resource *res; + int ret = 0; + + if (!info || !info->cputype) + return -EINVAL; + desc = info->desc; + desc->pins = info->pads; + desc->npins = info->num_pads; + desc->pctlops = &pxa3xx_pctrl_ops; + desc->pmxops = &pxa3xx_pmx_ops; + info->dev = &pdev->dev; + pxa3xx_pinctrl_gpio_range.npins = info->num_gpio; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENOENT; + info->phy_base = res->start; + info->phy_size = resource_size(res); + info->virt_base = ioremap(info->phy_base, info->phy_size); + if (!info->virt_base) + return -ENOMEM; + info->pctrl = pinctrl_register(desc, &pdev->dev, info); + if (!info->pctrl) { + dev_err(&pdev->dev, "failed to register PXA pinmux driver\n"); + ret = -EINVAL; + goto err; + } + pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range); + platform_set_drvdata(pdev, info); + return 0; +err: + iounmap(info->virt_base); + return ret; +} + +int pxa3xx_pinctrl_unregister(struct platform_device *pdev) +{ + struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev); + + pinctrl_unregister(info->pctrl); + iounmap(info->virt_base); + platform_set_drvdata(pdev, NULL); + return 0; +} + +static int __init pxa3xx_pinctrl_init(void) +{ + pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n"); + return 0; +} +core_initcall_sync(pxa3xx_pinctrl_init); + +static void __exit pxa3xx_pinctrl_exit(void) +{ +} +module_exit(pxa3xx_pinctrl_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h new file mode 100644 index 00000000000..8135744d659 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.h @@ -0,0 +1,264 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#ifndef __PINCTRL_PXA3XX_H + +#include +#include + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#define PXA3xx_MUX_GPIO 0 + +#define PXA3xx_MAX_MUX 8 +#define MFPR_FUNC_MASK 0x7 + +enum pxa_cpu_type { + PINCTRL_INVALID = 0, + PINCTRL_PXA300, + PINCTRL_PXA310, + PINCTRL_PXA320, + PINCTRL_PXA168, + PINCTRL_PXA910, + PINCTRL_PXA930, + PINCTRL_PXA955, + PINCTRL_MMP2, + PINCTRL_MAX, +}; + +struct pxa3xx_mfp_pin { + const char *name; + const unsigned int pin; + const unsigned int mfpr; /* register offset */ + const unsigned short func[8]; +}; + +struct pxa3xx_pin_group { + const char *name; + const unsigned mux; + const unsigned *pins; + const unsigned npins; +}; + +struct pxa3xx_pmx_func { + const char *name; + const char * const * groups; + const unsigned num_groups; +}; + +struct pxa3xx_pinmux_info { + struct device *dev; + struct pinctrl_dev *pctrl; + enum pxa_cpu_type cputype; + unsigned int phy_base; + unsigned int phy_size; + void __iomem *virt_base; + + struct pxa3xx_mfp_pin *mfp; + unsigned int num_mfp; + struct pxa3xx_pin_group *grps; + unsigned int num_grps; + struct pxa3xx_pmx_func *funcs; + unsigned int num_funcs; + unsigned int num_gpio; + struct pinctrl_desc *desc; + struct pinctrl_pin_desc *pads; + unsigned int num_pads; + + unsigned ds_mask; /* drive strength mask */ + unsigned ds_shift; /* drive strength shift */ + unsigned slp_mask; /* sleep mask */ + unsigned slp_input_low; + unsigned slp_input_high; + unsigned slp_output_low; + unsigned slp_output_high; + unsigned slp_float; +}; + +enum pxa3xx_pin_list { + GPIO0 = 0, + GPIO1, + GPIO2, + GPIO3, + GPIO4, + GPIO5, + GPIO6, + GPIO7, + GPIO8, + GPIO9, + GPIO10, /* 10 */ + GPIO11, + GPIO12, + GPIO13, + GPIO14, + GPIO15, + GPIO16, + GPIO17, + GPIO18, + GPIO19, + GPIO20, /* 20 */ + GPIO21, + GPIO22, + GPIO23, + GPIO24, + GPIO25, + GPIO26, + GPIO27, + GPIO28, + GPIO29, + GPIO30, /* 30 */ + GPIO31, + GPIO32, + GPIO33, + GPIO34, + GPIO35, + GPIO36, + GPIO37, + GPIO38, + GPIO39, + GPIO40, /* 40 */ + GPIO41, + GPIO42, + GPIO43, + GPIO44, + GPIO45, + GPIO46, + GPIO47, + GPIO48, + GPIO49, + GPIO50, /* 50 */ + GPIO51, + GPIO52, + GPIO53, + GPIO54, + GPIO55, + GPIO56, + GPIO57, + GPIO58, + GPIO59, + GPIO60, /* 60 */ + GPIO61, + GPIO62, + GPIO63, + GPIO64, + GPIO65, + GPIO66, + GPIO67, + GPIO68, + GPIO69, + GPIO70, /* 70 */ + GPIO71, + GPIO72, + GPIO73, + GPIO74, + GPIO75, + GPIO76, + GPIO77, + GPIO78, + GPIO79, + GPIO80, /* 80 */ + GPIO81, + GPIO82, + GPIO83, + GPIO84, + GPIO85, + GPIO86, + GPIO87, + GPIO88, + GPIO89, + GPIO90, /* 90 */ + GPIO91, + GPIO92, + GPIO93, + GPIO94, + GPIO95, + GPIO96, + GPIO97, + GPIO98, + GPIO99, + GPIO100, /* 100 */ + GPIO101, + GPIO102, + GPIO103, + GPIO104, + GPIO105, + GPIO106, + GPIO107, + GPIO108, + GPIO109, + GPIO110, /* 110 */ + GPIO111, + GPIO112, + GPIO113, + GPIO114, + GPIO115, + GPIO116, + GPIO117, + GPIO118, + GPIO119, + GPIO120, /* 120 */ + GPIO121, + GPIO122, + GPIO123, + GPIO124, + GPIO125, + GPIO126, + GPIO127, + GPIO128, + GPIO129, + GPIO130, /* 130 */ + GPIO131, + GPIO132, + GPIO133, + GPIO134, + GPIO135, + GPIO136, + GPIO137, + GPIO138, + GPIO139, + GPIO140, /* 140 */ + GPIO141, + GPIO142, + GPIO143, + GPIO144, + GPIO145, + GPIO146, + GPIO147, + GPIO148, + GPIO149, + GPIO150, /* 150 */ + GPIO151, + GPIO152, + GPIO153, + GPIO154, + GPIO155, + GPIO156, + GPIO157, + GPIO158, + GPIO159, + GPIO160, /* 160 */ + GPIO161, + GPIO162, + GPIO163, + GPIO164, + GPIO165, + GPIO166, + GPIO167, + GPIO168, + GPIO169, +}; + +extern int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info); +extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev); +#endif /* __PINCTRL_PXA3XX_H */ diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c new file mode 100644 index 00000000000..c72ab4b9cc8 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa910.c @@ -0,0 +1,1007 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa910.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA910_DS_MASK 0x1800 +#define PXA910_DS_SHIFT 11 +#define PXA910_SLEEP_MASK 0x38 +#define PXA910_SLEEP_SELECT (1 << 9) +#define PXA910_SLEEP_DATA (1 << 8) +#define PXA910_SLEEP_DIR (1 << 7) + +#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA910_MUX_##f0, \ + PXA910_MUX_##f1, \ + PXA910_MUX_##f2, \ + PXA910_MUX_##f3, \ + PXA910_MUX_##f4, \ + PXA910_MUX_##f5, \ + PXA910_MUX_##f6, \ + PXA910_MUX_##f7, \ + }, \ + } + +#define GRP_910(a, m, p) \ + { .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 170 pins */ +enum pxa910_pin_list { + /* 0~127: GPIO0~GPIO127 */ + ND_IO15 = 128, + ND_IO14, + ND_IO13, /* 130 */ + ND_IO12, + ND_IO11, + ND_IO10, + ND_IO9, + ND_IO8, + ND_IO7, + ND_IO6, + ND_IO5, + ND_IO4, + ND_IO3, /* 140 */ + ND_IO2, + ND_IO1, + ND_IO0, + ND_NCS0, + ND_NCS1, + SM_NCS0, + SM_NCS1, + ND_NWE, + ND_NRE, + ND_CLE, /* 150 */ + ND_ALE, + SM_SCLK, + ND_RDY0, + SM_ADV, + ND_RDY1, + SM_ADVMUX, + SM_RDY, + MMC1_DAT7, + MMC1_DAT6, + MMC1_DAT5, /* 160 */ + MMC1_DAT4, + MMC1_DAT3, + MMC1_DAT2, + MMC1_DAT1, + MMC1_DAT0, + MMC1_CMD, + MMC1_CLK, + MMC1_CD, + VCXO_OUT, +}; + +enum pxa910_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA910_MUX_GPIO = 0, + PXA910_MUX_NAND, + PXA910_MUX_USIM2, + PXA910_MUX_EXT_DMA, + PXA910_MUX_EXT_INT, + PXA910_MUX_MMC1, + PXA910_MUX_MMC2, + PXA910_MUX_MMC3, + PXA910_MUX_SM_INT, + PXA910_MUX_PRI_JTAG, + PXA910_MUX_SEC1_JTAG, + PXA910_MUX_SEC2_JTAG, + PXA910_MUX_RESET, /* SLAVE RESET OUT */ + PXA910_MUX_CLK_REQ, + PXA910_MUX_VCXO_REQ, + PXA910_MUX_VCXO_OUT, + PXA910_MUX_VCXO_REQ2, + PXA910_MUX_VCXO_OUT2, + PXA910_MUX_SPI, + PXA910_MUX_SPI2, + PXA910_MUX_GSSP, + PXA910_MUX_SSP0, + PXA910_MUX_SSP1, + PXA910_MUX_SSP2, + PXA910_MUX_DSSP2, + PXA910_MUX_DSSP3, + PXA910_MUX_UART0, + PXA910_MUX_UART1, + PXA910_MUX_UART2, + PXA910_MUX_TWSI, + PXA910_MUX_CCIC, + PXA910_MUX_PWM0, + PXA910_MUX_PWM1, + PXA910_MUX_PWM2, + PXA910_MUX_PWM3, + PXA910_MUX_HSL, + PXA910_MUX_ONE_WIRE, + PXA910_MUX_LCD, + PXA910_MUX_DAC_ST23, + PXA910_MUX_ULPI, + PXA910_MUX_TB, + PXA910_MUX_KP_MK, + PXA910_MUX_KP_DK, + PXA910_MUX_TCU_GPOA, + PXA910_MUX_TCU_GPOB, + PXA910_MUX_ROT, + PXA910_MUX_TDS, + PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */ + PXA910_MUX_MN_CLK, /* MN CLK OUT */ + PXA910_MUX_SMC, + PXA910_MUX_SM_ADDR18, + PXA910_MUX_SM_ADDR19, + PXA910_MUX_SM_ADDR20, + PXA910_MUX_NONE = 0xffff, +}; + + +static struct pinctrl_pin_desc pxa910_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(ND_IO15, "ND_IO15"), + PINCTRL_PIN(ND_IO14, "ND_IO14"), + PINCTRL_PIN(ND_IO13, "ND_IO13"), + PINCTRL_PIN(ND_IO12, "ND_IO12"), + PINCTRL_PIN(ND_IO11, "ND_IO11"), + PINCTRL_PIN(ND_IO10, "ND_IO10"), + PINCTRL_PIN(ND_IO9, "ND_IO9"), + PINCTRL_PIN(ND_IO8, "ND_IO8"), + PINCTRL_PIN(ND_IO7, "ND_IO7"), + PINCTRL_PIN(ND_IO6, "ND_IO6"), + PINCTRL_PIN(ND_IO5, "ND_IO5"), + PINCTRL_PIN(ND_IO4, "ND_IO4"), + PINCTRL_PIN(ND_IO3, "ND_IO3"), + PINCTRL_PIN(ND_IO2, "ND_IO2"), + PINCTRL_PIN(ND_IO1, "ND_IO1"), + PINCTRL_PIN(ND_IO0, "ND_IO0"), + PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"), + PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"), + PINCTRL_PIN(SM_NCS0, "SM_NCS0"), + PINCTRL_PIN(SM_NCS1, "SM_NCS1"), + PINCTRL_PIN(ND_NWE, "ND_NWE"), + PINCTRL_PIN(ND_NRE, "ND_NRE"), + PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"), + PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"), + PINCTRL_PIN(SM_SCLK, "SM_SCLK"), + PINCTRL_PIN(ND_RDY0, "ND_RDY0"), + PINCTRL_PIN(SM_ADV, "SM_ADV"), + PINCTRL_PIN(ND_RDY1, "ND_RDY1"), + PINCTRL_PIN(SM_RDY, "SM_RDY"), + PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"), + PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"), + PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"), + PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"), + PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"), + PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"), + PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"), + PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"), + PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"), + PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"), + PINCTRL_PIN(MMC1_CD, "MMC1 CD"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin pxa910_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_910(GPIO0, 0x0DC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO1, 0x0E0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO2, 0x0E4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO3, 0x0E8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO4, 0x0EC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO5, 0x0F0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO6, 0x0F4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO7, 0x0F8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO8, 0x0FC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO9, 0x100, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO10, 0x104, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO11, 0x108, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO12, 0x10C, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO13, 0x110, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO14, 0x114, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO15, 0x118, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO16, 0x11C, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO17, 0x120, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO18, 0x124, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO19, 0x128, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO20, 0x12C, GPIO, SSP1, NONE, NONE, VCXO_OUT, NONE, NONE, NONE), + MFPR_910(GPIO21, 0x130, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO22, 0x134, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO23, 0x138, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO24, 0x13C, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO25, 0x140, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO26, 0x144, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO27, 0x148, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO28, 0x14C, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO29, 0x150, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO30, 0x154, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO31, 0x158, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO32, 0x15C, GPIO, UART0, DAC_ST23, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO33, 0x160, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO34, 0x164, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO35, 0x168, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO36, 0x16C, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO37, 0x170, GPIO, MMC2, NONE, NONE, NONE, SPI, HSL, NONE), + MFPR_910(GPIO38, 0x174, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO39, 0x178, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO40, 0x17C, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO41, 0x180, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO42, 0x184, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO43, 0x188, GPIO, UART1, NONE, DAC_ST23, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO44, 0x18C, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO45, 0x190, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO46, 0x194, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO47, 0x198, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO48, 0x19C, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO49, 0x1A0, GPIO, SSP0, UART0, VCXO_REQ, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO50, 0x1A4, GPIO, SSP0, UART0, VCXO_OUT, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO51, 0x1A8, GPIO, UART2, PWM1, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO52, 0x1AC, GPIO, UART2, DAC_ST23, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO53, 0x1B0, GPIO, UART2, TWSI, NONE, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO54, 0x1B4, GPIO, UART2, TWSI, SSP0, NONE, NONE, DSSP3, NONE), + MFPR_910(GPIO55, 0x2F0, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO56, 0x2F4, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO57, 0x2F8, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO58, 0x2FC, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO59, 0x300, TDS, GPIO, TCU_GPOA, TCU_GPOB, ONE_WIRE, NONE, NONE, NONE), + MFPR_910(GPIO60, 0x304, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO61, 0x308, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO62, 0x30C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO63, 0x310, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO64, 0x314, GPIO, SPI2, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO65, 0x318, GPIO, SPI2, NONE, NONE, NONE, NONE, ONE_WIRE, HSL), + MFPR_910(GPIO66, 0x31C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO67, 0x1B8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO68, 0x1BC, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO69, 0x1C0, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO70, 0x1C4, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO71, 0x1C8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO72, 0x1CC, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO73, 0x1D0, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO74, 0x1D4, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO75, 0x1D8, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO76, 0x1DC, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO77, 0x1E0, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO78, 0x1E4, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO79, 0x1E8, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO80, 0x1EC, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO81, 0x1F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO82, 0x1F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO83, 0x1F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO84, 0x1FC, GPIO, LCD, VCXO_REQ2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO85, 0x200, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO86, 0x204, GPIO, LCD, VCXO_OUT2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO87, 0x208, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO88, 0x20C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO89, 0x210, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO90, 0x214, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO91, 0x218, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO92, 0x21C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO93, 0x220, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO94, 0x224, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO95, 0x228, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO96, 0x22C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO97, 0x230, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO98, 0x234, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO99, 0x0B0, MMC1, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO100, 0x238, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO101, 0x23C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO102, 0x240, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO103, 0x244, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO104, 0x248, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO105, 0x24C, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO106, 0x250, GPIO, LCD, DSSP3, ONE_WIRE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO107, 0x254, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO108, 0x258, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO109, 0x25C, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO110, 0x298, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO111, 0x29C, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO112, 0x2A0, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO113, 0x2A4, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO114, 0x2A8, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO115, 0x2AC, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO116, 0x2B0, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO117, 0x0B4, PRI_JTAG, GPIO, PWM0, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO118, 0x0B8, PRI_JTAG, GPIO, PWM1, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO119, 0x0BC, PRI_JTAG, GPIO, PWM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO120, 0x0C0, PRI_JTAG, GPIO, PWM3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO121, 0x32C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO122, 0x0C8, RESET, GPIO, 32K_CLK, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO123, 0x0CC, CLK_REQ, GPIO, ONE_WIRE, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(GPIO124, 0x0D0, GPIO, MN_CLK, DAC_ST23, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO125, 0x0D4, VCXO_REQ, GPIO, NONE, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(GPIO126, 0x06C, GPIO, SMC, NONE, SM_ADDR18, NONE, EXT_DMA, NONE, NONE), + MFPR_910(GPIO127, 0x070, GPIO, SMC, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO15, 0x004, NAND, GPIO, USIM2, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO14, 0x008, NAND, GPIO, USIM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO13, 0x00C, NAND, GPIO, USIM2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO12, 0x010, NAND, GPIO, SSP2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO11, 0x014, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO10, 0x018, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO9, 0x01C, NAND, GPIO, SSP2, NONE, VCXO_OUT2, NONE, NONE, NONE), + MFPR_910(ND_IO8, 0x020, NAND, GPIO, NONE, NONE, PWM3, NONE, NONE, NONE), + MFPR_910(ND_IO7, 0x024, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO6, 0x028, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO5, 0x02C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO4, 0x030, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO3, 0x034, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO2, 0x038, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO1, 0x03C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO0, 0x040, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS0, 0x044, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS1, 0x048, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS0, 0x04C, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS1, 0x050, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NWE, 0x054, GPIO, NAND, NONE, SM_ADDR20, NONE, SMC, NONE, NONE), + MFPR_910(ND_NRE, 0x058, GPIO, NAND, NONE, SMC, NONE, EXT_DMA, NONE, NONE), + MFPR_910(ND_CLE, 0x05C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_ALE, 0x060, GPIO, NAND, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_SCLK, 0x064, MMC3, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY0, 0x068, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADV, 0x074, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY1, 0x078, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADVMUX, 0x07C, SMC, GPIO, NONE, SM_ADDR19, NONE, NONE, NONE, NONE), + MFPR_910(SM_RDY, 0x080, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT7, 0x084, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT6, 0x088, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT5, 0x08C, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT4, 0x090, MMC1, GPIO, NONE, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT3, 0x094, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT2, 0x098, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT1, 0x09C, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT0, 0x0A0, MMC1, HSL, SEC2_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CMD, 0x0A4, MMC1, HSL, SEC1_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CLK, 0x0A8, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CD, 0x0AC, MMC1, GPIO, SEC1_JTAG, NONE, NONE, NONE, NONE, NONE), + MFPR_910(VCXO_OUT, 0x0D8, VCXO_OUT, PWM3, NONE, NONE, NONE, NONE, NONE, NONE), +}; + + +static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69}; +static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13}; +static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD, + MMC1_CLK, MMC1_CD, GPIO99}; +static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42}; +static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO49, GPIO50}; +static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK}; +static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48}; +static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32}; +static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46}; +static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44}; +static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52}; +static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52}; +static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54}; +static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80}; +static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84, + GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, + GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101, + GPIO102, GPIO103}; +static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108}; +static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37}; +static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71}; +static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65}; +static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103}; +static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105}; +static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113}; +static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109}; +static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_CLK}; +static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24}; +static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24}; +static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, + MMC1_CMD}; +static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9}; +static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned p910_pwm0_pin1[] = {GPIO117}; +static const unsigned p910_pwm1_pin1[] = {GPIO118}; +static const unsigned p910_pwm1_pin2[] = {GPIO51}; +static const unsigned p910_pwm2_pin1[] = {GPIO119}; +static const unsigned p910_pwm3_pin1[] = {GPIO120}; +static const unsigned p910_pwm3_pin2[] = {ND_IO8}; +static const unsigned p910_pwm3_pin3[] = {VCXO_OUT}; +static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119, + GPIO120}; +static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_CMD, MMC1_CD}; +static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CLK}; +static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64, + GPIO65, GPIO66}; +static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CMD, MMC1_CLK}; +static const unsigned p910_w1_pin1[] = {GPIO59}; +static const unsigned p910_w1_pin2[] = {GPIO65}; +static const unsigned p910_w1_pin3[] = {GPIO106}; +static const unsigned p910_w1_pin4[] = {GPIO123}; +static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, + GPIO14, GPIO15}; +static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12}; +static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58, + GPIO59}; +static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59}; +static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17}; +static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58}; +static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4}; +static const unsigned p910_ext_dma0_pin1[] = {GPIO72}; +static const unsigned p910_ext_dma0_pin2[] = {ND_IO15}; +static const unsigned p910_ext_dma0_pin3[] = {ND_NRE}; +static const unsigned p910_ext_dma1_pin1[] = {GPIO73}; +static const unsigned p910_ext_dma1_pin2[] = {GPIO123}; +static const unsigned p910_ext_dma1_pin3[] = {GPIO126}; +static const unsigned p910_ext_dma2_pin1[] = {GPIO74}; +static const unsigned p910_ext0_int_pin1[] = {GPIO44}; +static const unsigned p910_ext0_int_pin2[] = {ND_IO13}; +static const unsigned p910_ext1_int_pin1[] = {GPIO45}; +static const unsigned p910_ext1_int_pin2[] = {ND_IO12}; +static const unsigned p910_ext2_int_pin1[] = {GPIO46}; +static const unsigned p910_ext2_int_pin2[] = {GPIO125}; +static const unsigned p910_dac_st23_pin1[] = {GPIO32}; +static const unsigned p910_dac_st23_pin2[] = {GPIO43}; +static const unsigned p910_dac_st23_pin3[] = {GPIO52}; +static const unsigned p910_dac_st23_pin4[] = {GPIO124}; +static const unsigned p910_vcxo_out_pin1[] = {GPIO50}; +static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT}; +static const unsigned p910_vcxo_out_pin3[] = {GPIO20}; +static const unsigned p910_vcxo_req_pin1[] = {GPIO49}; +static const unsigned p910_vcxo_req_pin2[] = {GPIO125}; +static const unsigned p910_vcxo_out2_pin1[] = {GPIO86}; +static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9}; +static const unsigned p910_vcxo_req2_pin1[] = {GPIO84}; +static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12, + ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE, + ND_ALE, ND_RDY0}; +static const unsigned p910_gpio0_pin1[] = {GPIO0}; +static const unsigned p910_gpio0_pin2[] = {SM_ADV}; +static const unsigned p910_gpio1_pin1[] = {GPIO1}; +static const unsigned p910_gpio1_pin2[] = {ND_RDY1}; +static const unsigned p910_gpio2_pin1[] = {GPIO2}; +static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX}; +static const unsigned p910_gpio3_pin1[] = {GPIO3}; +static const unsigned p910_gpio3_pin2[] = {SM_RDY}; +static const unsigned p910_gpio20_pin1[] = {GPIO20}; +static const unsigned p910_gpio20_pin2[] = {ND_IO15}; +static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6}; +static const unsigned p910_gpio21_pin1[] = {GPIO21}; +static const unsigned p910_gpio21_pin2[] = {ND_IO14}; +static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5}; +static const unsigned p910_gpio22_pin1[] = {GPIO22}; +static const unsigned p910_gpio22_pin2[] = {ND_IO13}; +static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4}; +static const unsigned p910_gpio23_pin1[] = {GPIO23}; +static const unsigned p910_gpio23_pin2[] = {ND_IO12}; +static const unsigned p910_gpio23_pin3[] = {MMC1_CD}; +static const unsigned p910_gpio24_pin1[] = {GPIO24}; +static const unsigned p910_gpio24_pin2[] = {ND_IO11}; +static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7}; +static const unsigned p910_gpio25_pin1[] = {GPIO25}; +static const unsigned p910_gpio25_pin2[] = {ND_IO10}; +static const unsigned p910_gpio26_pin1[] = {GPIO26}; +static const unsigned p910_gpio26_pin2[] = {ND_IO9}; +static const unsigned p910_gpio27_pin1[] = {GPIO27}; +static const unsigned p910_gpio27_pin2[] = {ND_IO8}; +static const unsigned p910_gpio85_pin1[] = {GPIO85}; +static const unsigned p910_gpio85_pin2[] = {ND_NCS0}; +static const unsigned p910_gpio86_pin1[] = {GPIO86}; +static const unsigned p910_gpio86_pin2[] = {ND_NCS1}; +static const unsigned p910_gpio87_pin1[] = {GPIO87}; +static const unsigned p910_gpio87_pin2[] = {SM_NCS0}; +static const unsigned p910_gpio88_pin1[] = {GPIO88}; +static const unsigned p910_gpio88_pin2[] = {SM_NCS1}; +static const unsigned p910_gpio89_pin1[] = {GPIO89}; +static const unsigned p910_gpio89_pin2[] = {ND_NWE}; +static const unsigned p910_gpio90_pin1[] = {GPIO90}; +static const unsigned p910_gpio90_pin2[] = {ND_NRE}; +static const unsigned p910_gpio91_pin1[] = {GPIO91}; +static const unsigned p910_gpio91_pin2[] = {ND_ALE}; +static const unsigned p910_gpio92_pin1[] = {GPIO92}; +static const unsigned p910_gpio92_pin2[] = {ND_RDY0}; + +static struct pxa3xx_pin_group pxa910_grps[] = { + GRP_910("usim2 3p1", USIM2, p910_usim2_pin1), + GRP_910("usim2 3p2", USIM2, p910_usim2_pin2), + GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1), + GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1), + GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1), + GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2), + GRP_910("uart0 4p", UART0, p910_uart0_pin1), + GRP_910("uart1 2p1", UART1, p910_uart1_pin1), + GRP_910("uart1 2p2", UART1, p910_uart1_pin2), + GRP_910("uart1 2p3", UART1, p910_uart1_pin3), + GRP_910("uart1 4p4", UART1, p910_uart1_pin4), + GRP_910("uart1 4p5", UART1, p910_uart1_pin5), + GRP_910("uart2 2p1", UART2, p910_uart2_pin1), + GRP_910("uart2 2p2", UART2, p910_uart2_pin2), + GRP_910("uart2 4p3", UART2, p910_uart2_pin3), + GRP_910("uart2 4p4", UART2, p910_uart2_pin4), + GRP_910("twsi 2p1", TWSI, p910_twsi_pin1), + GRP_910("twsi 2p2", TWSI, p910_twsi_pin2), + GRP_910("twsi 2p3", TWSI, p910_twsi_pin3), + GRP_910("ccic", CCIC, p910_ccic_pin1), + GRP_910("lcd", LCD, p910_lcd_pin1), + GRP_910("spi 4p1", SPI, p910_spi_pin1), + GRP_910("spi 4p2", SPI, p910_spi_pin2), + GRP_910("spi 5p3", SPI, p910_spi_pin3), + GRP_910("spi 5p4", SPI, p910_spi_pin4), + GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1), + GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2), + GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3), + GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1), + GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2), + GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3), + GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1), + GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2), + GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3), + GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4), + GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1), + GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2), + GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1), + GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2), + GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3), + GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4), + GRP_910("gssp", GSSP, p910_gssp_pin1), + GRP_910("pwm0", PWM0, p910_pwm0_pin1), + GRP_910("pwm1-1", PWM1, p910_pwm1_pin1), + GRP_910("pwm1-2", PWM1, p910_pwm1_pin2), + GRP_910("pwm2", PWM2, p910_pwm2_pin1), + GRP_910("pwm3-1", PWM3, p910_pwm3_pin1), + GRP_910("pwm3-2", PWM3, p910_pwm3_pin2), + GRP_910("pwm3-3", PWM3, p910_pwm3_pin3), + GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1), + GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1), + GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1), + GRP_910("hsl 6p1", HSL, p910_hsl_pin1), + GRP_910("hsl 6p2", HSL, p910_hsl_pin2), + GRP_910("hsl 6p3", HSL, p910_hsl_pin3), + GRP_910("w1-1", ONE_WIRE, p910_w1_pin1), + GRP_910("w1-2", ONE_WIRE, p910_w1_pin2), + GRP_910("w1-3", ONE_WIRE, p910_w1_pin3), + GRP_910("w1-4", ONE_WIRE, p910_w1_pin4), + GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1), + GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2), + GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1), + GRP_910("tds 5p1", TDS, p910_tds_pin1), + GRP_910("tds 4p2", TDS, p910_tds_pin2), + GRP_910("tb 4p1", TB, p910_tb_pin1), + GRP_910("tb 4p2", TB, p910_tb_pin2), + GRP_910("tb 4p3", TB, p910_tb_pin3), + GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1), + GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2), + GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3), + GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1), + GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2), + GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3), + GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1), + GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1), + GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2), + GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1), + GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2), + GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1), + GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2), + GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1), + GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2), + GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3), + GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4), + GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1), + GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2), + GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3), + GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1), + GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2), + GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1), + GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2), + GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1), + GRP_910("ulpi", ULPI, p910_ulpi_pin1), + GRP_910("nand", NAND, p910_nand_pin1), + GRP_910("gpio0-1", GPIO, p910_gpio0_pin1), + GRP_910("gpio0-2", GPIO, p910_gpio0_pin2), + GRP_910("gpio1-1", GPIO, p910_gpio1_pin1), + GRP_910("gpio1-2", GPIO, p910_gpio1_pin2), + GRP_910("gpio2-1", GPIO, p910_gpio2_pin1), + GRP_910("gpio2-2", GPIO, p910_gpio2_pin2), + GRP_910("gpio3-1", GPIO, p910_gpio3_pin1), + GRP_910("gpio3-2", GPIO, p910_gpio3_pin2), + GRP_910("gpio20-1", GPIO, p910_gpio20_pin1), + GRP_910("gpio20-2", GPIO, p910_gpio20_pin2), + GRP_910("gpio21-1", GPIO, p910_gpio21_pin1), + GRP_910("gpio21-2", GPIO, p910_gpio21_pin2), + GRP_910("gpio22-1", GPIO, p910_gpio22_pin1), + GRP_910("gpio22-2", GPIO, p910_gpio22_pin2), + GRP_910("gpio23-1", GPIO, p910_gpio23_pin1), + GRP_910("gpio23-2", GPIO, p910_gpio23_pin2), + GRP_910("gpio24-1", GPIO, p910_gpio24_pin1), + GRP_910("gpio24-2", GPIO, p910_gpio24_pin2), + GRP_910("gpio25-1", GPIO, p910_gpio25_pin1), + GRP_910("gpio25-2", GPIO, p910_gpio25_pin2), + GRP_910("gpio26-1", GPIO, p910_gpio26_pin1), + GRP_910("gpio26-2", GPIO, p910_gpio26_pin2), + GRP_910("gpio27-1", GPIO, p910_gpio27_pin1), + GRP_910("gpio27-2", GPIO, p910_gpio27_pin2), + GRP_910("gpio85-1", GPIO, p910_gpio85_pin1), + GRP_910("gpio85-2", GPIO, p910_gpio85_pin2), + GRP_910("gpio86-1", GPIO, p910_gpio86_pin1), + GRP_910("gpio86-2", GPIO, p910_gpio86_pin2), + GRP_910("gpio87-1", GPIO, p910_gpio87_pin1), + GRP_910("gpio87-2", GPIO, p910_gpio87_pin2), + GRP_910("gpio88-1", GPIO, p910_gpio88_pin1), + GRP_910("gpio88-2", GPIO, p910_gpio88_pin2), + GRP_910("gpio89-1", GPIO, p910_gpio89_pin1), + GRP_910("gpio89-2", GPIO, p910_gpio89_pin2), + GRP_910("gpio90-1", GPIO, p910_gpio90_pin1), + GRP_910("gpio90-2", GPIO, p910_gpio90_pin2), + GRP_910("gpio91-1", GPIO, p910_gpio91_pin1), + GRP_910("gpio91-2", GPIO, p910_gpio91_pin2), + GRP_910("gpio92-1", GPIO, p910_gpio92_pin1), + GRP_910("gpio92-2", GPIO, p910_gpio92_pin2), +}; + +static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"}; +static const char * const p910_mmc1_grps[] = {"mmc1 12p"}; +static const char * const p910_mmc2_grps[] = {"mmc2 10p"}; +static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"}; +static const char * const p910_uart0_grps[] = {"uart0 4p"}; +static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2", + "uart1 2p3", "uart1 4p4", "uart1 4p5"}; +static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2", + "uart2 4p3", "uart2 4p4"}; +static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2", + "twsi 2p3"}; +static const char * const p910_ccic_grps[] = {"ccic"}; +static const char * const p910_lcd_grps[] = {"lcd"}; +static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3", + "spi 5p4"}; +static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2", + "dssp2 3p3"}; +static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2", + "dssp3 3p3"}; +static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2", + "ssp0 4p3", "ssp0 4p4"}; +static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"}; +static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2", + "ssp2 4p3", "ssp2 4p4"}; +static const char * const p910_gssp_grps[] = {"gssp"}; +static const char * const p910_pwm0_grps[] = {"pwm0"}; +static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"}; +static const char * const p910_pwm2_grps[] = {"pwm2"}; +static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"}; +static const char * const p910_pri_jtag_grps[] = {"pri jtag"}; +static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"}; +static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"}; +static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"}; +static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"}; +static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"}; +static const char * const p910_kpdk_grps[] = {"kpdk 8p1"}; +static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"}; +static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"}; +static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2", + "ext dma0-3"}; +static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2", + "ext dma1-3"}; +static const char * const p910_dma2_grps[] = {"ext dma2"}; +static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"}; +static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"}; +static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"}; +static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2", + "dac st23-3", "dac st23-4"}; +static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2", + "vcxo out-3"}; +static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"}; +static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1", + "vcxo out2-2"}; +static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"}; +static const char * const p910_ulpi_grps[] = {"ulpi"}; +static const char * const p910_nand_grps[] = {"nand"}; +static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"}; +static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"}; +static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"}; +static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"}; +static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"}; +static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"}; +static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"}; +static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"}; +static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"}; +static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"}; +static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"}; +static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"}; +static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"}; +static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; +static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"}; +static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"}; +static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"}; +static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"}; + +static struct pxa3xx_pmx_func pxa910_funcs[] = { + {"usim2", ARRAY_AND_SIZE(p910_usim2_grps)}, + {"mmc1", ARRAY_AND_SIZE(p910_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p910_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(p910_mmc3_grps)}, + {"uart0", ARRAY_AND_SIZE(p910_uart0_grps)}, + {"uart1", ARRAY_AND_SIZE(p910_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(p910_uart2_grps)}, + {"twsi", ARRAY_AND_SIZE(p910_twsi_grps)}, + {"ccic", ARRAY_AND_SIZE(p910_ccic_grps)}, + {"lcd", ARRAY_AND_SIZE(p910_lcd_grps)}, + {"spi", ARRAY_AND_SIZE(p910_spi_grps)}, + {"dssp2", ARRAY_AND_SIZE(p910_dssp2_grps)}, + {"dssp3", ARRAY_AND_SIZE(p910_dssp3_grps)}, + {"ssp0", ARRAY_AND_SIZE(p910_ssp0_grps)}, + {"ssp1", ARRAY_AND_SIZE(p910_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(p910_ssp2_grps)}, + {"gssp", ARRAY_AND_SIZE(p910_gssp_grps)}, + {"pwm0", ARRAY_AND_SIZE(p910_pwm0_grps)}, + {"pwm1", ARRAY_AND_SIZE(p910_pwm1_grps)}, + {"pwm2", ARRAY_AND_SIZE(p910_pwm2_grps)}, + {"pwm3", ARRAY_AND_SIZE(p910_pwm3_grps)}, + {"pri_jtag", ARRAY_AND_SIZE(p910_pri_jtag_grps)}, + {"sec1_jtag", ARRAY_AND_SIZE(p910_sec1_jtag_grps)}, + {"sec2_jtag", ARRAY_AND_SIZE(p910_sec2_jtag_grps)}, + {"hsl", ARRAY_AND_SIZE(p910_hsl_grps)}, + {"w1", ARRAY_AND_SIZE(p910_w1_grps)}, + {"kpmk", ARRAY_AND_SIZE(p910_kpmk_grps)}, + {"kpdk", ARRAY_AND_SIZE(p910_kpdk_grps)}, + {"tds", ARRAY_AND_SIZE(p910_tds_grps)}, + {"tb", ARRAY_AND_SIZE(p910_tb_grps)}, + {"dma0", ARRAY_AND_SIZE(p910_dma0_grps)}, + {"dma1", ARRAY_AND_SIZE(p910_dma1_grps)}, + {"dma2", ARRAY_AND_SIZE(p910_dma2_grps)}, + {"int0", ARRAY_AND_SIZE(p910_int0_grps)}, + {"int1", ARRAY_AND_SIZE(p910_int1_grps)}, + {"int2", ARRAY_AND_SIZE(p910_int2_grps)}, + {"dac_st23", ARRAY_AND_SIZE(p910_dac_st23_grps)}, + {"vcxo_out", ARRAY_AND_SIZE(p910_vcxo_out_grps)}, + {"vcxo_req", ARRAY_AND_SIZE(p910_vcxo_req_grps)}, + {"vcxo_out2", ARRAY_AND_SIZE(p910_vcxo_out2_grps)}, + {"vcxo_req2", ARRAY_AND_SIZE(p910_vcxo_req2_grps)}, + {"ulpi", ARRAY_AND_SIZE(p910_ulpi_grps)}, + {"nand", ARRAY_AND_SIZE(p910_nand_grps)}, + {"gpio0", ARRAY_AND_SIZE(p910_gpio0_grps)}, + {"gpio1", ARRAY_AND_SIZE(p910_gpio1_grps)}, + {"gpio2", ARRAY_AND_SIZE(p910_gpio2_grps)}, + {"gpio3", ARRAY_AND_SIZE(p910_gpio3_grps)}, + {"gpio20", ARRAY_AND_SIZE(p910_gpio20_grps)}, + {"gpio21", ARRAY_AND_SIZE(p910_gpio21_grps)}, + {"gpio22", ARRAY_AND_SIZE(p910_gpio22_grps)}, + {"gpio23", ARRAY_AND_SIZE(p910_gpio23_grps)}, + {"gpio24", ARRAY_AND_SIZE(p910_gpio24_grps)}, + {"gpio25", ARRAY_AND_SIZE(p910_gpio25_grps)}, + {"gpio26", ARRAY_AND_SIZE(p910_gpio26_grps)}, + {"gpio27", ARRAY_AND_SIZE(p910_gpio27_grps)}, + {"gpio85", ARRAY_AND_SIZE(p910_gpio85_grps)}, + {"gpio86", ARRAY_AND_SIZE(p910_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p910_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p910_gpio88_grps)}, + {"gpio89", ARRAY_AND_SIZE(p910_gpio89_grps)}, + {"gpio90", ARRAY_AND_SIZE(p910_gpio90_grps)}, + {"gpio91", ARRAY_AND_SIZE(p910_gpio91_grps)}, + {"gpio92", ARRAY_AND_SIZE(p910_gpio92_grps)}, +}; + +static struct pinctrl_desc pxa910_pctrl_desc = { + .name = "pxa910-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa910_info = { + .mfp = pxa910_mfp, + .num_mfp = ARRAY_SIZE(pxa910_mfp), + .grps = pxa910_grps, + .num_grps = ARRAY_SIZE(pxa910_grps), + .funcs = pxa910_funcs, + .num_funcs = ARRAY_SIZE(pxa910_funcs), + .num_gpio = 128, + .desc = &pxa910_pctrl_desc, + .pads = pxa910_pads, + .num_pads = ARRAY_SIZE(pxa910_pads), + + .cputype = PINCTRL_PXA910, + .ds_mask = PXA910_DS_MASK, + .ds_shift = PXA910_DS_SHIFT, +}; + +static int __devinit pxa910_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa910_info); +} + +static int __devexit pxa910_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa910_pinmux_driver = { + .driver = { + .name = "pxa910-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa910_pinmux_probe, + .remove = __devexit_p(pxa910_pinmux_remove), +}; + +static int __init pxa910_pinmux_init(void) +{ + return platform_driver_register(&pxa910_pinmux_driver); +} +core_initcall_sync(pxa910_pinmux_init); + +static void __exit pxa910_pinmux_exit(void) +{ + platform_driver_unregister(&pxa910_pinmux_driver); +} +module_exit(pxa910_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-70-g09d2 From b5d5843a1dd0031d63d9d9484346d86eae9cab3b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Fri, 27 Jan 2012 04:24:55 +0000 Subject: mISDN: use memchr_inv Use memchr_inv to check if the data contains all same bytes. It is faster than looping for each byte. Signed-off-by: Akinobu Mita Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/mISDN/l1oip_core.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/l1oip_core.c b/drivers/isdn/mISDN/l1oip_core.c index 22f8ec8b924..04f115a9c43 100644 --- a/drivers/isdn/mISDN/l1oip_core.c +++ b/drivers/isdn/mISDN/l1oip_core.c @@ -1112,7 +1112,7 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) struct l1oip *hc = bch->hw; int ret = -EINVAL; struct mISDNhead *hh = mISDN_HEAD_P(skb); - int l, ll, i; + int l, ll; unsigned char *p; switch (hh->prim) { @@ -1128,13 +1128,8 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) break; } /* check for AIS / ulaw-silence */ - p = skb->data; l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0xff) - break; - } - if (i == l) { + if (!memchr_inv(skb->data, 0xff, l)) { if (debug & DEBUG_L1OIP_MSG) printk(KERN_DEBUG "%s: got AIS, not sending, " "but counting\n", __func__); @@ -1144,13 +1139,8 @@ handle_bmsg(struct mISDNchannel *ch, struct sk_buff *skb) return 0; } /* check for silence */ - p = skb->data; l = skb->len; - for (i = 0; i < l; i++) { - if (*p++ != 0x2a) - break; - } - if (i == l) { + if (!memchr_inv(skb->data, 0x2a, l)) { if (debug & DEBUG_L1OIP_MSG) printk(KERN_DEBUG "%s: got silence, not sending" ", but counting\n", __func__); -- cgit v1.2.3-70-g09d2 From 8ef78adcb03b1fcb53c3bd62df4e96c1d2706c58 Mon Sep 17 00:00:00 2001 From: Peter P Waskiewicz Jr Date: Wed, 1 Feb 2012 09:19:21 +0000 Subject: ixgbe: Add module parameter to allow untested and unsafe SFP+ modules The X520 family of network devices, with the 82599 chip, support a small number of Intel-verified SFP+ modules on their NICs. To maintain stability and quality, the current devices restrict untested 3rd party SFP+ modules. This patch introduces a module parameter for ixgbe to allow these untested modules at the user's peril. It also includes a warning to the syslog alerting users that the modules aren't supported, and results may vary. CC: Jesper Dangaard Brouer Signed-off-by: Peter P Waskiewicz Jr Tested-by: Phil Schmitt Signed-off-by: Jeff Kirsher Signed-off-by: David S. Miller --- drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 8 ++++++++ drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | 14 +++++++++++--- drivers/net/ethernet/intel/ixgbe/ixgbe_type.h | 1 + 3 files changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index 1ee5d0fbb90..2e8e7640b60 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -131,6 +131,11 @@ MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate per physical function"); #endif /* CONFIG_PCI_IOV */ +static unsigned int allow_unsupported_sfp; +module_param(allow_unsupported_sfp, uint, 0); +MODULE_PARM_DESC(allow_unsupported_sfp, + "Allow unsupported and untested SFP+ modules on 82599-based adapters"); + MODULE_AUTHOR("Intel Corporation, "); MODULE_DESCRIPTION("Intel(R) 10 Gigabit PCI Express Network Driver"); MODULE_LICENSE("GPL"); @@ -7489,6 +7494,9 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, e_crit(probe, "Fan has stopped, replace the adapter\n"); } + if (allow_unsupported_sfp) + hw->allow_unsupported_sfp = allow_unsupported_sfp; + /* reset_hw fills in the perm_addr as well */ hw->phy.reset_if_overtemp = true; err = hw->mac.ops.reset_hw(hw); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index 7cf1e1f56c6..29fda9777ff 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c @@ -834,6 +834,7 @@ out: **/ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) { + struct ixgbe_adapter *adapter = hw->back; s32 status = IXGBE_ERR_PHY_ADDR_INVALID; u32 vendor_oui = 0; enum ixgbe_sfp_type stored_sfp_type = hw->phy.sfp_type; @@ -1068,9 +1069,16 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) if (hw->phy.type == ixgbe_phy_sfp_intel) { status = 0; } else { - hw_dbg(hw, "SFP+ module not supported\n"); - hw->phy.type = ixgbe_phy_sfp_unsupported; - status = IXGBE_ERR_SFP_NOT_SUPPORTED; + if (hw->allow_unsupported_sfp) { + e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules."); + status = 0; + } else { + hw_dbg(hw, + "SFP+ module not supported\n"); + hw->phy.type = + ixgbe_phy_sfp_unsupported; + status = IXGBE_ERR_SFP_NOT_SUPPORTED; + } } } else { status = 0; diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h index 775602ef90e..2dc5e71cb3f 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h @@ -2892,6 +2892,7 @@ struct ixgbe_hw { u8 revision_id; bool adapter_stopped; bool force_full_reset; + bool allow_unsupported_sfp; }; struct ixgbe_info { -- cgit v1.2.3-70-g09d2 From d45b9d39a1aed7851948460d29b843ce70eb0a68 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Sun, 29 Jan 2012 20:17:39 +0000 Subject: be2net: add descriptions for stat counters reported via ethtool Also rename a few counters appropritely and delete 2 counters that are not implemented in HW. vlan_mismatch_drops does not exist in BE3 and is accounted for in address_mismatch_drops. Do the same thing for BE2 and Lancer. Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 3 +- drivers/net/ethernet/emulex/benet/be_cmds.h | 10 ++-- drivers/net/ethernet/emulex/benet/be_ethtool.c | 64 ++++++++++++++++++++++++-- drivers/net/ethernet/emulex/benet/be_main.c | 15 +++--- 4 files changed, 74 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h index 453d48612f8..74aa1481197 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -265,7 +265,6 @@ struct be_drv_stats { u32 rx_drops_no_erx_descr; u32 rx_drops_no_tpre_descr; u32 rx_drops_too_many_frags; - u32 rx_drops_invalid_ring; u32 forwarded_packets; u32 rx_drops_mtu; u32 rx_crc_errors; @@ -276,7 +275,7 @@ struct be_drv_stats { u32 rx_in_range_errors; u32 rx_out_range_errors; u32 rx_frame_too_long; - u32 rx_address_match_errors; + u32 rx_address_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h index dca89249088..bbd012b41fb 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.h +++ b/drivers/net/ethernet/emulex/benet/be_cmds.h @@ -592,8 +592,8 @@ struct be_port_rxf_stats_v0 { u32 rx_in_range_errors; /* dword 10*/ u32 rx_out_range_errors; /* dword 11*/ u32 rx_frame_too_long; /* dword 12*/ - u32 rx_address_match_errors; /* dword 13*/ - u32 rx_vlan_mismatch; /* dword 14*/ + u32 rx_address_mismatch_drops; /* dword 13*/ + u32 rx_vlan_mismatch_drops; /* dword 14*/ u32 rx_dropped_too_small; /* dword 15*/ u32 rx_dropped_too_short; /* dword 16*/ u32 rx_dropped_header_too_small; /* dword 17*/ @@ -799,8 +799,8 @@ struct lancer_pport_stats { u32 rx_control_frames_unknown_opcode_hi; u32 rx_in_range_errors; u32 rx_out_of_range_errors; - u32 rx_address_match_errors; - u32 rx_vlan_mismatch_errors; + u32 rx_address_mismatch_drops; + u32 rx_vlan_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; @@ -1384,7 +1384,7 @@ struct be_port_rxf_stats_v1 { u32 rx_in_range_errors; u32 rx_out_range_errors; u32 rx_frame_too_long; - u32 rx_address_match_errors; + u32 rx_address_mismatch_drops; u32 rx_dropped_too_small; u32 rx_dropped_too_short; u32 rx_dropped_header_too_small; diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c index 6db6b6ae5e9..0a5ee224cfe 100644 --- a/drivers/net/ethernet/emulex/benet/be_ethtool.c +++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c @@ -42,15 +42,42 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_INFO(rx_alignment_symbol_errors)}, {DRVSTAT_INFO(rx_pause_frames)}, {DRVSTAT_INFO(rx_control_frames)}, + /* Received packets dropped when the Ethernet length field + * is not equal to the actual Ethernet data length. + */ {DRVSTAT_INFO(rx_in_range_errors)}, + /* Received packets dropped when their length field is >= 1501 bytes + * and <= 1535 bytes. + */ {DRVSTAT_INFO(rx_out_range_errors)}, + /* Received packets dropped when they are longer than 9216 bytes */ {DRVSTAT_INFO(rx_frame_too_long)}, - {DRVSTAT_INFO(rx_address_match_errors)}, + /* Received packets dropped when they don't pass the unicast or + * multicast address filtering. + */ + {DRVSTAT_INFO(rx_address_mismatch_drops)}, + /* Received packets dropped when IP packet length field is less than + * the IP header length field. + */ {DRVSTAT_INFO(rx_dropped_too_small)}, + /* Received packets dropped when IP length field is greater than + * the actual packet length. + */ {DRVSTAT_INFO(rx_dropped_too_short)}, + /* Received packets dropped when the IP header length field is less + * than 5. + */ {DRVSTAT_INFO(rx_dropped_header_too_small)}, + /* Received packets dropped when the TCP header length field is less + * than 5 or the TCP header length + IP header length is more + * than IP packet length. + */ {DRVSTAT_INFO(rx_dropped_tcp_length)}, {DRVSTAT_INFO(rx_dropped_runt)}, + /* Number of received packets dropped when a fifo for descriptors going + * into the packet demux block overflows. In normal operation, this + * fifo must never overflow. + */ {DRVSTAT_INFO(rxpp_fifo_overflow_drop)}, {DRVSTAT_INFO(rx_input_fifo_overflow_drop)}, {DRVSTAT_INFO(rx_ip_checksum_errs)}, @@ -59,16 +86,35 @@ static const struct be_ethtool_stat et_stats[] = { {DRVSTAT_INFO(tx_pauseframes)}, {DRVSTAT_INFO(tx_controlframes)}, {DRVSTAT_INFO(rx_priority_pause_frames)}, + /* Received packets dropped when an internal fifo going into + * main packet buffer tank (PMEM) overflows. + */ {DRVSTAT_INFO(pmem_fifo_overflow_drop)}, {DRVSTAT_INFO(jabber_events)}, + /* Received packets dropped due to lack of available HW packet buffers + * used to temporarily hold the received packets. + */ {DRVSTAT_INFO(rx_drops_no_pbuf)}, - {DRVSTAT_INFO(rx_drops_no_txpb)}, + /* Received packets dropped due to input receive buffer + * descriptor fifo overflowing. + */ {DRVSTAT_INFO(rx_drops_no_erx_descr)}, + /* Packets dropped because the internal FIFO to the offloaded TCP + * receive processing block is full. This could happen only for + * offloaded iSCSI or FCoE trarffic. + */ {DRVSTAT_INFO(rx_drops_no_tpre_descr)}, + /* Received packets dropped when they need more than 8 + * receive buffers. This cannot happen as the driver configures + * 2048 byte receive buffers. + */ {DRVSTAT_INFO(rx_drops_too_many_frags)}, - {DRVSTAT_INFO(rx_drops_invalid_ring)}, {DRVSTAT_INFO(forwarded_packets)}, + /* Received packets dropped when the frame length + * is more than 9018 bytes + */ {DRVSTAT_INFO(rx_drops_mtu)}, + /* Number of packets dropped due to random early drop function */ {DRVSTAT_INFO(eth_red_drops)}, {DRVSTAT_INFO(be_on_die_temperature)} }; @@ -84,8 +130,15 @@ static const struct be_ethtool_stat et_rx_stats[] = { {DRVSTAT_RX_INFO(rx_events)}, {DRVSTAT_RX_INFO(rx_compl)}, {DRVSTAT_RX_INFO(rx_mcast_pkts)}, + /* Number of page allocation failures while posting receive buffers + * to HW. + */ {DRVSTAT_RX_INFO(rx_post_fail)}, + /* Recevied packets dropped due to skb allocation failure */ {DRVSTAT_RX_INFO(rx_drops_no_skbs)}, + /* Received packets dropped due to lack of available fetched buffers + * posted by the driver. + */ {DRVSTAT_RX_INFO(rx_drops_no_frags)} }; #define ETHTOOL_RXSTATS_NUM (ARRAY_SIZE(et_rx_stats)) @@ -97,9 +150,14 @@ static const struct be_ethtool_stat et_tx_stats[] = { {DRVSTAT_TX_INFO(tx_compl)}, /* If moving this member see above note */ {DRVSTAT_TX_INFO(tx_bytes)}, {DRVSTAT_TX_INFO(tx_pkts)}, + /* Number of skbs queued for trasmission by the driver */ {DRVSTAT_TX_INFO(tx_reqs)}, + /* Number of TX work request blocks DMAed to HW */ {DRVSTAT_TX_INFO(tx_wrbs)}, {DRVSTAT_TX_INFO(tx_compl)}, + /* Number of times the TX queue was stopped due to lack + * of spaces in the TXQ. + */ {DRVSTAT_TX_INFO(tx_stops)} }; #define ETHTOOL_TXSTATS_NUM (ARRAY_SIZE(et_tx_stats)) diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 0fbf365f5c6..1395f803cf7 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -286,7 +286,9 @@ static void populate_be2_stats(struct be_adapter *adapter) drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow; drvs->rx_dropped_header_too_small = port_stats->rx_dropped_header_too_small; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = + port_stats->rx_address_mismatch_drops + + port_stats->rx_vlan_mismatch_drops; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; @@ -298,9 +300,7 @@ static void populate_be2_stats(struct be_adapter *adapter) else drvs->jabber_events = rxf_stats->port0_jabber_events; drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; - drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; - drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; @@ -337,7 +337,7 @@ static void populate_be3_stats(struct be_adapter *adapter) port_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = port_stats->rx_input_fifo_overflow_drop; - drvs->rx_address_match_errors = port_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = port_stats->rx_address_mismatch_drops; drvs->rx_alignment_symbol_errors = port_stats->rx_alignment_symbol_errors; drvs->rxpp_fifo_overflow_drop = port_stats->rxpp_fifo_overflow_drop; @@ -345,9 +345,7 @@ static void populate_be3_stats(struct be_adapter *adapter) drvs->tx_controlframes = port_stats->tx_controlframes; drvs->jabber_events = port_stats->jabber_events; drvs->rx_drops_no_pbuf = rxf_stats->rx_drops_no_pbuf; - drvs->rx_drops_no_txpb = rxf_stats->rx_drops_no_txpb; drvs->rx_drops_no_erx_descr = rxf_stats->rx_drops_no_erx_descr; - drvs->rx_drops_invalid_ring = rxf_stats->rx_drops_invalid_ring; drvs->forwarded_packets = rxf_stats->forwarded_packets; drvs->rx_drops_mtu = rxf_stats->rx_drops_mtu; drvs->rx_drops_no_tpre_descr = rxf_stats->rx_drops_no_tpre_descr; @@ -380,13 +378,14 @@ static void populate_lancer_stats(struct be_adapter *adapter) drvs->rx_dropped_header_too_small = pport_stats->rx_dropped_header_too_small; drvs->rx_input_fifo_overflow_drop = pport_stats->rx_fifo_overflow; - drvs->rx_address_match_errors = pport_stats->rx_address_match_errors; + drvs->rx_address_mismatch_drops = + pport_stats->rx_address_mismatch_drops + + pport_stats->rx_vlan_mismatch_drops; drvs->rx_alignment_symbol_errors = pport_stats->rx_symbol_errors_lo; drvs->rxpp_fifo_overflow_drop = pport_stats->rx_fifo_overflow; drvs->tx_pauseframes = pport_stats->tx_pause_frames_lo; drvs->tx_controlframes = pport_stats->tx_control_frames_lo; drvs->jabber_events = pport_stats->rx_jabbers; - drvs->rx_drops_invalid_ring = pport_stats->rx_drops_invalid_queue; drvs->forwarded_packets = pport_stats->num_forwards_lo; drvs->rx_drops_mtu = pport_stats->rx_drops_mtu_lo; drvs->rx_drops_too_many_frags = -- cgit v1.2.3-70-g09d2 From dc7cdf6c6bfc837501ea403a73eec78a350b1f7f Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Mon, 30 Jan 2012 12:00:18 +0000 Subject: hamradio: fix incompatible pointer in module parameter Fixed 'warning: return from incompatible pointer type' related to module parameters. Signed-off-by: Danny Kukawka Signed-off-by: David S. Miller --- drivers/net/hamradio/baycom_epp.c | 2 +- drivers/net/hamradio/baycom_par.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index 9537aaa50c2..49b8b58fc5c 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c @@ -1162,7 +1162,7 @@ static void baycom_probe(struct net_device *dev) /* * command line settable parameters */ -static const char *mode[NR_PORTS] = { "", }; +static char *mode[NR_PORTS] = { "", }; static int iobase[NR_PORTS] = { 0x378, }; module_param_array(mode, charp, NULL, 0); diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 279d2296290..f1aea0c9833 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c @@ -477,7 +477,7 @@ static int baycom_ioctl(struct net_device *dev, struct ifreq *ifr, /* * command line settable parameters */ -static const char *mode[NR_PORTS] = { "picpar", }; +static char *mode[NR_PORTS] = { "picpar", }; static int iobase[NR_PORTS] = { 0x378, }; module_param_array(mode, charp, NULL, 0); -- cgit v1.2.3-70-g09d2 From 12806a241b1756518bf63c4a464fff73c1a363f2 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 1 Feb 2012 03:05:13 +0000 Subject: atm: Fix typo in lanai.c Correct spelling "reseting" to resetting" in drivers/atm/lanai.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/atm/lanai.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index f5569699f31..68c75887181 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -1572,7 +1572,7 @@ static inline void host_vcc_unbind(struct lanai_dev *lanai, static void lanai_reset(struct lanai_dev *lanai) { - printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* reseting - not " + printk(KERN_CRIT DEV_LABEL "(itf %d): *NOT* resetting - not " "implemented\n", lanai->number); /* TODO */ /* The following is just a hack until we write the real -- cgit v1.2.3-70-g09d2 From c3ca881f0a6e6421f167d3938f4b1e1d008cb505 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Wed, 1 Feb 2012 03:13:59 +0000 Subject: vmxnet3: Fix typo in vmxnet3_drv.c Correct spelling in "uncommited" to "uncommitted" in drivers/net/vmxnet3/vmxnet3_drv.c Signed-off-by: Masanari Iida Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 482cfa891f8..e1562e8acba 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -633,7 +633,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, dev_dbg(&adapter->netdev->dev, "alloc_rx_buf: %d allocated, next2fill %u, next2comp " - "%u, uncommited %u\n", num_allocated, ring->next2fill, + "%u, uncommitted %u\n", num_allocated, ring->next2fill, ring->next2comp, rq->uncommitted[ring_idx]); /* so that the device can distinguish a full ring and an empty ring */ -- cgit v1.2.3-70-g09d2 From 07d57a32fb6eb2da017796e038682f817a4f685e Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 1 Feb 2012 11:22:22 -0700 Subject: drivercore: Output common devicetree information in uevent When userspace needs to find a specific device, it currently isn't easy to resolve a /sys/devices/ path from a specific device tree node. Nor is it easy to obtain the compatible list for devices. This patch generalizes the code that inserts OF_* values into the uevent device attribute so that any device that is attached to an OF node will have that information exported to userspace. Without this patch only platform devices and some powerpc-specific busses have access to this data. The original function also creates a MODALIAS property for the compatible list, but that code has not been generalized into the common case because it has the potential to break module loading on a lot of bus types. Bus types are still responsible for their own MODALIAS properties. Boot tested on ARM and compile tested on PowerPC and SPARC. Signed-off-by: Grant Likely Acked-by: Greg Kroah-Hartman Cc: Tobias Klauser Cc: Frederic Lambert Cc: Rob Herring Cc: Mark Brown Cc: "David S. Miller" Cc: Benjamin Herrenschmidt --- arch/powerpc/kernel/ibmebus.c | 2 +- drivers/base/core.c | 5 +++++ drivers/base/platform.c | 2 +- drivers/macintosh/macio_asic.c | 2 +- drivers/of/device.c | 30 ++++++++++++++++-------------- include/linux/of_device.h | 8 ++++++-- 6 files changed, 30 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c index d39ae606ff8..79bb282e650 100644 --- a/arch/powerpc/kernel/ibmebus.c +++ b/arch/powerpc/kernel/ibmebus.c @@ -713,7 +713,7 @@ static struct dev_pm_ops ibmebus_bus_dev_pm_ops = { struct bus_type ibmebus_bus_type = { .name = "ibmebus", - .uevent = of_device_uevent, + .uevent = of_device_uevent_modalias, .bus_attrs = ibmebus_bus_attrs, .match = ibmebus_bus_bus_match, .probe = ibmebus_bus_device_probe, diff --git a/drivers/base/core.c b/drivers/base/core.c index 4a67cc0c8b3..28d8c21bb32 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include #include @@ -267,6 +269,9 @@ static int dev_uevent(struct kset *kset, struct kobject *kobj, if (dev->driver) add_uevent_var(env, "DRIVER=%s", dev->driver->name); + /* Add common DT information about the device */ + of_device_uevent(dev, env); + /* have the bus specific function add its stuff */ if (dev->bus && dev->bus->uevent) { retval = dev->bus->uevent(dev, env); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index f0c605e99ad..a1a72250258 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -621,7 +621,7 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) int rc; /* Some devices have extra OF data and an OF-style MODALIAS */ - rc = of_device_uevent(dev,env); + rc = of_device_uevent_modalias(dev,env); if (rc != -ENODEV) return rc; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 4daf9e5a773..20e5c2cda43 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -137,7 +137,7 @@ extern struct device_attribute macio_dev_attrs[]; struct bus_type macio_bus_type = { .name = "macio", .match = macio_bus_match, - .uevent = of_device_uevent, + .uevent = of_device_uevent_modalias, .probe = macio_device_probe, .remove = macio_device_remove, .shutdown = macio_device_shutdown, diff --git a/drivers/of/device.c b/drivers/of/device.c index 62b4b32ac88..4c74e4fc5a5 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -128,39 +128,41 @@ ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len) /** * of_device_uevent - Display OF related uevent information */ -int of_device_uevent(struct device *dev, struct kobj_uevent_env *env) +void of_device_uevent(struct device *dev, struct kobj_uevent_env *env) { const char *compat; int seen = 0, cplen, sl; if ((!dev) || (!dev->of_node)) - return -ENODEV; - - if (add_uevent_var(env, "OF_NAME=%s", dev->of_node->name)) - return -ENOMEM; + return; - if (add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type)) - return -ENOMEM; + add_uevent_var(env, "OF_NAME=%s", dev->of_node->name); + add_uevent_var(env, "OF_FULLNAME=%s", dev->of_node->full_name); + if (dev->of_node->type && strcmp("", dev->of_node->type) != 0) + add_uevent_var(env, "OF_TYPE=%s", dev->of_node->type); /* Since the compatible field can contain pretty much anything * it's not really legal to split it out with commas. We split it * up using a number of environment variables instead. */ - compat = of_get_property(dev->of_node, "compatible", &cplen); while (compat && *compat && cplen > 0) { - if (add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat)) - return -ENOMEM; - + add_uevent_var(env, "OF_COMPATIBLE_%d=%s", seen, compat); sl = strlen(compat) + 1; compat += sl; cplen -= sl; seen++; } + add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen); +} - if (add_uevent_var(env, "OF_COMPATIBLE_N=%d", seen)) - return -ENOMEM; +int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) +{ + int sl; + + if ((!dev) || (!dev->of_node)) + return -ENODEV; - /* modalias is trickier, we add it in 2 steps */ + /* Devicetree modalias is tricky, we add it in 2 steps */ if (add_uevent_var(env, "MODALIAS=")) return -ENOMEM; diff --git a/include/linux/of_device.h b/include/linux/of_device.h index ae5638480ef..cbc42143fa5 100644 --- a/include/linux/of_device.h +++ b/include/linux/of_device.h @@ -34,7 +34,8 @@ extern void of_device_unregister(struct platform_device *ofdev); extern ssize_t of_device_get_modalias(struct device *dev, char *str, ssize_t len); -extern int of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +extern void of_device_uevent(struct device *dev, struct kobj_uevent_env *env); +extern int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env); static inline void of_device_node_put(struct device *dev) { @@ -49,7 +50,10 @@ static inline int of_driver_match_device(struct device *dev, return 0; } -static inline int of_device_uevent(struct device *dev, +static inline void of_device_uevent(struct device *dev, + struct kobj_uevent_env *env) { } + +static inline int of_device_uevent_modalias(struct device *dev, struct kobj_uevent_env *env) { return -ENODEV; -- cgit v1.2.3-70-g09d2 From 90bbf4fdf2dc64aa7c20a93a9744c56a566baf26 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 1 Feb 2012 13:33:42 +0100 Subject: spi/nuc900: Remove unnecessary memset of struct nuc900_spi The memory allocated using kzalloc by spi_alloc_master so it doesn't need to be set to 0 again. Signed-off-by: Tobias Klauser Signed-off-by: Grant Likely --- drivers/spi/spi-nuc900.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-nuc900.c b/drivers/spi/spi-nuc900.c index 182e9c87382..dae8be229c5 100644 --- a/drivers/spi/spi-nuc900.c +++ b/drivers/spi/spi-nuc900.c @@ -360,8 +360,6 @@ static int __devinit nuc900_spi_probe(struct platform_device *pdev) } hw = spi_master_get_devdata(master); - memset(hw, 0, sizeof(struct nuc900_spi)); - hw->master = spi_master_get(master); hw->pdata = pdev->dev.platform_data; hw->dev = &pdev->dev; -- cgit v1.2.3-70-g09d2 From d976f7626627117c211137cd2aaf8c1656e6627d Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Thu, 26 Jan 2012 15:52:15 -0800 Subject: clocksource: scx200_hrt: use pr_ instead of printk Switch from printk to using pr_. Signed-off-by: Jim Cromie [added commit msg & tweaked subject -jstultz] Signed-off-by: John Stultz --- drivers/clocksource/scx200_hrt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index 27f4d9637b6..e4e4a04ab23 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c @@ -71,7 +71,7 @@ static int __init init_hrt_clocksource(void) if (!request_region(scx200_cb_base + SCx200_TIMER_OFFSET, SCx200_TIMER_SIZE, "NatSemi SCx200 High-Resolution Timer")) { - printk(KERN_WARNING NAME ": unable to lock timer region\n"); + pr_warn("unable to lock timer region\n"); return -ENODEV; } @@ -88,7 +88,7 @@ static int __init init_hrt_clocksource(void) cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm, cs_hrt.shift); } - printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n", + pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm); return clocksource_register(&cs_hrt); -- cgit v1.2.3-70-g09d2 From 13f0f030fb9d52c7fd48f3e6a2fe9ab0123875da Mon Sep 17 00:00:00 2001 From: Yong Zhang Date: Thu, 1 Dec 2011 15:20:15 +0800 Subject: clocksource: dbx500: convert to clocksource_register_hz() Convert clocksource_dbx500_prcmu to use clocksource_register_hz. Cc: Thomas Gleixner Cc: Mattias Wallin Acked-by: Linus Walleij Signed-off-by: Yong Zhang Signed-off-by: John Stultz --- drivers/clocksource/clksrc-dbx500-prcmu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/clksrc-dbx500-prcmu.c b/drivers/clocksource/clksrc-dbx500-prcmu.c index fb6b6d28b60..c26c369eb9e 100644 --- a/drivers/clocksource/clksrc-dbx500-prcmu.c +++ b/drivers/clocksource/clksrc-dbx500-prcmu.c @@ -52,7 +52,6 @@ static struct clocksource clocksource_dbx500_prcmu = { .name = "dbx500-prcmu-timer", .rating = 300, .read = clksrc_dbx500_prcmu_read, - .shift = 10, .mask = CLOCKSOURCE_MASK(32), .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; @@ -90,7 +89,5 @@ void __init clksrc_dbx500_prcmu_init(void __iomem *base) setup_sched_clock(dbx500_prcmu_sched_clock_read, 32, RATE_32K); #endif - clocksource_calc_mult_shift(&clocksource_dbx500_prcmu, - RATE_32K, SCHED_CLOCK_MIN_WRAP); - clocksource_register(&clocksource_dbx500_prcmu); + clocksource_register_hz(&clocksource_dbx500_prcmu, RATE_32K); } -- cgit v1.2.3-70-g09d2 From 12d6d41276def096cb3f7dc36f438db9ed6a0a8d Mon Sep 17 00:00:00 2001 From: John Stultz Date: Mon, 9 Jan 2012 16:15:03 -0800 Subject: clocksource: scx200_hrt: Convert scx200 to use clocksource_register_hz Converts the scx200 clocksource to using clocksource_register_hz. CC: Jim Cromie Tested-by: Jim Cromie Acked-by: Jim Cromie Signed-off-by: John Stultz --- drivers/clocksource/scx200_hrt.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/scx200_hrt.c b/drivers/clocksource/scx200_hrt.c index e4e4a04ab23..60db8b1492f 100644 --- a/drivers/clocksource/scx200_hrt.c +++ b/drivers/clocksource/scx200_hrt.c @@ -49,9 +49,6 @@ static cycle_t read_hrt(struct clocksource *cs) return (cycle_t) inl(scx200_cb_base + SCx200_TIMER_OFFSET); } -#define HRT_SHIFT_1 22 -#define HRT_SHIFT_27 26 - static struct clocksource cs_hrt = { .name = "scx200_hrt", .rating = 250, @@ -63,6 +60,7 @@ static struct clocksource cs_hrt = { static int __init init_hrt_clocksource(void) { + u32 freq; /* Make sure scx200 has initialized the configuration block */ if (!scx200_cb_present()) return -ENODEV; @@ -79,19 +77,15 @@ static int __init init_hrt_clocksource(void) outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0), scx200_cb_base + SCx200_TMCNFG_OFFSET); - if (mhz27) { - cs_hrt.shift = HRT_SHIFT_27; - cs_hrt.mult = clocksource_hz2mult((HRT_FREQ + ppm) * 27, - cs_hrt.shift); - } else { - cs_hrt.shift = HRT_SHIFT_1; - cs_hrt.mult = clocksource_hz2mult(HRT_FREQ + ppm, - cs_hrt.shift); - } + freq = (HRT_FREQ + ppm); + if (mhz27) + freq *= 27; + pr_info("enabling scx200 high-res timer (%s MHz +%d ppm)\n", + printk(KERN_INFO "enabling scx200 high-res timer (%s MHz +%d ppm)\n", mhz27 ? "27":"1", ppm); - return clocksource_register(&cs_hrt); + return clocksource_register_hz(&cs_hrt, freq); } module_init(init_hrt_clocksource); -- cgit v1.2.3-70-g09d2 From b519508298e0292e1771eecf14aaf67755adc39d Mon Sep 17 00:00:00 2001 From: Arjan van de Ven Date: Mon, 30 Jan 2012 20:23:30 -0800 Subject: clocksource: Load the ACPI PM clocksource asynchronously The ACPI clocksource takes quite some time to initialize, and this increases the boot time of the kernel for a double digit percentage. This while almost all modern systems will be using the HPET already anyway. This patch turns the clocksource loading into an asynchronous operation; which means it won't hold up the boot while still becoming available normally. To make this work well, an udelay() had to be turned into an usleep_range() so that on UP systems, we yield the CPU to regular boot tasks instead of spinning. CC: John Stultz CC: Thomas Gleixner CC: Len Brown Signed-off-by: Arjan van de Ven Signed-off-by: John Stultz --- drivers/clocksource/acpi_pm.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/acpi_pm.c b/drivers/clocksource/acpi_pm.c index 6b5cf02c35c..82e882028fc 100644 --- a/drivers/clocksource/acpi_pm.c +++ b/drivers/clocksource/acpi_pm.c @@ -23,6 +23,7 @@ #include #include #include +#include #include /* @@ -179,17 +180,15 @@ static int verify_pmtmr_rate(void) /* Number of reads we try to get two different values */ #define ACPI_PM_READ_CHECKS 10000 -static int __init init_acpi_pm_clocksource(void) +static void __init acpi_pm_clocksource_async(void *unused, async_cookie_t cookie) { cycle_t value1, value2; unsigned int i, j = 0; - if (!pmtmr_ioport) - return -ENODEV; /* "verify" this timing source: */ for (j = 0; j < ACPI_PM_MONOTONICITY_CHECKS; j++) { - udelay(100 * j); + usleep_range(100 * j, 100 * j + 100); value1 = clocksource_acpi_pm.read(&clocksource_acpi_pm); for (i = 0; i < ACPI_PM_READ_CHECKS; i++) { value2 = clocksource_acpi_pm.read(&clocksource_acpi_pm); @@ -203,25 +202,34 @@ static int __init init_acpi_pm_clocksource(void) " 0x%#llx, 0x%#llx - aborting.\n", value1, value2); pmtmr_ioport = 0; - return -EINVAL; + return; } if (i == ACPI_PM_READ_CHECKS) { printk(KERN_INFO "PM-Timer failed consistency check " " (0x%#llx) - aborting.\n", value1); pmtmr_ioport = 0; - return -ENODEV; + return; } } if (verify_pmtmr_rate() != 0){ pmtmr_ioport = 0; - return -ENODEV; + return; } - return clocksource_register_hz(&clocksource_acpi_pm, + clocksource_register_hz(&clocksource_acpi_pm, PMTMR_TICKS_PER_SEC); } +static int __init init_acpi_pm_clocksource(void) +{ + if (!pmtmr_ioport) + return -ENODEV; + + async_schedule(acpi_pm_clocksource_async, NULL); + return 0; +} + /* We use fs_initcall because we want the PCI fixups to have run * but we still need to load before device_initcall */ -- cgit v1.2.3-70-g09d2 From 57b9bef0d6990d088a5e840c88ae137d8e76202c Mon Sep 17 00:00:00 2001 From: Krishna Gudipati Date: Wed, 1 Feb 2012 15:02:41 +0000 Subject: bna: Implement ethtool flash_device entry point. Incorporated review comments from Ben Hutchings. Change details: - Implement ethtool flash_device() entry point to write the firmware image to the flash firmware partition. Signed-off-by: Krishna Gudipati Reviewed-by: Ben Hutchings Signed-off-by: David S. Miller --- drivers/net/ethernet/brocade/bna/bfa_defs.h | 1 + drivers/net/ethernet/brocade/bna/bnad_ethtool.c | 42 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/brocade/bna/bfa_defs.h b/drivers/net/ethernet/brocade/bna/bfa_defs.h index 871c6309334..48f87733739 100644 --- a/drivers/net/ethernet/brocade/bna/bfa_defs.h +++ b/drivers/net/ethernet/brocade/bna/bfa_defs.h @@ -297,6 +297,7 @@ enum bfa_mode { #define BFA_FLASH_PART_ENTRY_SIZE 32 /* partition entry size */ #define BFA_FLASH_PART_MAX 32 /* maximal # of partitions */ #define BFA_TOTAL_FLASH_SIZE 0x400000 +#define BFA_FLASH_PART_FWIMG 2 #define BFA_FLASH_PART_MFG 7 /* diff --git a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c index 9b44ec8096b..a27c601af3d 100644 --- a/drivers/net/ethernet/brocade/bna/bnad_ethtool.c +++ b/drivers/net/ethernet/brocade/bna/bnad_ethtool.c @@ -1072,6 +1072,47 @@ done: return ret; } +static int +bnad_flash_device(struct net_device *netdev, struct ethtool_flash *eflash) +{ + struct bnad *bnad = netdev_priv(netdev); + struct bnad_iocmd_comp fcomp; + const struct firmware *fw; + int ret = 0; + + ret = request_firmware(&fw, eflash->data, &bnad->pcidev->dev); + if (ret) { + pr_err("BNA: Can't locate firmware %s\n", eflash->data); + goto out; + } + + fcomp.bnad = bnad; + fcomp.comp_status = 0; + + init_completion(&fcomp.comp); + spin_lock_irq(&bnad->bna_lock); + ret = bfa_nw_flash_update_part(&bnad->bna.flash, BFA_FLASH_PART_FWIMG, + bnad->id, (u8 *)fw->data, fw->size, 0, + bnad_cb_completion, &fcomp); + if (ret != BFA_STATUS_OK) { + pr_warn("BNA: Flash update failed with err: %d\n", ret); + ret = -EIO; + spin_unlock_irq(&bnad->bna_lock); + goto out; + } + + spin_unlock_irq(&bnad->bna_lock); + wait_for_completion(&fcomp.comp); + if (fcomp.comp_status != BFA_STATUS_OK) { + ret = -EIO; + pr_warn("BNA: Firmware image update to flash failed with: %d\n", + fcomp.comp_status); + } +out: + release_firmware(fw); + return ret; +} + static const struct ethtool_ops bnad_ethtool_ops = { .get_settings = bnad_get_settings, .set_settings = bnad_set_settings, @@ -1090,6 +1131,7 @@ static const struct ethtool_ops bnad_ethtool_ops = { .get_eeprom_len = bnad_get_eeprom_len, .get_eeprom = bnad_get_eeprom, .set_eeprom = bnad_set_eeprom, + .flash_device = bnad_flash_device, }; void -- cgit v1.2.3-70-g09d2 From 3c325fbd0cdb4f83b7761cd8ba7519d7a236de38 Mon Sep 17 00:00:00 2001 From: Masanari Iida Date: Tue, 31 Jan 2012 23:32:55 +0900 Subject: ath6kl: Fix typo in cfg80211.c Correct spelling "spported" to "supported" in drivers/net/wireless/ath/ath6kl/cfg80211.c Signed-off-by: Masanari Iida Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 5934e40ee55..d1922d8eb3b 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -194,7 +194,7 @@ static int ath6kl_set_auth_type(struct ath6kl_vif *vif, break; default: - ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type); + ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type); return -ENOTSUPP; } -- cgit v1.2.3-70-g09d2 From 1b46dc04866a4962644ef32d7398e34b40f7ac21 Mon Sep 17 00:00:00 2001 From: Kalle Valo Date: Tue, 31 Jan 2012 21:26:22 +0200 Subject: ath6kl: fix compiler warning in ath6kl_init_hw_params() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both Luis and John reported that they see a compiler warning: drivers/net/wireless/ath/ath6kl/init.c: In function 'ath6kl_init_hw_params': drivers/net/wireless/ath/ath6kl/init.c:1377:26: warning: ‘hw’ may be used uninitialized in this function Oddly enough I have never seen it. But AFAICT the code is correct and hw is not used uninitalized so add uninitialized_var() to inform that to the compiler. Reported-by: Luis R. Rodriguez Reported-by: John W. Linville Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c index bf56e5f1761..0d76c377810 100644 --- a/drivers/net/wireless/ath/ath6kl/init.c +++ b/drivers/net/wireless/ath/ath6kl/init.c @@ -1470,7 +1470,7 @@ static int ath6kl_init_upload(struct ath6kl *ar) int ath6kl_init_hw_params(struct ath6kl *ar) { - const struct ath6kl_hw *hw; + const struct ath6kl_hw *uninitialized_var(hw); int i; for (i = 0; i < ARRAY_SIZE(hw_list); i++) { -- cgit v1.2.3-70-g09d2 From 5fbea5dcc05415474bae7108803e324f112d5b58 Mon Sep 17 00:00:00 2001 From: Chilam Ng Date: Wed, 1 Feb 2012 01:03:37 -0800 Subject: ath6kl: initialize the 'nominal_phy' field in the 'wmi_create_pstream_cmd' struct for create_qos command The nominal_phy field is uninitialized. Initialize it to min_phy_rate for create_qos. kvalo: simplified the equation as checkpatch complained for a too long line Signed-off-by: Chilam Ng Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/debug.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c index 6b546dc6672..d832058816f 100644 --- a/drivers/net/wireless/ath/ath6kl/debug.c +++ b/drivers/net/wireless/ath/ath6kl/debug.c @@ -1441,6 +1441,8 @@ static ssize_t ath6kl_create_qos_write(struct file *file, return -EINVAL; pstream.medium_time = cpu_to_le32(val32); + pstream.nominal_phy = le32_to_cpu(pstream.min_phy_rate) / 1000000; + ath6kl_wmi_create_pstream_cmd(ar->wmi, vif->fw_vif_idx, &pstream); return count; -- cgit v1.2.3-70-g09d2 From b63fd6ce71226e5e048e2035ba202b53f89a1825 Mon Sep 17 00:00:00 2001 From: Philippe Rétornaz Date: Tue, 24 Jan 2012 14:22:01 +0100 Subject: i.MX SDMA: Fix burstsize settings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 6584cb88 (ARM i.MX dma: Fix burstsize settings) fixed the mxcmmc driver but forgot to fix the SDMA driver to handle the correct burtsize. This make the SD card access works again with DMA on i.MX31 boards. Signed-off-by: Philippe Rétornaz Tested-by: Sascha Hauer Acked-by: Sascha Hauer Signed-off-by: Vinod Koul --- drivers/dma/imx-sdma.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index f380e79fd4d..bf736ad679c 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c @@ -1100,11 +1100,13 @@ static int sdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, case DMA_SLAVE_CONFIG: if (dmaengine_cfg->direction == DMA_DEV_TO_MEM) { sdmac->per_address = dmaengine_cfg->src_addr; - sdmac->watermark_level = dmaengine_cfg->src_maxburst; + sdmac->watermark_level = dmaengine_cfg->src_maxburst * + dmaengine_cfg->src_addr_width; sdmac->word_size = dmaengine_cfg->src_addr_width; } else { sdmac->per_address = dmaengine_cfg->dst_addr; - sdmac->watermark_level = dmaengine_cfg->dst_maxburst; + sdmac->watermark_level = dmaengine_cfg->dst_maxburst * + dmaengine_cfg->dst_addr_width; sdmac->word_size = dmaengine_cfg->dst_addr_width; } sdmac->direction = dmaengine_cfg->direction; -- cgit v1.2.3-70-g09d2 From 3596bb929f2abd3433c2eaa5755fad48ac207af1 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Thu, 2 Feb 2012 10:31:26 +0100 Subject: HID: add extra hotkeys in Asus AIO keyboards The Asus All-In-One PC has a wireless keyboard with wifi toggle, brightness up, brightness down and display off hotkeys. This patch adds suppoort for these hotkeys. Signed-off-by: Keng-Yu Lin Signed-off-by: Jiri Kosina --- drivers/hid/hid-chicony.c | 5 +++++ drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + 3 files changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index 8965ad93d51..4162505793c 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -45,6 +45,10 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0xff09: ch_map_key_clear(BTN_9); break; case 0xff0a: ch_map_key_clear(BTN_A); break; case 0xff0b: ch_map_key_clear(BTN_B); break; + case 0x00f1: ch_map_key_clear(KEY_WLAN); break; + case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; + case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; + case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; default: return 0; } @@ -53,6 +57,7 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, static const struct hid_device_id ch_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { } }; MODULE_DEVICE_TABLE(hid, ch_devices); diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index af08ce7207d..75dbe344cab 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1396,6 +1396,7 @@ static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS2) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHUNGHWAT, USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CVTOUCH, USB_DEVICE_ID_CVTOUCH_SCREEN) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index b8574cddd95..fb9e61f8566 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -190,6 +190,7 @@ #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 +#define USB_DEVICE_ID_CHICONY_WIRELESS2 0x1123 #define USB_VENDOR_ID_CHUNGHWAT 0x2247 #define USB_DEVICE_ID_CHUNGHWAT_MULTITOUCH 0x0001 -- cgit v1.2.3-70-g09d2 From 6c30d5a53229aad22bb675e0bd6eb518ecaa4316 Mon Sep 17 00:00:00 2001 From: Keng-Yu Lin Date: Mon, 30 Jan 2012 14:25:45 +0800 Subject: HID: add more hotkeys in Asus AIO keyboards Add support for the camera key. The hotkey for Asus S.H.E(Super Hybrid Engine) mode is mapped to KEY_KEY_PROG1 just for notifying the userspace. Signed-off-by: Keng-Yu Lin Signed-off-by: Jiri Kosina --- drivers/hid/hid-chicony.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-chicony.c b/drivers/hid/hid-chicony.c index 4162505793c..b99af346fdf 100644 --- a/drivers/hid/hid-chicony.c +++ b/drivers/hid/hid-chicony.c @@ -49,6 +49,8 @@ static int ch_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0x00f2: ch_map_key_clear(KEY_BRIGHTNESSDOWN); break; case 0x00f3: ch_map_key_clear(KEY_BRIGHTNESSUP); break; case 0x00f4: ch_map_key_clear(KEY_DISPLAY_OFF); break; + case 0x00f7: ch_map_key_clear(KEY_CAMERA); break; + case 0x00f8: ch_map_key_clear(KEY_PROG1); break; default: return 0; } -- cgit v1.2.3-70-g09d2 From 765031668fb2b064aebd9a568e5ad794cbe3413a Mon Sep 17 00:00:00 2001 From: Nestor Lopez Casado Date: Thu, 2 Feb 2012 10:54:14 +0100 Subject: HID: logitech: fix mask to enable DJ mode The user can only experience the bug if she pairs 6 devices to a Unifying receiver. The sixth paired device would not work. The value changed is actually a bitmask that enables reporting from each paired device. As the sixth bit was not set, the sixth device reports are ignored by the receiver and never get to the driver. Signed-off-by: Nestor Lopez Casado drivers/hid/hid-logitech-dj.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 38b12e45780..2b56efcbdf6 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -445,7 +445,7 @@ static int logi_dj_recv_switch_to_dj_mode(struct dj_receiver_dev *djrcv_dev, dj_report.report_id = REPORT_ID_DJ_SHORT; dj_report.device_index = 0xFF; dj_report.report_type = REPORT_TYPE_CMD_SWITCH; - dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x1F; + dj_report.report_params[CMD_SWITCH_PARAM_DEVBITFIELD] = 0x3F; dj_report.report_params[CMD_SWITCH_PARAM_TIMEOUT_SECONDS] = (u8)timeout; return logi_dj_recv_send_report(djrcv_dev, &dj_report); } -- cgit v1.2.3-70-g09d2 From b89529a10c954f14191367355da2a6053c49abb9 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Thu, 12 Jan 2012 19:40:34 +0100 Subject: Input: Use accessor for MT values The current MT accessor function does not distinguish between the MT values and the slot specification event. Add an accessor function for the values only, and use it where appropriate. Signed-off-by: Henrik Rydberg --- drivers/input/input.c | 2 +- include/linux/input/mt.h | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/input/input.c b/drivers/input/input.c index 1f78c957a75..8921c6180c5 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c @@ -180,7 +180,7 @@ static int input_handle_abs_event(struct input_dev *dev, return INPUT_IGNORE_EVENT; } - is_mt_event = code >= ABS_MT_FIRST && code <= ABS_MT_LAST; + is_mt_event = input_is_mt_value(code); if (!is_mt_event) { pold = &dev->absinfo[code].value; diff --git a/include/linux/input/mt.h b/include/linux/input/mt.h index 318bb82325a..f86737586e1 100644 --- a/include/linux/input/mt.h +++ b/include/linux/input/mt.h @@ -48,10 +48,14 @@ static inline void input_mt_slot(struct input_dev *dev, int slot) input_event(dev, EV_ABS, ABS_MT_SLOT, slot); } +static inline bool input_is_mt_value(int axis) +{ + return axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST; +} + static inline bool input_is_mt_axis(int axis) { - return axis == ABS_MT_SLOT || - (axis >= ABS_MT_FIRST && axis <= ABS_MT_LAST); + return axis == ABS_MT_SLOT || input_is_mt_value(axis); } void input_mt_report_slot_state(struct input_dev *dev, -- cgit v1.2.3-70-g09d2 From 34ce8d07e63baa37d21aeca87f3248b008114899 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Feb 2012 13:45:09 +0000 Subject: regulator: wm8350: Don't specify consumer supplies with struct device Very, very deprecated. Signed-off-by: Mark Brown --- drivers/regulator/wm8350-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 6894009d815..4f46067455c 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c @@ -1544,7 +1544,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, return -ENOMEM; } - led->isink_consumer.dev = &pdev->dev; + led->isink_consumer.dev_name = dev_name(&pdev->dev); led->isink_consumer.supply = "led_isink"; led->isink_init.num_consumer_supplies = 1; led->isink_init.consumer_supplies = &led->isink_consumer; @@ -1559,7 +1559,7 @@ int wm8350_register_led(struct wm8350 *wm8350, int lednum, int dcdc, int isink, return ret; } - led->dcdc_consumer.dev = &pdev->dev; + led->dcdc_consumer.dev_name = dev_name(&pdev->dev); led->dcdc_consumer.supply = "led_vcc"; led->dcdc_init.num_consumer_supplies = 1; led->dcdc_init.consumer_supplies = &led->dcdc_consumer; -- cgit v1.2.3-70-g09d2 From 20a14b84f8d62ba9ad7acad1d67a2ffa3c06468b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 31 Jan 2012 15:13:31 +0800 Subject: regulator: Kill s5m8767_get_reg_id function Calling s5m8767_get_reg_id() is exactly the same as calling rdev_get_id(). It is pointless to add s5m8767_get_reg_id() function. Use rdev_get_id() directly and remove s5m8767_get_reg_id() function. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/s5m8767.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/s5m8767.c b/drivers/regulator/s5m8767.c index a5b9d83913f..5b00e5ac70c 100644 --- a/drivers/regulator/s5m8767.c +++ b/drivers/regulator/s5m8767.c @@ -120,16 +120,11 @@ static const struct s5m_voltage_desc *reg_voltage_map[] = { [S5M8767_BUCK9] = &buck_voltage_val3, }; -static inline int s5m8767_get_reg_id(struct regulator_dev *rdev) -{ - return rdev_get_id(rdev); -} - static int s5m8767_list_voltage(struct regulator_dev *rdev, unsigned int selector) { const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int val; if (reg_id >= ARRAY_SIZE(reg_voltage_map) || reg_id < 0) @@ -148,7 +143,7 @@ static int s5m8767_list_voltage(struct regulator_dev *rdev, static int s5m8767_get_register(struct regulator_dev *rdev, int *reg) { - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); switch (reg_id) { case S5M8767_LDO1 ... S5M8767_LDO2: @@ -224,7 +219,7 @@ static int s5m8767_reg_disable(struct regulator_dev *rdev) static int s5m8767_get_voltage_register(struct regulator_dev *rdev, int *_reg) { - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int reg; switch (reg_id) { @@ -265,7 +260,7 @@ static int s5m8767_get_voltage_sel(struct regulator_dev *rdev) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int reg, mask = 0xff, ret; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); u8 val; ret = s5m8767_get_voltage_register(rdev, ®); @@ -325,7 +320,7 @@ static int s5m8767_set_voltage(struct regulator_dev *rdev, struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); int min_vol = min_uV, max_vol = max_uV; const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int reg, mask, ret; int i; u8 val; @@ -387,7 +382,7 @@ static int s5m8767_set_voltage_buck(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); const struct s5m_voltage_desc *desc; int new_val, old_val, i = 0; int min_vol = min_uV, max_vol = max_uV; @@ -456,7 +451,7 @@ static int s5m8767_set_voltage_time_sel(struct regulator_dev *rdev, { struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); const struct s5m_voltage_desc *desc; - int reg_id = s5m8767_get_reg_id(rdev); + int reg_id = rdev_get_id(rdev); int mask; int new_val, old_val; -- cgit v1.2.3-70-g09d2 From 737f360d5bef5e01c6cfa755dca0b449a154c1e0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Feb 2012 00:10:51 +0000 Subject: regulator: Remove support for supplies specified by struct device This has been deprecated for a very long time now. Signed-off-by: Mark Brown Reviewed-by: Linus Walleij Acked-by: Liam Girdwood --- drivers/regulator/core.c | 23 ++++++++--------------- include/linux/regulator/machine.h | 2 -- 2 files changed, 8 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index e9a83f84ada..b9c900e8179 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -996,7 +996,6 @@ static int set_supply(struct regulator_dev *rdev, /** * set_consumer_device_supply - Bind a regulator to a symbolic supply * @rdev: regulator source - * @consumer_dev: device the supply applies to * @consumer_dev_name: dev_name() string for device supply applies to * @supply: symbolic name for supply * @@ -1008,18 +1007,12 @@ static int set_supply(struct regulator_dev *rdev, * Only one of consumer_dev and consumer_dev_name may be specified. */ static int set_consumer_device_supply(struct regulator_dev *rdev, - struct device *consumer_dev, const char *consumer_dev_name, - const char *supply) + const char *consumer_dev_name, + const char *supply) { struct regulator_map *node; int has_dev; - if (consumer_dev && consumer_dev_name) - return -EINVAL; - - if (!consumer_dev_name && consumer_dev) - consumer_dev_name = dev_name(consumer_dev); - if (supply == NULL) return -EINVAL; @@ -1039,11 +1032,12 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, if (strcmp(node->supply, supply) != 0) continue; - dev_dbg(consumer_dev, "%s/%s is '%s' supply; fail %s/%s\n", - dev_name(&node->regulator->dev), - node->regulator->desc->name, - supply, - dev_name(&rdev->dev), rdev_get_name(rdev)); + pr_debug("%s: %s/%s is '%s' supply; fail %s/%s\n", + consumer_dev_name, + dev_name(&node->regulator->dev), + node->regulator->desc->name, + supply, + dev_name(&rdev->dev), rdev_get_name(rdev)); return -EBUSY; } @@ -2855,7 +2849,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, if (init_data) { for (i = 0; i < init_data->num_consumer_supplies; i++) { ret = set_consumer_device_supply(rdev, - init_data->consumer_supplies[i].dev, init_data->consumer_supplies[i].dev_name, init_data->consumer_supplies[i].supply); if (ret < 0) { diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index f3f13fd5868..7abb1609331 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h @@ -139,12 +139,10 @@ struct regulation_constraints { * make struct device available late such as I2C and is the preferred * form. * - * @dev: Device structure for the consumer. * @dev_name: Result of dev_name() for the consumer. * @supply: Name for the supply. */ struct regulator_consumer_supply { - struct device *dev; /* consumer */ const char *dev_name; /* dev_name() for consumer */ const char *supply; /* consumer supply - e.g. "vcc" */ }; -- cgit v1.2.3-70-g09d2 From 7437cfa532842ce75189826742bddf1ba137f58e Mon Sep 17 00:00:00 2001 From: Ulf Hansson Date: Wed, 18 Jan 2012 09:17:27 +0100 Subject: ARM: 7280/1: mmc: mmci: Cache MMCICLOCK and MMCIPOWER register Instead of reading a register value everytime we need to apply a new value for it, maintain a cached copy for it. This also means we are able to skip writes that are not needed. Tested-by: Linus Walleij Signed-off-by: Ulf Hansson Signed-off-by: Linus Walleij Signed-off-by: Russell King --- drivers/mmc/host/mmci.c | 41 +++++++++++++++++++++++++++++------------ drivers/mmc/host/mmci.h | 3 ++- 2 files changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 1f8832699cd..f36d8b8c891 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c @@ -118,6 +118,28 @@ static struct variant_data variant_ux500v2 = { .signal_direction = true, }; +/* + * This must be called with host->lock held + */ +static void mmci_write_clkreg(struct mmci_host *host, u32 clk) +{ + if (host->clk_reg != clk) { + host->clk_reg = clk; + writel(clk, host->base + MMCICLOCK); + } +} + +/* + * This must be called with host->lock held + */ +static void mmci_write_pwrreg(struct mmci_host *host, u32 pwr) +{ + if (host->pwr_reg != pwr) { + host->pwr_reg = pwr; + writel(pwr, host->base + MMCIPOWER); + } +} + /* * This must be called with host->lock held */ @@ -165,7 +187,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_8) clk |= MCI_ST_8BIT_BUS; - writel(clk, host->base + MMCICLOCK); + mmci_write_clkreg(host, clk); } static void @@ -846,14 +868,13 @@ static int mmci_pio_write(struct mmci_host *host, char *buffer, unsigned int rem */ if (variant->sdio && mmc_card_sdio(host->mmc->card)) { + u32 clk; if (count < 8) - writel(readl(host->base + MMCICLOCK) & - ~variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg & ~variant->clkreg_enable; else - writel(readl(host->base + MMCICLOCK) | - variant->clkreg_enable, - host->base + MMCICLOCK); + clk = host->clk_reg | variant->clkreg_enable; + + mmci_write_clkreg(host, clk); } /* @@ -1114,11 +1135,7 @@ static void mmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) spin_lock_irqsave(&host->lock, flags); mmci_set_clkreg(host, ios->clock); - - if (host->pwr != pwr) { - host->pwr = pwr; - writel(pwr, host->base + MMCIPOWER); - } + mmci_write_pwrreg(host, pwr); spin_unlock_irqrestore(&host->lock, flags); diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index 89eb2e3556d..d437ccf62d6 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h @@ -179,7 +179,8 @@ struct mmci_host { unsigned int mclk; unsigned int cclk; - u32 pwr; + u32 pwr_reg; + u32 clk_reg; struct mmci_platform_data *plat; struct variant_data *variant; -- cgit v1.2.3-70-g09d2 From 14af60b6fb3b76634278364b697dae2f9f360abf Mon Sep 17 00:00:00 2001 From: Chris Blair Date: Thu, 2 Feb 2012 13:59:34 +0100 Subject: spi/pl022: Add high priority message pump support This switches the PL022 worker to a kthread in order to get hold of a mechanism to control the message pump priority. On low-latency systems elevating the message kthread to realtime priority give a real sleek response curve. This has been confirmed by measurements. Realtime priority elevation for a certain PL022 port can be requested from platform data. Cc: Mark Brown Acked-by: Viresh Kumar Signed-off-by: Chris Blair Signed-off-by: Linus Walleij Signed-off-by: Grant Likely --- drivers/spi/spi-pl022.c | 77 +++++++++++++++++++++++++++++++--------------- include/linux/amba/pl022.h | 3 ++ 2 files changed, 55 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 2f9cb43a239..81847c9a758 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include @@ -41,6 +41,7 @@ #include #include #include +#include /* * This macro is used to define some register default values. @@ -330,12 +331,13 @@ struct vendor_data { * @clk: outgoing clock "SPICLK" for the SPI bus * @master: SPI framework hookup * @master_info: controller-specific data from machine setup - * @workqueue: a workqueue on which any spi_message request is queued - * @pump_messages: work struct for scheduling work to the workqueue + * @kworker: thread struct for message pump + * @kworker_task: pointer to task for message pump kworker thread + * @pump_messages: work struct for scheduling work to the message pump * @queue_lock: spinlock to syncronise access to message queue * @queue: message queue - * @busy: workqueue is busy - * @running: workqueue is running + * @busy: message pump is busy + * @running: message pump is running * @pump_transfers: Tasklet used in Interrupt Transfer mode * @cur_msg: Pointer to current spi_message being processed * @cur_transfer: Pointer to current spi_transfer @@ -365,9 +367,10 @@ struct pl022 { struct clk *clk; struct spi_master *master; struct pl022_ssp_controller *master_info; - /* Driver message queue */ - struct workqueue_struct *workqueue; - struct work_struct pump_messages; + /* Driver message pump */ + struct kthread_worker kworker; + struct task_struct *kworker_task; + struct kthread_work pump_messages; spinlock_t queue_lock; struct list_head queue; bool busy; @@ -504,7 +507,7 @@ static void giveback(struct pl022 *pl022) pl022->cur_msg = NULL; pl022->cur_transfer = NULL; pl022->cur_chip = NULL; - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); spin_unlock_irqrestore(&pl022->queue_lock, flags); msg->state = NULL; @@ -1494,8 +1497,8 @@ out: } /** - * pump_messages - Workqueue function which processes spi message queue - * @data: pointer to private data of SSP driver + * pump_messages - kthread work function which processes spi message queue + * @work: pointer to kthread work struct contained in the pl022 private struct * * This function checks if there is any spi message in the queue that * needs processing and delegate control to appropriate function @@ -1503,7 +1506,7 @@ out: * based on the kind of the transfer * */ -static void pump_messages(struct work_struct *work) +static void pump_messages(struct kthread_work *work) { struct pl022 *pl022 = container_of(work, struct pl022, pump_messages); @@ -1556,7 +1559,7 @@ static void pump_messages(struct work_struct *work) if (!was_busy) /* * We enable the core voltage and clocks here, then the clocks - * and core will be disabled when this workqueue is run again + * and core will be disabled when this thread is run again * and there is no more work to be done. */ pm_runtime_get_sync(&pl022->adev->dev); @@ -1572,6 +1575,8 @@ static void pump_messages(struct work_struct *work) static int __init init_queue(struct pl022 *pl022) { + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + INIT_LIST_HEAD(&pl022->queue); spin_lock_init(&pl022->queue_lock); @@ -1581,11 +1586,29 @@ static int __init init_queue(struct pl022 *pl022) tasklet_init(&pl022->pump_transfers, pump_transfers, (unsigned long)pl022); - INIT_WORK(&pl022->pump_messages, pump_messages); - pl022->workqueue = create_singlethread_workqueue( + init_kthread_worker(&pl022->kworker); + pl022->kworker_task = kthread_run(kthread_worker_fn, + &pl022->kworker, dev_name(pl022->master->dev.parent)); - if (pl022->workqueue == NULL) - return -EBUSY; + if (IS_ERR(pl022->kworker_task)) { + dev_err(&pl022->adev->dev, + "failed to create message pump task\n"); + return -ENOMEM; + } + init_kthread_work(&pl022->pump_messages, pump_messages); + + /* + * Board config will indicate if this controller should run the + * message pump with high (realtime) priority to reduce the transfer + * latency on the bus by minimising the delay between a transfer + * request and the scheduling of the message pump thread. Without this + * setting the message pump thread will remain at default priority. + */ + if (pl022->master_info->rt) { + dev_info(&pl022->adev->dev, + "will run message pump with realtime priority\n"); + sched_setscheduler(pl022->kworker_task, SCHED_FIFO, ¶m); + } return 0; } @@ -1608,7 +1631,7 @@ static int start_queue(struct pl022 *pl022) pl022->next_msg_cs_active = false; spin_unlock_irqrestore(&pl022->queue_lock, flags); - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); return 0; } @@ -1646,16 +1669,20 @@ static int destroy_queue(struct pl022 *pl022) int status; status = stop_queue(pl022); - /* we are unloading the module or failing to load (only two calls + + /* + * We are unloading the module or failing to load (only two calls * to this routine), and neither call can handle a return value. - * However, destroy_workqueue calls flush_workqueue, and that will - * block until all work is done. If the reason that stop_queue - * timed out is that the work will never finish, then it does no - * good to call destroy_workqueue, so return anyway. */ + * However, flush_kthread_worker will block until all work is done. + * If the reason that stop_queue timed out is that the work will never + * finish, then it does no good to call flush/stop thread, so + * return anyway. + */ if (status != 0) return status; - destroy_workqueue(pl022->workqueue); + flush_kthread_worker(&pl022->kworker); + kthread_stop(pl022->kworker_task); return 0; } @@ -1802,7 +1829,7 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) list_add_tail(&msg->queue, &pl022->queue); if (pl022->running && !pl022->busy) - queue_work(pl022->workqueue, &pl022->pump_messages); + queue_kthread_work(&pl022->kworker, &pl022->pump_messages); spin_unlock_irqrestore(&pl022->queue_lock, flags); return 0; diff --git a/include/linux/amba/pl022.h b/include/linux/amba/pl022.h index 572f637299c..3672f40f345 100644 --- a/include/linux/amba/pl022.h +++ b/include/linux/amba/pl022.h @@ -241,6 +241,8 @@ struct dma_chan; * @autosuspend_delay: delay in ms following transfer completion before the * runtime power management system suspends the device. A setting of 0 * indicates no delay and the device will be suspended immediately. + * @rt: indicates the controller should run the message pump with realtime + * priority to minimise the transfer latency on the bus. */ struct pl022_ssp_controller { u16 bus_id; @@ -250,6 +252,7 @@ struct pl022_ssp_controller { void *dma_rx_param; void *dma_tx_param; int autosuspend_delay; + bool rt; }; /** -- cgit v1.2.3-70-g09d2 From 5816269e4ee3db2bc2ad44afc89f4abe81c7aa26 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:36 -0700 Subject: tty: serial: OMAP: use a 1-byte RX FIFO threshold in PIO mode In the (default) PIO mode, use a one-byte RX FIFO threshold. The OMAP UART IP blocks do not appear to be capable of waking the system under an RX timeout condition. Since the previous RX FIFO threshold was 16 bytes, this meant that omap-serial.c did not become aware of any received data until all those bytes arrived or until another UART interrupt occurred. This made the serial console and presumably other serial applications (GPS, serial Bluetooth) unusable or extremely slow. A 1-byte RX FIFO threshold also allows the MPU to enter a low-power consumption state while waiting for the FIFO to fill. This can be verified using the serial console by comparing the behavior when "0123456789abcde" is pasted in from another window, with the behavior when "0123456789abcdef" is pasted in. Since the former string is less than sixteen bytes long, the string is not echoed for some time, while the latter string is echoed immediately. DMA operation is unaffected by this patch. Thanks to Russell King - ARM Linux for some additional information on the standard behavior of the RX timeout event, which was used to improve this commit description. Signed-off-by: Paul Walmsley Cc: Tomi Valkeinen Cc: Govindraj Raja Cc: Alan Cox Cc: Russell King Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d192dcbb82f..c9c9ba2a5bb 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -46,6 +46,13 @@ #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ +/* SCR register bitmasks */ +#define OMAP_UART_SCR_RX_TRIG_GRANU1_MASK (1 << 7) + +/* FCR register bitmasks */ +#define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 +#define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) + static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; /* Forward declaration of functions */ @@ -811,14 +818,21 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ - serial_out(up, UART_FCR, up->fcr); - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + + up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; if (up->use_dma) { serial_out(up, UART_TI752_TLR, 0); - up->scr |= (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8); + up->scr |= UART_FCR_TRIGGER_4; + } else { + /* Set receive FIFO threshold to 1 byte */ + up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; + up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT); } + serial_out(up, UART_FCR, up->fcr); + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); + serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); -- cgit v1.2.3-70-g09d2 From edbe5dbefe5b514d094558ab59c8dc7578e117dd Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:52 -0700 Subject: tty: serial: OMAP: block idle while the UART is transferring data in PIO mode Prevent OMAP UARTs from going idle while they are still transferring data in PIO mode. This works around an oversight in the OMAP UART hardware present in OMAP34xx and earlier: an idle UART won't send a wakeup when the TX FIFO threshold is reached. This causes long delays during data transmission when the MPU powerdomain enters a low-power mode. The MPU interrupt controller is not able to respond to interrupts when it's in a low-power state, so the TX buffer is not refilled until another wakeup event occurs. This fix changes the erratum i291 DMA idle workaround. Rather than toggling between force-idle and no-idle, it will toggle between smart-idle and no-idle. The important part of the workaround is the no-idle part, so this shouldn't result in any change in behavior. This fix should work on all OMAP UARTs. Future patches intended for the 3.4 merge window will make this workaround conditional on a "feature" flag, and will use the OMAP36xx+ TX event wakeup support. Thanks to Kevin Hilman for mentioning the erratum i291 workaround, which led to the development of this approach. Signed-off-by: Paul Walmsley Cc: Alan Cox Cc: Tomi Valkeinen Acked-by: Govindraj.R Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- arch/arm/mach-omap2/serial.c | 8 ++++---- drivers/tty/serial/omap-serial.c | 7 +++++++ 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 247d89478f2..f590afc1f67 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -107,18 +107,18 @@ static void omap_uart_set_noidle(struct platform_device *pdev) omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO); } -static void omap_uart_set_forceidle(struct platform_device *pdev) +static void omap_uart_set_smartidle(struct platform_device *pdev) { struct omap_device *od = to_omap_device(pdev); - omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE); + omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_SMART); } #else static void omap_uart_enable_wakeup(struct platform_device *pdev, bool enable) {} static void omap_uart_set_noidle(struct platform_device *pdev) {} -static void omap_uart_set_forceidle(struct platform_device *pdev) {} +static void omap_uart_set_smartidle(struct platform_device *pdev) {} #endif /* CONFIG_PM */ #ifdef CONFIG_OMAP_MUX @@ -349,7 +349,7 @@ void __init omap_serial_init_port(struct omap_board_data *bdata, omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; omap_up.flags = UPF_BOOT_AUTOCONF; omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; - omap_up.set_forceidle = omap_uart_set_forceidle; + omap_up.set_forceidle = omap_uart_set_smartidle; omap_up.set_noidle = omap_uart_set_noidle; omap_up.enable_wakeup = omap_uart_enable_wakeup; omap_up.dma_rx_buf_size = info->dma_rx_buf_size; diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index c9c9ba2a5bb..11fa15623e1 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -136,6 +136,7 @@ static void serial_omap_enable_ms(struct uart_port *port) static void serial_omap_stop_tx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; + struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; if (up->use_dma && up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE) { @@ -158,6 +159,9 @@ static void serial_omap_stop_tx(struct uart_port *port) serial_out(up, UART_IER, up->ier); } + if (!up->use_dma && pdata->set_forceidle) + pdata->set_forceidle(up->pdev); + pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); } @@ -286,6 +290,7 @@ static inline void serial_omap_enable_ier_thri(struct uart_omap_port *up) static void serial_omap_start_tx(struct uart_port *port) { struct uart_omap_port *up = (struct uart_omap_port *)port; + struct omap_uart_port_info *pdata = up->pdev->dev.platform_data; struct circ_buf *xmit; unsigned int start; int ret = 0; @@ -293,6 +298,8 @@ static void serial_omap_start_tx(struct uart_port *port) if (!up->use_dma) { pm_runtime_get_sync(&up->pdev->dev); serial_omap_enable_ier_thri(up); + if (pdata->set_noidle) + pdata->set_noidle(up->pdev); pm_runtime_mark_last_busy(&up->pdev->dev); pm_runtime_put_autosuspend(&up->pdev->dev); return; -- cgit v1.2.3-70-g09d2 From 6bbcbf22085e0b144899d6067e243dd26c0e7533 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 25 Jan 2012 19:50:56 -0700 Subject: tty: serial: omap-serial: wakeup latency constraint is in microseconds, not milliseconds The receive FIFO wakeup latency estimate in the omap-serial driver is three orders of magnitude too small. This effectively prevents the MPU from going to a low-power state when CONFIG_CPU_IDLE=y. This is a major power management regression and masks some other FIFO-related bugs in the driver. Fix by correcting the most egregious problem in the RX wakeup latency estimate. There are several other flaws in the estimator; these will be fixed by a separate patch series intended for 3.4. The difference in low-power states with this patch can be observed via debugfs in pm_debug/count. This estimate does not have any effect when CONFIG_CPU_IDLE=n. Signed-off-by: Paul Walmsley Cc: Tomi Valkeinen Cc: Alan Cox Acked-by: Govindraj.R Reviewed-by: Kevin Hilman Tested-by: Kevin Hilman Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/omap-serial.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index 11fa15623e1..72fa783729d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c @@ -740,8 +740,7 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, quot = serial_omap_get_divisor(port, baud); /* calculate wakeup latency constraint */ - up->calc_latency = (1000000 * up->port.fifosize) / - (1000 * baud / 8); + up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8); up->latency = up->calc_latency; schedule_work(&up->qos_work); -- cgit v1.2.3-70-g09d2 From ed6a3803408f18da387463d569b4edc5078fd9aa Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 2 Jan 2012 16:10:08 +0200 Subject: iwlwifi: add fw_alive to transport layer API, kill tx_start Define a new handler in the transport layer API: fw_alive. Move iwl_reset_ict to this new handler, and move the content of tx_start to this handler. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 3 --- drivers/net/wireless/iwlwifi/iwl-agn.h | 2 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 ++---- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 10 ++++++++-- drivers/net/wireless/iwlwifi/iwl-trans.h | 15 +++++++-------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 2 +- 7 files changed, 19 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 90315c69cdf..9d9185ffc39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1243,9 +1243,6 @@ int iwl_alive_start(struct iwl_priv *priv) int ret = 0; struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; - /*TODO: this should go to the transport layer */ - iwl_reset_ict(trans(priv)); - IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); /* After the ALIVE response, we can send host commands to the uCode */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 39cbe1a1577..0f5133ac357 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -73,8 +73,6 @@ struct iwlagn_ucode_capabilities { extern struct ieee80211_ops iwlagn_hw_ops; -int iwl_reset_ict(struct iwl_trans *trans); - static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd) { hdr->op_code = cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0ac9b4d3027..0f73778b73f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -258,7 +258,7 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, /***************************************************** * ICT ******************************************************/ -int iwl_reset_ict(struct iwl_trans *trans); +void iwl_reset_ict(struct iwl_trans *trans); void iwl_disable_ict(struct iwl_trans *trans); int iwl_alloc_isr_ict(struct iwl_trans *trans); void iwl_free_isr_ict(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 848c598bfad..2822b7e8bca 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1213,7 +1213,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) /* Device is going up inform it about using ICT interrupt table, * also we need to tell the driver to start using ICT interrupt. */ -int iwl_reset_ict(struct iwl_trans *trans) +void iwl_reset_ict(struct iwl_trans *trans) { u32 val; unsigned long flags; @@ -1221,7 +1221,7 @@ int iwl_reset_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (!trans_pcie->ict_tbl) - return 0; + return; spin_lock_irqsave(&trans->shrd->lock, flags); iwl_disable_interrupts(trans); @@ -1241,8 +1241,6 @@ int iwl_reset_ict(struct iwl_trans *trans) iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans->shrd->lock, flags); - - return 0; } /* Device is going down disable ict interrupt usage */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 5e6af4ba965..affa56fafdb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -835,7 +835,7 @@ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) iwl_write_prph(bus(trans), SCD_TXFACT, mask); } -static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) +static void iwl_tx_start(struct iwl_trans *trans) { const struct queue_to_fifo_ac *queue_to_fifo; struct iwl_trans_pcie *trans_pcie = @@ -948,6 +948,12 @@ static void iwl_trans_pcie_tx_start(struct iwl_trans *trans) APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } +static void iwl_trans_pcie_fw_alive(struct iwl_trans *trans) +{ + iwl_reset_ict(trans); + iwl_tx_start(trans); +} + /** * iwlagn_txq_ctx_stop - Stop all Tx DMA channels */ @@ -1903,11 +1909,11 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie = { .alloc = iwl_trans_pcie_alloc, .request_irq = iwl_trans_pcie_request_irq, + .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, .stop_device = iwl_trans_pcie_stop_device, - .tx_start = iwl_trans_pcie_tx_start, .wake_any_queue = iwl_trans_pcie_wake_any_queue, .send_cmd = iwl_trans_pcie_send_cmd, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 42a9f303f54..9795a23ee94 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -139,8 +139,7 @@ struct iwl_host_cmd { * layer. * @prepare_card_hw: claim the ownership on the HW. Will be called during * probe. - * @tx_start: starts and configures all the Tx fifo - usually done once the fw - * is alive. + * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) * @send_cmd:send a host command @@ -166,9 +165,9 @@ struct iwl_trans_ops { struct iwl_trans *(*alloc)(struct iwl_shared *shrd); int (*request_irq)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); + void (*fw_alive)(struct iwl_trans *trans); int (*prepare_card_hw)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); - void (*tx_start)(struct iwl_trans *trans); void (*wake_any_queue)(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, @@ -264,6 +263,11 @@ static inline int iwl_trans_request_irq(struct iwl_trans *trans) return trans->ops->request_irq(trans); } +static inline void iwl_trans_fw_alive(struct iwl_trans *trans) +{ + trans->ops->fw_alive(trans); +} + static inline int iwl_trans_start_device(struct iwl_trans *trans) { return trans->ops->start_device(trans); @@ -279,11 +283,6 @@ static inline void iwl_trans_stop_device(struct iwl_trans *trans) trans->ops->stop_device(trans); } -static inline void iwl_trans_tx_start(struct iwl_trans *trans) -{ - trans->ops->tx_start(trans); -} - static inline void iwl_trans_wake_any_queue(struct iwl_trans *trans, enum iwl_rxon_context_id ctx, const char *msg) diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 2edf0ef65a5..0d7f207ac61 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -447,7 +447,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) if (!priv->tx_cmd_pool) return -ENOMEM; - iwl_trans_tx_start(trans); + iwl_trans_fw_alive(trans); for_each_context(priv, ctx) ctx->last_tx_rejected = false; -- cgit v1.2.3-70-g09d2 From a591697730a3c416cd384bc199eb5dde622c4c78 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 10 Jan 2012 19:22:56 +0200 Subject: iwlwifi: Connect IDI transport to driver. This patch connects IDI transport to driver. It does so by using a number of ifdefs at this stage. IDI is a new transport that is under development. Signed-off-by: Gregory Greenman Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 13 ++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 7 ++++++- drivers/net/wireless/iwlwifi/iwl-trans.h | 1 + 4 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 03702a2e913..2c46063522c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -454,7 +454,11 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) bus->irq = pdev->irq; bus->ops = &bus_ops_pci; +#ifdef CONFIG_IWLWIFI_IDI + err = iwl_probe(bus, &trans_ops_idi, cfg); +#else err = iwl_probe(bus, &trans_ops_pcie, cfg); +#endif if (err) goto out_disable_msi; return 0; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 2822b7e8bca..b94c95370b7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -35,6 +35,10 @@ #include "iwl-io.h" #include "iwl-trans-pcie-int.h" +#ifdef CONFIG_IWLWIFI_IDI +#include "iwl-amfh.h" +#endif + /****************************************************************************** * * RX path functions @@ -1100,8 +1104,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* Disable periodic interrupt; we use it as just a one-shot. */ iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); +#ifdef CONFIG_IWLWIFI_IDI + iwl_amfh_rx_handler(); +#else iwl_rx_handle(trans); - +#endif /* * Enable periodic interrupt in 8 msec only if we received * real RX interrupt (instead of just periodic int), to catch @@ -1123,7 +1130,11 @@ void iwl_irq_tasklet(struct iwl_trans *trans) isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ +#ifdef CONFIG_IWLWIFI_IDI + trans->shrd->trans->ucode_write_complete = 1; +#else trans->ucode_write_complete = 1; +#endif wake_up(&trans->shrd->wait_command_queue); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index affa56fafdb..0b4280c9258 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -647,8 +647,10 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_nic_config(priv(trans)); +#ifndef CONFIG_IWLWIFI_IDI /* Allocate the RX queue, or reset if it is already allocated */ iwl_rx_init(trans); +#endif /* Allocate or reset and init all Tx and Command queues */ if (iwl_tx_init(trans)) @@ -1016,8 +1018,9 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) */ if (test_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status)) { iwl_trans_tx_stop(trans); +#ifndef CONFIG_IWLWIFI_IDI iwl_trans_rx_stop(trans); - +#endif /* Power-down device's busmaster DMA clocks */ iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); @@ -1298,7 +1301,9 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) { iwl_calib_free_results(trans); iwl_trans_pcie_tx_free(trans); +#ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); +#endif free_irq(bus(trans)->irq, trans); iwl_free_isr_ict(trans); trans->shrd->trans = NULL; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 9795a23ee94..2a6649c9ca4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -383,6 +383,7 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) * Transport layers implementations ******************************************************/ extern const struct iwl_trans_ops trans_ops_pcie; +extern const struct iwl_trans_ops trans_ops_idi; int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, const void *data, size_t len); -- cgit v1.2.3-70-g09d2 From 8747bb4936c137bb93b91afd70eedd65069d26cd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 4 Jan 2012 16:57:09 +0200 Subject: iwlwifi: separate the APM from the EEPROM There is no link between the two. Ensure that the NIC is on outside the code of the EEPROM handling. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++ drivers/net/wireless/iwlwifi/iwl-eeprom.c | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 9d9185ffc39..f3bd6a3eec3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1848,8 +1848,12 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /***************** * 4. Read EEPROM *****************/ + /* switch the NIC on before accessing the EEPROM */ + iwl_apm_init(priv); /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); + /* Reset chip to save power until we load uCode during "up". */ + iwl_apm_stop(priv); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_free_trans; diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index e27d9f55267..ce214e0ab49 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -676,8 +676,6 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) } e = (__le16 *)shrd->eeprom; - iwl_apm_init(priv); - ret = iwl_eeprom_verify_signature(trans(priv)); if (ret < 0) { IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp); @@ -758,8 +756,6 @@ done: err: if (ret) iwl_eeprom_free(priv->shrd); - /* Reset chip to save power until we load uCode during "up". */ - iwl_apm_stop(priv); alloc_err: return ret; } -- cgit v1.2.3-70-g09d2 From 87e7597b5a3f99238d95d63c44c9f872a41b37ae Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 1 Feb 2012 10:49:17 +0000 Subject: qeth: Move away from using neighbour entries in qeth_l3_fill_header() We've moving to a model where dst_entry objects to not have a reference to the associated neighbour entry, instead such neighbours must be looked up on-demand. Here in qeth_l3_fill_header() it's actually much simpler to use the information in the route itself. The code is already conditionalized upon protocol type. Signed-off-by: David S. Miller Tested-by: Ursula Braun --- drivers/s390/net/qeth_l3_main.c | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 9648e4e6833..25cd3799a76 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -28,6 +28,8 @@ #include #include +#include +#include #include #include @@ -2832,7 +2834,6 @@ static void qeth_l3_fill_af_iucv_hdr(struct qeth_card *card, static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, struct sk_buff *skb, int ipv, int cast_type) { - struct neighbour *n = NULL; struct dst_entry *dst; memset(hdr, 0, sizeof(struct qeth_hdr)); @@ -2855,33 +2856,29 @@ static void qeth_l3_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, rcu_read_lock(); dst = skb_dst(skb); - if (dst) - n = dst_get_neighbour_noref(dst); if (ipv == 4) { + struct rtable *rt = (struct rtable *) dst; + __be32 *pkey = &ip_hdr(skb)->daddr; + + if (rt->rt_gateway) + pkey = &rt->rt_gateway; + /* IPv4 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags4(cast_type); memset(hdr->hdr.l3.dest_addr, 0, 12); - if (n) { - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - *((u32 *) n->primary_key); - } else { - /* fill in destination address used in ip header */ - *((u32 *) (&hdr->hdr.l3.dest_addr[12])) = - ip_hdr(skb)->daddr; - } + *((__be32 *) (&hdr->hdr.l3.dest_addr[12])) = *pkey; } else if (ipv == 6) { + struct rt6_info *rt = (struct rt6_info *) dst; + struct in6_addr *pkey = &ipv6_hdr(skb)->daddr; + + if (!ipv6_addr_any(&rt->rt6i_gateway)) + pkey = &rt->rt6i_gateway; + /* IPv6 */ hdr->hdr.l3.flags = qeth_l3_get_qeth_hdr_flags6(cast_type); if (card->info.type == QETH_CARD_TYPE_IQD) hdr->hdr.l3.flags &= ~QETH_HDR_PASSTHRU; - if (n) { - memcpy(hdr->hdr.l3.dest_addr, - n->primary_key, 16); - } else { - /* fill in destination address used in ip header */ - memcpy(hdr->hdr.l3.dest_addr, - &ipv6_hdr(skb)->daddr, 16); - } + memcpy(hdr->hdr.l3.dest_addr, pkey, 16); } else { /* passthrough */ if ((skb->dev->type == ARPHRD_IEEE802_TR) && -- cgit v1.2.3-70-g09d2 From e1f4c485cdb2b1d7aae172b731f6c2b403381ebb Mon Sep 17 00:00:00 2001 From: Danny Kukawka Date: Thu, 2 Feb 2012 03:20:28 +0000 Subject: eicon: fix -Warray-bounds warning Fix for a -Warray-bounds warning. mixer_notify_update() tries to write to ((CAPI_MSG *) msg)->info.facility_req.structs[3] while structs is defined as byte structs[1]. Set all 'structs' which are part of the typdefs in the info union to 'byte structs[0]'. v2: set all info.*.structs to byte structs[0] Signed-off-by: Danny Kukawka Signed-off-by: David S. Miller --- drivers/isdn/hardware/eicon/capi20.h | 60 ++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hardware/eicon/capi20.h b/drivers/isdn/hardware/eicon/capi20.h index 7ebcccda74d..27ecd61888d 100644 --- a/drivers/isdn/hardware/eicon/capi20.h +++ b/drivers/isdn/hardware/eicon/capi20.h @@ -117,7 +117,7 @@ typedef struct api_profile_s { /*------------------------------------------------------------------*/ /* ALERT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _ALT_REQP; /* ALERT-CONFIRM */ typedef struct { @@ -126,7 +126,7 @@ typedef struct { /* CONNECT-REQUEST */ typedef struct { word CIP_Value; - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Called party subaddress, Calling party number, Calling party subaddress, @@ -143,7 +143,7 @@ typedef struct { /* CONNECT-INDICATION */ typedef struct { word CIP_Value; - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Called party subaddress, Calling party number, Calling party subaddress, @@ -155,24 +155,24 @@ typedef struct { /* CONNECT-RESPONSE */ typedef struct { word Accept; - byte structs[1]; /* B_protocol, + byte structs[0]; /* B_protocol, Connected party number, Connected party subaddress, LLC */ } _CON_RESP; /* CONNECT-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* Connected party number, + byte structs[0]; /* Connected party number, Connected party subaddress, LLC */ } _CON_A_INDP; /* CONNECT-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_A_RESP; /* DISCONNECT-REQUEST */ typedef struct { - byte structs[1]; /* Additional Info */ + byte structs[0]; /* Additional Info */ } _DIS_REQP; /* DISCONNECT-CONFIRM */ typedef struct { @@ -184,13 +184,13 @@ typedef struct { } _DIS_INDP; /* DISCONNECT-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_RESP; /* LISTEN-REQUEST */ typedef struct { dword Info_Mask; dword CIP_Mask; - byte structs[1]; /* Calling party number, + byte structs[0]; /* Calling party number, Calling party subaddress */ } _LIS_REQP; /* LISTEN-CONFIRM */ @@ -199,7 +199,7 @@ typedef struct { } _LIS_CONP; /* INFO-REQUEST */ typedef struct { - byte structs[1]; /* Called party number, + byte structs[0]; /* Called party number, Additional Info */ } _INF_REQP; /* INFO-CONFIRM */ @@ -209,15 +209,15 @@ typedef struct { /* INFO-INDICATION */ typedef struct { word Number; - byte structs[1]; /* Info element */ + byte structs[0]; /* Info element */ } _INF_INDP; /* INFO-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _INF_RESP; /* SELECT-B-REQUEST */ typedef struct { - byte structs[1]; /* B-protocol */ + byte structs[0]; /* B-protocol */ } _SEL_B_REQP; /* SELECT-B-CONFIRM */ typedef struct { @@ -226,7 +226,7 @@ typedef struct { /* FACILITY-REQUEST */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_REQP; /* FACILITY-CONFIRM STRUCT FOR SUPPLEMENT. SERVICES */ typedef struct { @@ -240,21 +240,21 @@ typedef struct { typedef struct { word Info; word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_CONP; /* FACILITY-INDICATION */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_INDP; /* FACILITY-RESPONSE */ typedef struct { word Selector; - byte structs[1]; /* Facility parameters */ + byte structs[0]; /* Facility parameters */ } _FAC_RESP; /* CONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_REQP; /* CONNECT-B3-CONFIRM */ typedef struct { @@ -262,24 +262,24 @@ typedef struct { } _CON_B3_CONP; /* CONNECT-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_INDP; /* CONNECT-B3-RESPONSE */ typedef struct { word Accept; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_RESP; /* CONNECT-B3-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_A_INDP; /* CONNECT-B3-ACTIVE-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _CON_B3_A_RESP; /* DISCONNECT-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _DIS_B3_REQP; /* DISCONNECT-B3-CONFIRM */ typedef struct { @@ -288,11 +288,11 @@ typedef struct { /* DISCONNECT-B3-INDICATION */ typedef struct { word Info; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _DIS_B3_INDP; /* DISCONNECT-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _DIS_B3_RESP; /* DATA-B3-REQUEST */ typedef struct { @@ -335,7 +335,7 @@ typedef struct { } _DAT_B3_RESP; /* RESET-B3-REQUEST */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_REQP; /* RESET-B3-CONFIRM */ typedef struct { @@ -343,20 +343,20 @@ typedef struct { } _RES_B3_CONP; /* RESET-B3-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _RES_B3_INDP; /* RESET-B3-RESPONSE */ typedef struct { - byte structs[1]; /* empty */ + byte structs[0]; /* empty */ } _RES_B3_RESP; /* CONNECT-B3-T90-ACTIVE-INDICATION */ typedef struct { - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_INDP; /* CONNECT-B3-T90-ACTIVE-RESPONSE */ typedef struct { word Reject; - byte structs[1]; /* NCPI */ + byte structs[0]; /* NCPI */ } _CON_B3_T90_A_RESP; /*------------------------------------------------------------------*/ /* message structure */ -- cgit v1.2.3-70-g09d2 From e81fb554cfe082dc59a707767c426cbd2e361033 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:08:57 -0800 Subject: iwlwifi: move the shrd memory from priv Allocating the shrd area dynamically will allow more agility while revamping the flows. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 +--- drivers/net/wireless/iwlwifi/iwl-dev.h | 1 - drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ++++++++++ 3 files changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f3bd6a3eec3..b42be308450 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1780,9 +1780,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, } priv = hw->priv; - priv->shrd = &priv->_shrd; - bus->shrd = priv->shrd; - priv->shrd->bus = bus; + priv->shrd = bus->shrd; priv->shrd->priv = priv; priv->shrd->trans = trans_ops->alloc(priv->shrd); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index af846002150..fff5b620927 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -821,7 +821,6 @@ struct iwl_wipan_noa_data { struct iwl_priv { /*data shared among all the driver's layers */ - struct iwl_shared _shrd; struct iwl_shared *shrd; /* ieee device used by generic ieee processing code */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 2c46063522c..a3ca0a78336 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -374,10 +374,18 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!bus) { dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_pci_bus"); + return -ENOMEM; + } + + bus->shrd = kzalloc(sizeof(*bus->shrd), GFP_KERNEL); + if (!bus->shrd) { + dev_printk(KERN_ERR, &pdev->dev, + "Couldn't allocate iwl_shared"); err = -ENOMEM; goto out_no_pci; } + bus->shrd->bus = bus; pci_bus = IWL_BUS_GET_PCI_BUS(bus); pci_bus->pci_dev = pdev; @@ -472,6 +480,7 @@ out_pci_release_regions: out_pci_disable_device: pci_disable_device(pdev); out_no_pci: + kfree(bus->shrd); kfree(bus); return err; } @@ -491,6 +500,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) pci_disable_device(pci_dev); pci_set_drvdata(pci_dev, NULL); + kfree(bus->shrd); kfree(bus); } -- cgit v1.2.3-70-g09d2 From b52e7ea109cfe4ea7fea99b1cd20f57ccd95476a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:16:59 -0800 Subject: iwlwifi: allocate the transport from the bus layer Change the way we alloc the transport on the way. Since the transport is allocated from a bus specific area, we can give the bus specific parameters (i.e. pci_dev for PCI) to the transport. This will be useful when the bus layer will be killed. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 16 +++------------- drivers/net/wireless/iwlwifi/iwl-pci.c | 17 ++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 24 ++++++++++++++---------- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +++++++++++++++------ 4 files changed, 48 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index b42be308450..1a4ba9de99b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1783,12 +1783,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, priv->shrd = bus->shrd; priv->shrd->priv = priv; - priv->shrd->trans = trans_ops->alloc(priv->shrd); - if (priv->shrd->trans == NULL) { - err = -ENOMEM; - goto out_free_traffic_mem; - } - /* At this point both hw and priv are allocated. */ SET_IEEE80211_DEV(hw, bus(priv)->dev); @@ -1835,12 +1829,12 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, err = iwl_trans_request_irq(trans(priv)); if (err) - goto out_free_trans; + goto out_free_traffic_mem; if (iwl_trans_prepare_card_hw(trans(priv))) { err = -EIO; IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_trans; + goto out_free_traffic_mem; } /***************** @@ -1854,7 +1848,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_apm_stop(priv); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); - goto out_free_trans; + goto out_free_traffic_mem; } err = iwl_eeprom_check_version(priv); if (err) @@ -1935,8 +1929,6 @@ out_destroy_workqueue: iwl_uninit_drv(priv); out_free_eeprom: iwl_eeprom_free(priv->shrd); -out_free_trans: - iwl_trans_free(trans(priv)); out_free_traffic_mem: iwl_free_traffic_mem(priv); ieee80211_free_hw(priv->hw); @@ -1980,8 +1972,6 @@ void __devexit iwl_remove(struct iwl_priv * priv) priv->shrd->workqueue = NULL; iwl_free_traffic_mem(priv); - iwl_trans_free(trans(priv)); - iwl_uninit_drv(priv); dev_kfree_skb(priv->beacon_skb); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index a3ca0a78336..c0d62e72495 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -463,14 +463,28 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI + trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); + if (trans(bus) == NULL) { + err = -ENOMEM; + goto out_disable_msi; + } + err = iwl_probe(bus, &trans_ops_idi, cfg); #else + trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); + if (trans(bus) == NULL) { + err = -ENOMEM; + goto out_disable_msi; + } + err = iwl_probe(bus, &trans_ops_pcie, cfg); #endif if (err) - goto out_disable_msi; + goto out_free_trans; return 0; +out_free_trans: + iwl_trans_free(trans(bus)); out_disable_msi: pci_disable_msi(pdev); pci_iounmap(pdev, pci_bus->hw_base); @@ -493,6 +507,7 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) struct iwl_shared *shrd = bus->shrd; iwl_remove(shrd->priv); + iwl_trans_free(shrd->trans); pci_disable_msi(pci_dev); pci_iounmap(pci_dev, pci_bus->hw_base); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 0b4280c9258..f0d8cccbcb1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1376,19 +1376,24 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie; -static struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd) +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent) { + struct iwl_trans_pcie *trans_pcie; struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + sizeof(struct iwl_trans_pcie), GFP_KERNEL); - if (iwl_trans) { - struct iwl_trans_pcie *trans_pcie = - IWL_TRANS_GET_PCIE_TRANS(iwl_trans); - iwl_trans->ops = &trans_ops_pcie; - iwl_trans->shrd = shrd; - trans_pcie->trans = iwl_trans; - spin_lock_init(&iwl_trans->hcmd_lock); - } + + if (WARN_ON(!iwl_trans)) + return NULL; + + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); + + iwl_trans->ops = &trans_ops_pcie; + iwl_trans->shrd = shrd; + trans_pcie->trans = iwl_trans; + spin_lock_init(&iwl_trans->hcmd_lock); return iwl_trans; } @@ -1912,7 +1917,6 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, #endif /*CONFIG_IWLWIFI_DEBUGFS */ const struct iwl_trans_ops trans_ops_pcie = { - .alloc = iwl_trans_pcie_alloc, .request_irq = iwl_trans_pcie_request_irq, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 2a6649c9ca4..b1a7af26c57 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -133,7 +133,6 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations - * @alloc: allocates the meta data (not the queues themselves) * @request_irq: requests IRQ - will be called before the FW load in probe flow * @start_device: allocates and inits all the resources for the transport * layer. @@ -162,7 +161,6 @@ struct iwl_host_cmd { */ struct iwl_trans_ops { - struct iwl_trans *(*alloc)(struct iwl_shared *shrd); int (*request_irq)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); @@ -380,11 +378,8 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) #endif /***************************************************** -* Transport layers implementations +* Utils functions ******************************************************/ -extern const struct iwl_trans_ops trans_ops_pcie; -extern const struct iwl_trans_ops trans_ops_idi; - int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); @@ -394,4 +389,18 @@ int iwl_calib_set(struct iwl_trans *trans, const struct iwl_calib_hdr *cmd, int len); void iwl_calib_free_results(struct iwl_trans *trans); +/***************************************************** +* Transport layers implementations + their allocation function +******************************************************/ +struct pci_dev; +struct pci_device_id; +extern const struct iwl_trans_ops trans_ops_pcie; +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent); + +extern const struct iwl_trans_ops trans_ops_idi; +struct iwl_trans *iwl_trans_idi_alloc(struct iwl_shared *shrd, + void *pdev_void, + const void *ent_void); #endif /* __iwl_trans_h__ */ -- cgit v1.2.3-70-g09d2 From a42a184458ae95937893cb873c988385637c5e14 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 2 Feb 2012 14:33:08 -0800 Subject: iwlwifi: move the bus configuration to transport All the bus configuration is now done in the transport allocation fucntion. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 2 - drivers/net/wireless/iwlwifi/iwl-pci.c | 93 +----------- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 6 + drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 169 ++++++++++++++++++---- drivers/net/wireless/iwlwifi/iwl-trans.h | 5 + 5 files changed, 158 insertions(+), 117 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 941b9cb2344..37ed7b60aaf 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -148,7 +148,6 @@ struct iwl_bus_ops { * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data - * @irq - the irq number for the device * @reg_lock - protect hw register access */ struct iwl_bus { @@ -156,7 +155,6 @@ struct iwl_bus { const struct iwl_bus_ops *ops; struct iwl_shared *shrd; - unsigned int irq; spinlock_t reg_lock; /* pointer to bus specific struct */ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index c0d62e72495..631b67ca2b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -367,7 +367,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_bus *bus; struct iwl_pci_bus *pci_bus; - u16 pci_cmd; int err; bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); @@ -382,7 +381,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_shared"); err = -ENOMEM; - goto out_no_pci; + goto out_free_bus; } bus->shrd->bus = bus; @@ -391,82 +390,14 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, bus); - /* W/A - seems to solve weird behavior. We need to remove this if we - * don't want to stay in L1 all the time. This wastes a lot of power */ - pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | - PCIE_LINK_STATE_CLKPM); - - if (pci_enable_device(pdev)) { - err = -ENODEV; - goto out_no_pci; - } - - pci_set_master(pdev); - - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); - if (err) { - err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); - if (!err) - err = pci_set_consistent_dma_mask(pdev, - DMA_BIT_MASK(32)); - /* both attempts failed: */ - if (err) { - dev_printk(KERN_ERR, bus->dev, - "No suitable DMA available.\n"); - goto out_pci_disable_device; - } - } - - err = pci_request_regions(pdev, DRV_NAME); - if (err) { - dev_printk(KERN_ERR, bus->dev, "pci_request_regions failed"); - goto out_pci_disable_device; - } - - pci_bus->hw_base = pci_iomap(pdev, 0, 0); - if (!pci_bus->hw_base) { - dev_printk(KERN_ERR, bus->dev, "pci_iomap failed"); - err = -ENODEV; - goto out_pci_release_regions; - } - - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_len = 0x%08llx\n", - (unsigned long long) pci_resource_len(pdev, 0)); - dev_printk(KERN_INFO, &pdev->dev, - "pci_resource_base = %p\n", pci_bus->hw_base); - - dev_printk(KERN_INFO, &pdev->dev, - "HW Revision ID = 0x%X\n", pdev->revision); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); - - err = pci_enable_msi(pdev); - if (err) - dev_printk(KERN_ERR, &pdev->dev, - "pci_enable_msi failed(0X%x)", err); - - /* TODO: Move this away, not needed if not MSI */ - /* enable rfkill interrupt: hw bug w/a */ - pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); - if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { - pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; - pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); - } - bus->dev = &pdev->dev; - bus->irq = pdev->irq; bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { err = -ENOMEM; - goto out_disable_msi; + goto out_free_bus; } err = iwl_probe(bus, &trans_ops_idi, cfg); @@ -474,26 +405,20 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) trans(bus) = iwl_trans_pcie_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { err = -ENOMEM; - goto out_disable_msi; + goto out_free_bus; } err = iwl_probe(bus, &trans_ops_pcie, cfg); #endif if (err) goto out_free_trans; + return 0; out_free_trans: iwl_trans_free(trans(bus)); -out_disable_msi: - pci_disable_msi(pdev); - pci_iounmap(pdev, pci_bus->hw_base); -out_pci_release_regions: pci_set_drvdata(pdev, NULL); - pci_release_regions(pdev); -out_pci_disable_device: - pci_disable_device(pdev); -out_no_pci: +out_free_bus: kfree(bus->shrd); kfree(bus); return err; @@ -502,18 +427,12 @@ out_no_pci: static void __devexit iwl_pci_remove(struct pci_dev *pdev) { struct iwl_bus *bus = pci_get_drvdata(pdev); - struct iwl_pci_bus *pci_bus = IWL_BUS_GET_PCI_BUS(bus); - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); struct iwl_shared *shrd = bus->shrd; iwl_remove(shrd->priv); iwl_trans_free(shrd->trans); - pci_disable_msi(pci_dev); - pci_iounmap(pci_dev, pci_bus->hw_base); - pci_release_regions(pci_dev); - pci_disable_device(pci_dev); - pci_set_drvdata(pci_dev, NULL); + pci_set_drvdata(pdev, NULL); kfree(bus->shrd); kfree(bus); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 0f73778b73f..47d27bdf2df 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -211,6 +211,8 @@ struct iwl_tx_queue { * @txq_ctx_active_msk: what queue is active * queue_stopped: tracks what queue is stopped * queue_stop_count: tracks what SW queue is stopped + * @pci_dev: basic pci-network driver stuff + * @hw_base: pci hardware address support */ struct iwl_trans_pcie { struct iwl_rx_queue rxq; @@ -241,6 +243,10 @@ struct iwl_trans_pcie { #define IWL_MAX_HW_QUEUES 32 unsigned long queue_stopped[BITS_TO_LONGS(IWL_MAX_HW_QUEUES)]; atomic_t queue_stop_count[4]; + + /* PCI bus related data */ + struct pci_dev *pci_dev; + void __iomem *hw_base; }; #define IWL_TRANS_GET_PCIE_TRANS(_iwl_trans) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index f0d8cccbcb1..5d0cfe03340 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -60,6 +60,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *****************************************************************************/ +#include +#include #include #include #include @@ -1042,7 +1044,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) spin_unlock_irqrestore(&trans->shrd->lock, flags); /* wait to make sure we flush pending tasklet*/ - synchronize_irq(bus(trans)->irq); + synchronize_irq(trans->irq); tasklet_kill(&trans_pcie->irq_tasklet); /* stop and reset the on-board processor */ @@ -1246,10 +1248,10 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) iwl_alloc_isr_ict(trans); - err = request_irq(bus(trans)->irq, iwl_isr_ict, IRQF_SHARED, + err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, DRV_NAME, trans); if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", bus(trans)->irq); + IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); iwl_free_isr_ict(trans); return err; } @@ -1299,13 +1301,22 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, static void iwl_trans_pcie_free(struct iwl_trans *trans) { + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + iwl_calib_free_results(trans); iwl_trans_pcie_tx_free(trans); #ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); #endif - free_irq(bus(trans)->irq, trans); + free_irq(trans->irq, trans); iwl_free_isr_ict(trans); + + pci_disable_msi(trans_pcie->pci_dev); + pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); + pci_release_regions(trans_pcie->pci_dev); + pci_disable_device(trans_pcie->pci_dev); + trans->shrd->trans = NULL; kfree(trans); } @@ -1374,30 +1385,6 @@ static void iwl_trans_pcie_wake_any_queue(struct iwl_trans *trans, } } -const struct iwl_trans_ops trans_ops_pcie; - -struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, - struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct iwl_trans_pcie *trans_pcie; - struct iwl_trans *iwl_trans = kzalloc(sizeof(struct iwl_trans) + - sizeof(struct iwl_trans_pcie), - GFP_KERNEL); - - if (WARN_ON(!iwl_trans)) - return NULL; - - trans_pcie = IWL_TRANS_GET_PCIE_TRANS(iwl_trans); - - iwl_trans->ops = &trans_ops_pcie; - iwl_trans->shrd = shrd; - trans_pcie->trans = iwl_trans; - spin_lock_init(&iwl_trans->hcmd_lock); - - return iwl_trans; -} - static void iwl_trans_pcie_stop_queue(struct iwl_trans *trans, int txq_id, const char *msg) { @@ -1949,3 +1936,129 @@ const struct iwl_trans_ops trans_ops_pcie = { .resume = iwl_trans_pcie_resume, #endif }; + +/* TODO: remove this hack - will be possible when all the io{write/read} ops + * will be done through the transport + */ +struct iwl_pci_bus { + /* basic pci-network driver stuff */ + struct pci_dev *pci_dev; + + /* pci hardware address support */ + void __iomem *hw_base; +}; + +#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ + ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) + +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + +struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, + struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + struct iwl_pci_bus *iwl_pci_bus = IWL_BUS_GET_PCI_BUS(shrd->bus); + struct iwl_trans_pcie *trans_pcie; + struct iwl_trans *trans; + u16 pci_cmd; + int err; + + trans = kzalloc(sizeof(struct iwl_trans) + + sizeof(struct iwl_trans_pcie), GFP_KERNEL); + + if (WARN_ON(!trans)) + return NULL; + + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); + + trans->ops = &trans_ops_pcie; + trans->shrd = shrd; + trans_pcie->trans = trans; + spin_lock_init(&trans->hcmd_lock); + + /* W/A - seems to solve weird behavior. We need to remove this if we + * don't want to stay in L1 all the time. This wastes a lot of power */ + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 | + PCIE_LINK_STATE_CLKPM); + + if (pci_enable_device(pdev)) { + err = -ENODEV; + goto out_no_pci; + } + + pci_set_master(pdev); + + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36)); + if (err) { + err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); + if (!err) + err = pci_set_consistent_dma_mask(pdev, + DMA_BIT_MASK(32)); + /* both attempts failed: */ + if (err) { + dev_printk(KERN_ERR, &pdev->dev, + "No suitable DMA available.\n"); + goto out_pci_disable_device; + } + } + + err = pci_request_regions(pdev, DRV_NAME); + if (err) { + dev_printk(KERN_ERR, &pdev->dev, "pci_request_regions failed"); + goto out_pci_disable_device; + } + + trans_pcie->hw_base = pci_iomap(pdev, 0, 0); + if (!trans_pcie->hw_base) { + dev_printk(KERN_ERR, &pdev->dev, "pci_iomap failed"); + err = -ENODEV; + goto out_pci_release_regions; + } + + /* TODO: remove this hack */ + iwl_pci_bus->hw_base = trans_pcie->hw_base; + + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_len = 0x%08llx\n", + (unsigned long long) pci_resource_len(pdev, 0)); + dev_printk(KERN_INFO, &pdev->dev, + "pci_resource_base = %p\n", trans_pcie->hw_base); + + dev_printk(KERN_INFO, &pdev->dev, + "HW Revision ID = 0x%X\n", pdev->revision); + + /* We disable the RETRY_TIMEOUT register (0x41) to keep + * PCI Tx retries from interfering with C3 CPU state */ + pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); + + err = pci_enable_msi(pdev); + if (err) + dev_printk(KERN_ERR, &pdev->dev, + "pci_enable_msi failed(0X%x)", err); + + trans->dev = &pdev->dev; + trans->irq = pdev->irq; + trans_pcie->pci_dev = pdev; + + /* TODO: Move this away, not needed if not MSI */ + /* enable rfkill interrupt: hw bug w/a */ + pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd); + if (pci_cmd & PCI_COMMAND_INTX_DISABLE) { + pci_cmd &= ~PCI_COMMAND_INTX_DISABLE; + pci_write_config_word(pdev, PCI_COMMAND, pci_cmd); + } + + return trans; + +out_pci_release_regions: + pci_release_regions(pdev); +out_pci_disable_device: + pci_disable_device(pdev); +out_no_pci: + kfree(trans); + return NULL; +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index b1a7af26c57..9a807619486 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -228,6 +228,8 @@ struct iwl_calib_result { * @ops - pointer to iwl_trans_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @hcmd_lock: protects HCMD + * @dev - pointer to struct device * that represents the device + * @irq - the irq number for the device * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image * @ucode_init: init ucode image @@ -240,6 +242,9 @@ struct iwl_trans { struct iwl_shared *shrd; spinlock_t hcmd_lock; + struct device *dev; + unsigned int irq; + u8 ucode_write_complete; /* the image write is complete */ struct fw_img ucode_rt; struct fw_img ucode_init; -- cgit v1.2.3-70-g09d2 From 0390549571cb614ac5cd3327b63f95155a75c673 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 13:48:07 +0200 Subject: iwlwifi: the read / write register ops move to transport Most of the accesses to the registers are done from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 21 --------------- drivers/net/wireless/iwlwifi/iwl-io.h | 11 +++++--- drivers/net/wireless/iwlwifi/iwl-pci.c | 22 ---------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 37 ++++++++++++++------------- drivers/net/wireless/iwlwifi/iwl-trans.h | 21 +++++++++++++++ 5 files changed, 48 insertions(+), 64 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 37ed7b60aaf..981f7b79d39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -124,18 +124,12 @@ struct iwl_bus; * @apm_config: will be called during the config of the APM * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 - * @write8: write a byte to register at offset ofs - * @write32: write a dword to register at offset ofs - * @wread32: read a dword at register at offset ofs */ struct iwl_bus_ops { bool (*get_pm_support)(struct iwl_bus *bus); void (*apm_config)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); - void (*write8)(struct iwl_bus *bus, u32 ofs, u8 val); - void (*write32)(struct iwl_bus *bus, u32 ofs, u32 val); - u32 (*read32)(struct iwl_bus *bus, u32 ofs); }; /** @@ -183,21 +177,6 @@ static inline u32 bus_get_hw_id(struct iwl_bus *bus) return bus->ops->get_hw_id(bus); } -static inline void bus_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - bus->ops->write8(bus, ofs, val); -} - -static inline void bus_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - bus->ops->write32(bus, ofs, val); -} - -static inline u32 bus_read32(struct iwl_bus *bus, u32 ofs) -{ - return bus->ops->read32(bus, ofs); -} - /***************************************************** * Bus layer registration functions ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index 427d065435c..b8e00cd7b1f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -31,23 +31,28 @@ #include "iwl-devtrace.h" #include "iwl-shared.h" +/* TODO: remove when not needed any more */ #include "iwl-bus.h" +#include "iwl-trans.h" static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) { + /* TODO: get trans instead of bus */ trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); - bus_write8(bus, ofs, val); + iwl_trans_write8(trans(bus), ofs, val); } static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) { + /* TODO: get trans instead of bus */ trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); - bus_write32(bus, ofs, val); + iwl_trans_write32(trans(bus), ofs, val); } static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) { - u32 val = bus_read32(bus, ofs); + /* TODO: get trans instead of bus */ + u32 val = iwl_trans_read32(trans(bus), ofs); trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); return val; } diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 631b67ca2b6..ab462337d7a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -79,9 +79,6 @@ struct iwl_pci_bus { /* basic pci-network driver stuff */ struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; }; #define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ @@ -151,30 +148,11 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) return (pci_dev->device << 16) + pci_dev->subsystem_device; } -static void iwl_pci_write8(struct iwl_bus *bus, u32 ofs, u8 val) -{ - iowrite8(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static void iwl_pci_write32(struct iwl_bus *bus, u32 ofs, u32 val) -{ - iowrite32(val, IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); -} - -static u32 iwl_pci_read32(struct iwl_bus *bus, u32 ofs) -{ - u32 val = ioread32(IWL_BUS_GET_PCI_BUS(bus)->hw_base + ofs); - return val; -} - static const struct iwl_bus_ops bus_ops_pci = { .get_pm_support = iwl_pci_is_pm_supported, .apm_config = iwl_pci_apm_config, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, - .write8 = iwl_pci_write8, - .write32 = iwl_pci_write32, - .read32 = iwl_pci_read32, }; #define IWL_PCI_DEVICE(dev, subdev, cfg) \ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 5d0cfe03340..80f531844f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1299,6 +1299,22 @@ static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, return 0; } +static void iwl_trans_pcie_write8(struct iwl_trans *trans, u32 ofs, u8 val) +{ + iowrite8(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); +} + +static void iwl_trans_pcie_write32(struct iwl_trans *trans, u32 ofs, u32 val) +{ + iowrite32(val, IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); +} + +static u32 iwl_trans_pcie_read32(struct iwl_trans *trans, u32 ofs) +{ + u32 val = ioread32(IWL_TRANS_GET_PCIE_TRANS(trans)->hw_base + ofs); + return val; +} + static void iwl_trans_pcie_free(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -1935,22 +1951,11 @@ const struct iwl_trans_ops trans_ops_pcie = { .suspend = iwl_trans_pcie_suspend, .resume = iwl_trans_pcie_resume, #endif + .write8 = iwl_trans_pcie_write8, + .write32 = iwl_trans_pcie_write32, + .read32 = iwl_trans_pcie_read32, }; -/* TODO: remove this hack - will be possible when all the io{write/read} ops - * will be done through the transport - */ -struct iwl_pci_bus { - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; - - /* pci hardware address support */ - void __iomem *hw_base; -}; - -#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ - ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) - /* PCI registers */ #define PCI_CFG_RETRY_TIMEOUT 0x041 @@ -1958,7 +1963,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, struct pci_dev *pdev, const struct pci_device_id *ent) { - struct iwl_pci_bus *iwl_pci_bus = IWL_BUS_GET_PCI_BUS(shrd->bus); struct iwl_trans_pcie *trans_pcie; struct iwl_trans *trans; u16 pci_cmd; @@ -2018,9 +2022,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, goto out_pci_release_regions; } - /* TODO: remove this hack */ - iwl_pci_bus->hw_base = trans_pcie->hw_base; - dev_printk(KERN_INFO, &pdev->dev, "pci_resource_len = 0x%08llx\n", (unsigned long long) pci_resource_len(pdev, 0)); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 9a807619486..0a3727dac6a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -158,6 +158,9 @@ struct iwl_host_cmd { * automatically deleted. * @suspend: stop the device unless WoWLAN is configured * @resume: resume activity of the device + * @write8: write a u8 to a register at offset ofs from the BAR + * @write32: write a u32 to a register at offset ofs from the BAR + * @read32: read a u32 register at offset ofs from the BAR */ struct iwl_trans_ops { @@ -201,6 +204,9 @@ struct iwl_trans_ops { int (*suspend)(struct iwl_trans *trans); int (*resume)(struct iwl_trans *trans); #endif + void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); + void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); + u32 (*read32)(struct iwl_trans *trans, u32 ofs); }; /* one for each uCode image (inst/data, boot/init/runtime) */ @@ -382,6 +388,21 @@ static inline int iwl_trans_resume(struct iwl_trans *trans) } #endif +static inline void iwl_trans_write8(struct iwl_trans *trans, u32 ofs, u8 val) +{ + trans->ops->write8(trans, ofs, val); +} + +static inline void iwl_trans_write32(struct iwl_trans *trans, u32 ofs, u32 val) +{ + trans->ops->write32(trans, ofs, val); +} + +static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) +{ + return trans->ops->read32(trans, ofs); +} + /***************************************************** * Utils functions ******************************************************/ -- cgit v1.2.3-70-g09d2 From 1042db2af183b96cdce5972014d85e8bca0634ad Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 16:56:15 +0200 Subject: iwlwifi: give trans to all the read / write functions From now on, the transport layer in charge of providing access to the device. So change all the driver to give a pointer to the transport to all the low level functions that actually access the device. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 4 +- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +- drivers/net/wireless/iwlwifi/iwl-6000.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-rx.c | 8 +- drivers/net/wireless/iwlwifi/iwl-agn-tt.c | 14 +- drivers/net/wireless/iwlwifi/iwl-agn.c | 42 ++--- drivers/net/wireless/iwlwifi/iwl-bus.h | 3 - drivers/net/wireless/iwlwifi/iwl-core.c | 28 ++-- drivers/net/wireless/iwlwifi/iwl-core.h | 2 +- drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +- drivers/net/wireless/iwlwifi/iwl-eeprom.c | 61 +++---- drivers/net/wireless/iwlwifi/iwl-io.c | 193 +++++++++++----------- drivers/net/wireless/iwlwifi/iwl-io.h | 63 ++++--- drivers/net/wireless/iwlwifi/iwl-led.c | 9 +- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 27 +-- drivers/net/wireless/iwlwifi/iwl-pci.c | 4 +- drivers/net/wireless/iwlwifi/iwl-testmode.c | 16 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 8 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 82 ++++----- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 46 +++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 144 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 + drivers/net/wireless/iwlwifi/iwl-ucode.c | 37 ++--- 24 files changed, 405 insertions(+), 406 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index cc04cce1156..f7a555b9d24 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -84,13 +84,13 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv) static void iwl1000_nic_config(struct iwl_priv *priv) { /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); /* Setting digital SVR for 1000 card to 1.32V */ /* locking is acquired in iwl_set_bits_mask_prph() function */ - iwl_set_bits_mask_prph(bus(priv), APMG_DIGITAL_SVR_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_DIGITAL_SVR_REG, APMG_SVR_DIGITAL_VOLTAGE_1_32, ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK); } diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 00db092d8cd..87600345010 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -87,7 +87,7 @@ static void iwl2000_nic_config(struct iwl_priv *priv) iwl_rf_config(priv); if (cfg(priv)->iq_invert) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_IQ_INVER); } diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 47fd98b3652..5245a1422a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -73,7 +73,7 @@ static void iwl5000_nic_config(struct iwl_priv *priv) * (PCIe power is lost before PERST# is asserted), * causing ME FW to lose ownership and not being able to obtain it back. */ - iwl_set_bits_mask_prph(bus(priv), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans(priv), APMG_PS_CTRL_REG, APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index ab62c018fcd..464b8878467 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -82,7 +82,7 @@ static void iwl6050_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); } @@ -90,9 +90,9 @@ static void iwl6150_additional_nic_config(struct iwl_priv *priv) { /* Indicate calibration version to uCode. */ if (iwl_eeprom_calib_version(priv->shrd) >= 6) - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_CALIB_VERSION6); - iwl_set_bit(bus(priv), CSR_GP_DRIVER_REG, + iwl_set_bit(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_6050_1x2); } @@ -104,7 +104,7 @@ static void iwl6000_nic_config(struct iwl_priv *priv) /* no locking required for register write */ if (cfg(priv)->pa_type == IWL_PA_INTERNAL) { /* 2x2 IPA phy type */ - iwl_write32(bus(priv), CSR_GP_DRIVER_REG, + iwl_write32(trans(priv), CSR_GP_DRIVER_REG, CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA); } /* do additional nic configuration if needed */ diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c index f127f913e5a..a14ddab783e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rx.c @@ -628,16 +628,16 @@ static int iwlagn_rx_card_state_notif(struct iwl_priv *priv, if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED | CT_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); if (!(flags & RXON_CARD_DISABLED)) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); - iwl_write_direct32(bus(priv), HBUS_TARG_MBX_C, + iwl_write_direct32(trans(priv), HBUS_TARG_MBX_C, HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); } if (flags & CT_CARD_DISABLED) diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c index 56c6def015a..c728ed75584 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c @@ -178,19 +178,19 @@ static void iwl_tt_check_exit_ct_kill(unsigned long data) if (tt->state == IWL_TI_CT_KILL) { if (priv->thermal_throttle.ct_kill_toggle) { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = false; } else { - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); priv->thermal_throttle.ct_kill_toggle = true; } - iwl_read32(bus(priv), CSR_UCODE_DRV_GP1); - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - if (!iwl_grab_nic_access(bus(priv))) - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + iwl_read32(trans(priv), CSR_UCODE_DRV_GP1); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + if (!iwl_grab_nic_access(trans(priv))) + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); /* Reschedule the ct_kill timer to occur in * CT_KILL_EXIT_DURATION seconds to ensure we get a diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1a4ba9de99b..f79791500a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -328,14 +328,14 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, ptr = base + (4 * sizeof(u32)) + (start_idx * 3 * sizeof(u32)); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(priv)->reg_lock, reg_flags); - if (iwl_grab_nic_access(bus(priv))) { - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + spin_lock_irqsave(&trans(priv)->reg_lock, reg_flags); + if (iwl_grab_nic_access(trans(priv))) { + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); return; } /* Set starting address; reads will auto-increment */ - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, ptr); rmb(); /* @@ -352,19 +352,19 @@ static void iwl_print_cont_event_trace(struct iwl_priv *priv, u32 base, * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); if (mode == 0) { trace_iwlwifi_dev_ucode_cont_event(priv, 0, time, ev); } else { - data = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); + data = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); trace_iwlwifi_dev_ucode_cont_event(priv, time, data, ev); } } /* Allow device to power down */ - iwl_release_nic_access(bus(priv)); - spin_unlock_irqrestore(&bus(priv)->reg_lock, reg_flags); + iwl_release_nic_access(trans(priv)); + spin_unlock_irqrestore(&trans(priv)->reg_lock, reg_flags); } static void iwl_continuous_event_trace(struct iwl_priv *priv) @@ -383,7 +383,7 @@ static void iwl_continuous_event_trace(struct iwl_priv *priv) base = priv->shrd->device_pointers.log_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - iwl_read_targ_mem_words(bus(priv), base, &read, sizeof(read)); + iwl_read_targ_mem_words(trans(priv), base, &read, sizeof(read)); capacity = read.capacity; mode = read.mode; @@ -583,7 +583,7 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) priv->firmware_name); return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - bus(priv)->dev, + trans(priv)->dev, GFP_KERNEL, priv, iwl_ucode_callback); } @@ -1158,7 +1158,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv) int ret = 0; spin_lock_irqsave(&priv->shrd->lock, flags); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); spin_unlock_irqrestore(&priv->shrd->lock, flags); priv->thermal_throttle.ct_kill_toggle = false; @@ -1693,7 +1693,7 @@ static void iwl_uninit_drv(struct iwl_priv *priv) static u32 iwl_hw_detect(struct iwl_priv *priv) { - return iwl_read32(bus(priv), CSR_HW_REV); + return iwl_read32(trans(priv), CSR_HW_REV); } /* Size of one Rx buffer in host DRAM */ @@ -1727,32 +1727,32 @@ static int iwl_set_hw_params(struct iwl_priv *priv) static void iwl_debug_config(struct iwl_priv *priv) { - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUG " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUG " #ifdef CONFIG_IWLWIFI_DEBUG "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEBUGFS " #ifdef CONFIG_IWLWIFI_DEBUGFS "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TRACING " #ifdef CONFIG_IWLWIFI_DEVICE_TRACING "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_DEVICE_TESTMODE " #ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE "enabled\n"); #else "disabled\n"); #endif - dev_printk(KERN_INFO, bus(priv)->dev, "CONFIG_IWLWIFI_P2P " + dev_printk(KERN_INFO, trans(priv)->dev, "CONFIG_IWLWIFI_P2P " #ifdef CONFIG_IWLWIFI_P2P "enabled\n"); #else @@ -1810,7 +1810,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* these spin locks will be used in apm_ops.init and EEPROM access * we should init now */ - spin_lock_init(&bus(priv)->reg_lock); + spin_lock_init(&trans(priv)->reg_lock); spin_lock_init(&priv->shrd->lock); /* @@ -1818,7 +1818,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, * strange state ... like being left stranded by a primary kernel * and this is now the kdump kernel trying to start up */ - iwl_write32(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); /*********************** * 3. Read REV register @@ -1903,7 +1903,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_enable_rfkill_int(priv); /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(priv), + if (iwl_read32(trans(priv), CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); else diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 981f7b79d39..ce1a9cc106e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -142,15 +142,12 @@ struct iwl_bus_ops { * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data - * @reg_lock - protect hw register access */ struct iwl_bus { struct device *dev; const struct iwl_bus_ops *ops; struct iwl_shared *shrd; - spinlock_t reg_lock; - /* pointer to bus specific struct */ /*Ensure that this pointer will always be aligned to sizeof pointer */ char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 7d6eef96454..c9022c5fa81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -888,9 +888,9 @@ static int iwl_apm_stop_master(struct iwl_priv *priv) int ret = 0; /* stop device's busmaster DMA activity */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - ret = iwl_poll_bit(bus(priv), CSR_RESET, + ret = iwl_poll_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_MASTER_DISABLED, CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); if (ret) @@ -911,7 +911,7 @@ void iwl_apm_stop(struct iwl_priv *priv) iwl_apm_stop_master(priv); /* Reset the entire device */ - iwl_set_bit(bus(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); udelay(10); @@ -919,7 +919,8 @@ void iwl_apm_stop(struct iwl_priv *priv) * Clear "initialization complete" bit to move adapter from * D0A* (powered-up Active) --> D0U* (Uninitialized) state. */ - iwl_clear_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + iwl_clear_bit(trans(priv), CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } @@ -939,45 +940,46 @@ int iwl_apm_init(struct iwl_priv *priv) */ /* Disable L0S exit timer (platform NMI Work/Around) */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, + iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); /* * Disable L0s without affecting L1; * don't wait for ICH L0s (ICH bug W/A) */ - iwl_set_bit(bus(priv), CSR_GIO_CHICKEN_BITS, + iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); /* Set FH wait threshold to maximum (HW error during stress W/A) */ - iwl_set_bit(bus(priv), CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); + iwl_set_bit(trans(priv), CSR_DBG_HPET_MEM_REG, + CSR_DBG_HPET_MEM_REG_VAL); /* * Enable HAP INTA (interrupt from management bus) to * wake device's PCI Express link L1a -> L0s */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); bus_apm_config(bus(priv)); /* Configure analog phase-lock-loop before activating to D0A */ if (cfg(priv)->base_params->pll_cfg_val) - iwl_set_bit(bus(priv), CSR_ANA_PLL_CFG, + iwl_set_bit(trans(priv), CSR_ANA_PLL_CFG, cfg(priv)->base_params->pll_cfg_val); /* * Set "initialization complete" bit to move adapter from * D0U* --> D0A* (powered-up active) state. */ - iwl_set_bit(bus(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + iwl_set_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* * Wait for clock stabilization; once stabilized, access to * device-internal resources is supported, e.g. iwl_write_prph() * and accesses to uCode SRAM. */ - ret = iwl_poll_bit(bus(priv), CSR_GP_CNTRL, + ret = iwl_poll_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) { @@ -992,11 +994,11 @@ int iwl_apm_init(struct iwl_priv *priv) * do not disable clocks. This preserves any hardware bits already * set by default in "CLK_CTRL_REG" after reset. */ - iwl_write_prph(bus(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); + iwl_write_prph(trans(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(20); /* Disable L1-Active */ - iwl_set_bits_prph(bus(priv), APMG_PCIDEV_STT_REG, + iwl_set_bits_prph(trans(priv), APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 63f29111da1..e74bfb7bbb2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -300,7 +300,7 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) { IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); - iwl_write32(bus(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); + iwl_write32(trans(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); } extern bool bt_siso_mode; diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c index 978a1d4c6a0..136de6fb3fa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c +++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c @@ -263,7 +263,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, sram = priv->dbgfs_sram_offset & ~0x3; /* read the first u32 from sram */ - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); for (; len; len--) { /* put the address at the start of every line */ @@ -282,7 +282,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file, if (++offset == 4) { sram += 4; offset = 0; - val = iwl_read_targ_mem(bus(priv), sram); + val = iwl_read_targ_mem(trans(priv), sram); } /* put in extra spaces and split lines for human readability */ @@ -2055,7 +2055,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, const size_t bufsz = sizeof(buf); u32 pwrsave_status; - pwrsave_status = iwl_read32(bus(priv), CSR_GP_CNTRL) & + pwrsave_status = iwl_read32(trans(priv), CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK; pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c index ce214e0ab49..d1fd1cdb29c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c @@ -156,16 +156,16 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) for (count = 0; count < EEPROM_SEM_RETRY_LIMIT; count++) { /* Request semaphore */ - iwl_set_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); /* See if we got it */ - ret = iwl_poll_bit(bus, CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM, EEPROM_SEM_TIMEOUT); if (ret >= 0) { - IWL_DEBUG_EEPROM(bus, + IWL_DEBUG_EEPROM(trans(bus), "Acquired semaphore after %d tries.\n", count+1); return ret; @@ -177,14 +177,15 @@ static int iwl_eeprom_acquire_semaphore(struct iwl_bus *bus) static void iwl_eeprom_release_semaphore(struct iwl_bus *bus) { - iwl_clear_bit(bus, CSR_HW_IF_CONFIG_REG, + iwl_clear_bit(trans(bus), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_EEPROM_OWN_SEM); } static int iwl_eeprom_verify_signature(struct iwl_trans *trans) { - u32 gp = iwl_read32(bus(trans), CSR_EEPROM_GP) & CSR_EEPROM_GP_VALID_MSK; + u32 gp = iwl_read32(trans, CSR_EEPROM_GP) & + CSR_EEPROM_GP_VALID_MSK; int ret = 0; IWL_DEBUG_EEPROM(trans, "EEPROM signature=0x%08x\n", gp); @@ -305,13 +306,13 @@ void iwl_eeprom_get_mac(const struct iwl_shared *shrd, u8 *mac) static void iwl_set_otp_access(struct iwl_bus *bus, enum iwl_access_mode mode) { - iwl_read32(bus, CSR_OTP_GP_REG); + iwl_read32(trans(bus), CSR_OTP_GP_REG); if (mode == IWL_OTP_ACCESS_ABSOLUTE) - iwl_clear_bit(bus, CSR_OTP_GP_REG, + iwl_clear_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); else - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_OTP_ACCESS_MODE); } @@ -332,7 +333,7 @@ static int iwl_get_nvm_type(struct iwl_bus *bus, u32 hw_rev) nvm_type = NVM_DEVICE_TYPE_EEPROM; break; default: - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_DEVICE_SELECT) nvm_type = NVM_DEVICE_TYPE_OTP; else @@ -347,22 +348,22 @@ static int iwl_init_otp_access(struct iwl_bus *bus) int ret; /* Enable 40MHz radio clock */ - iwl_write32(bus, CSR_GP_CNTRL, - iwl_read32(bus, CSR_GP_CNTRL) | + iwl_write32(trans(bus), CSR_GP_CNTRL, + iwl_read32(trans(bus), CSR_GP_CNTRL) | CSR_GP_CNTRL_REG_FLAG_INIT_DONE); /* wait for clock to be ready */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans(bus), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); if (ret < 0) IWL_ERR(bus, "Time out access OTP\n"); else { - iwl_set_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_set_bits_prph(trans(bus), APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); udelay(5); - iwl_clear_bits_prph(bus, APMG_PS_CTRL_REG, + iwl_clear_bits_prph(trans(bus), APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_RESET_REQ); /* @@ -370,7 +371,7 @@ static int iwl_init_otp_access(struct iwl_bus *bus) * this is only applicable for HW with OTP shadow RAM */ if (cfg(bus)->base_params->shadow_ram_support) - iwl_set_bit(bus, CSR_DBG_LINK_PWR_MGMT_REG, + iwl_set_bit(trans(bus), CSR_DBG_LINK_PWR_MGMT_REG, CSR_RESET_LINK_PWR_MGMT_DISABLED); } return ret; @@ -382,9 +383,9 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) u32 r; u32 otpgp; - iwl_write32(bus, CSR_EEPROM_REG, + iwl_write32(trans(bus), CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus, CSR_EEPROM_REG, + ret = iwl_poll_bit(trans(bus), CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); @@ -392,13 +393,13 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) IWL_ERR(bus, "Time out reading OTP[%d]\n", addr); return ret; } - r = iwl_read32(bus, CSR_EEPROM_REG); + r = iwl_read32(trans(bus), CSR_EEPROM_REG); /* check for ECC errors: */ - otpgp = iwl_read32(bus, CSR_OTP_GP_REG); + otpgp = iwl_read32(trans(bus), CSR_OTP_GP_REG); if (otpgp & CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK) { /* stop in this case */ /* set the uncorrectable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); IWL_ERR(bus, "Uncorrectable OTP ECC error, abort OTP read\n"); return -EINVAL; @@ -406,7 +407,7 @@ static int iwl_read_otp_word(struct iwl_bus *bus, u16 addr, __le16 *eeprom_data) if (otpgp & CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK) { /* continue in this case */ /* set the correctable OTP ECC bit for acknowledgement */ - iwl_set_bit(bus, CSR_OTP_GP_REG, + iwl_set_bit(trans(bus), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK); IWL_ERR(bus, "Correctable OTP ECC error, continue read\n"); } @@ -656,7 +657,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) { struct iwl_shared *shrd = priv->shrd; __le16 *e; - u32 gp = iwl_read32(bus(priv), CSR_EEPROM_GP); + u32 gp = iwl_read32(trans(priv), CSR_EEPROM_GP); int sz; int ret; u16 addr; @@ -699,11 +700,11 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) ret = -ENOENT; goto done; } - iwl_write32(bus(priv), CSR_EEPROM_GP, - iwl_read32(bus(priv), CSR_EEPROM_GP) & + iwl_write32(trans(priv), CSR_EEPROM_GP, + iwl_read32(trans(priv), CSR_EEPROM_GP) & ~CSR_EEPROM_GP_IF_OWNER_MSK); - iwl_set_bit(bus(priv), CSR_OTP_GP_REG, + iwl_set_bit(trans(priv), CSR_OTP_GP_REG, CSR_OTP_GP_REG_ECC_CORR_STATUS_MSK | CSR_OTP_GP_REG_ECC_UNCORR_STATUS_MSK); /* traversing the linked list if no shadow ram supported */ @@ -728,10 +729,10 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) for (addr = 0; addr < sz; addr += sizeof(u16)) { u32 r; - iwl_write32(bus(priv), CSR_EEPROM_REG, + iwl_write32(trans(priv), CSR_EEPROM_REG, CSR_EEPROM_REG_MSK_ADDR & (addr << 1)); - ret = iwl_poll_bit(bus(priv), CSR_EEPROM_REG, + ret = iwl_poll_bit(trans(priv), CSR_EEPROM_REG, CSR_EEPROM_REG_READ_VALID_MSK, CSR_EEPROM_REG_READ_VALID_MSK, IWL_EEPROM_ACCESS_TIMEOUT); @@ -739,7 +740,7 @@ int iwl_eeprom_init(struct iwl_priv *priv, u32 hw_rev) IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr); goto done; } - r = iwl_read32(bus(priv), CSR_EEPROM_REG); + r = iwl_read32(trans(priv), CSR_EEPROM_REG); e[addr / 2] = cpu_to_le16(r >> 16); } } @@ -1068,7 +1069,7 @@ void iwl_rf_config(struct iwl_priv *priv) /* write radio config values to register */ if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) <= EEPROM_RF_CONFIG_TYPE_MAX) { - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, EEPROM_RF_CFG_TYPE_MSK(radio_cfg) | EEPROM_RF_CFG_STEP_MSK(radio_cfg) | EEPROM_RF_CFG_DASH_MSK(radio_cfg)); @@ -1080,7 +1081,7 @@ void iwl_rf_config(struct iwl_priv *priv) WARN_ON(1); /* set CSR_HW_CONFIG_REG for uCode use */ - iwl_set_bit(bus(priv), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI | CSR_HW_IF_CONFIG_REG_BIT_MAC_SI); } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c index 83fdff38115..e2e3b5c9cf7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.c +++ b/drivers/net/wireless/iwlwifi/iwl-io.c @@ -34,41 +34,41 @@ #define IWL_POLL_INTERVAL 10 /* microseconds */ -static inline void __iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) | mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) | mask); } -static inline void __iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +static inline void __iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { - iwl_write32(bus, reg, iwl_read32(bus, reg) & ~mask); + iwl_write32(trans, reg, iwl_read32(trans, reg) & ~mask); } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_set_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_set_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - __iwl_clear_bit(bus, reg, mask); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + __iwl_clear_bit(trans, reg, mask); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read32(bus, addr) & mask) == (bits & mask)) + if ((iwl_read32(trans, addr) & mask) == (bits & mask)) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -77,14 +77,15 @@ int iwl_poll_bit(struct iwl_bus *bus, u32 addr, return -ETIMEDOUT; } -int iwl_grab_nic_access_silent(struct iwl_bus *bus) +int iwl_grab_nic_access_silent(struct iwl_trans *trans) { int ret; - lockdep_assert_held(&bus->reg_lock); + lockdep_assert_held(&trans->reg_lock); /* this bit wakes up the NIC */ - __iwl_set_bit(bus, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); + __iwl_set_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* * These bits say the device is running, and should keep running for @@ -105,70 +106,70 @@ int iwl_grab_nic_access_silent(struct iwl_bus *bus) * 5000 series and later (including 1000 series) have non-volatile SRAM, * and do not save/restore SRAM when power cycling. */ - ret = iwl_poll_bit(bus, CSR_GP_CNTRL, + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN, (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY | CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000); if (ret < 0) { - iwl_write32(bus, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI); return -EIO; } return 0; } -int iwl_grab_nic_access(struct iwl_bus *bus) +int iwl_grab_nic_access(struct iwl_trans *trans) { - int ret = iwl_grab_nic_access_silent(bus); + int ret = iwl_grab_nic_access_silent(trans); if (ret) { - u32 val = iwl_read32(bus, CSR_GP_CNTRL); - IWL_ERR(bus, + u32 val = iwl_read32(trans, CSR_GP_CNTRL); + IWL_ERR(trans, "MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val); } return ret; } -void iwl_release_nic_access(struct iwl_bus *bus) +void iwl_release_nic_access(struct iwl_trans *trans) { - lockdep_assert_held(&bus->reg_lock); - __iwl_clear_bit(bus, CSR_GP_CNTRL, + lockdep_assert_held(&trans->reg_lock); + __iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg) +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg) { u32 value; unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - value = iwl_read32(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + value = iwl_read32(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return value; } -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value) +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, reg, value); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + iwl_write32(trans, reg, value); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout) { int t = 0; do { - if ((iwl_read_direct32(bus, addr) & mask) == mask) + if ((iwl_read_direct32(trans, addr) & mask) == mask) return t; udelay(IWL_POLL_INTERVAL); t += IWL_POLL_INTERVAL; @@ -177,135 +178,135 @@ int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, return -ETIMEDOUT; } -static inline u32 __iwl_read_prph(struct iwl_bus *bus, u32 reg) +static inline u32 __iwl_read_prph(struct iwl_trans *trans, u32 reg) { - iwl_write32(bus, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); + iwl_write32(trans, HBUS_TARG_PRPH_RADDR, reg | (3 << 24)); rmb(); - return iwl_read32(bus, HBUS_TARG_PRPH_RDAT); + return iwl_read32(trans, HBUS_TARG_PRPH_RDAT); } -static inline void __iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +static inline void __iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { - iwl_write32(bus, HBUS_TARG_PRPH_WADDR, + iwl_write32(trans, HBUS_TARG_PRPH_WADDR, ((addr & 0x0000FFFF) | (3 << 24))); wmb(); - iwl_write32(bus, HBUS_TARG_PRPH_WDAT, val); + iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val); } -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg) +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, reg); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); return val; } -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val) +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - __iwl_write_prph(bus, addr, val); - iwl_release_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + __iwl_write_prph(trans, addr, val); + iwl_release_nic_access(trans); } - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, __iwl_read_prph(bus, reg) | mask); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + __iwl_write_prph(trans, reg, __iwl_read_prph(trans, reg) | mask); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask) { unsigned long flags; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - __iwl_write_prph(bus, reg, - (__iwl_read_prph(bus, reg) & mask) | bits); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + __iwl_write_prph(trans, reg, + (__iwl_read_prph(trans, reg) & mask) | bits); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask) +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask) { unsigned long flags; u32 val; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); - val = __iwl_read_prph(bus, reg); - __iwl_write_prph(bus, reg, (val & ~mask)); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); + val = __iwl_read_prph(trans, reg); + __iwl_write_prph(trans, reg, (val & ~mask)); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - iwl_grab_nic_access(bus); + spin_lock_irqsave(&trans->reg_lock, flags); + iwl_grab_nic_access(trans); - iwl_write32(bus, HBUS_TARG_MEM_RADDR, addr); + iwl_write32(trans, HBUS_TARG_MEM_RADDR, addr); rmb(); for (offs = 0; offs < words; offs++) - vals[offs] = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + vals[offs] = iwl_read32(trans, HBUS_TARG_MEM_RDAT); - iwl_release_nic_access(bus); - spin_unlock_irqrestore(&bus->reg_lock, flags); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, flags); } -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr) +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr) { u32 value; - _iwl_read_targ_mem_words(bus, addr, &value, 1); + _iwl_read_targ_mem_words(trans, addr, &value, 1); return value; } -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words) { unsigned long flags; int offs, result = 0; u32 *vals = buf; - spin_lock_irqsave(&bus->reg_lock, flags); - if (!iwl_grab_nic_access(bus)) { - iwl_write32(bus, HBUS_TARG_MEM_WADDR, addr); + spin_lock_irqsave(&trans->reg_lock, flags); + if (!iwl_grab_nic_access(trans)) { + iwl_write32(trans, HBUS_TARG_MEM_WADDR, addr); wmb(); for (offs = 0; offs < words; offs++) - iwl_write32(bus, HBUS_TARG_MEM_WDAT, vals[offs]); - iwl_release_nic_access(bus); + iwl_write32(trans, HBUS_TARG_MEM_WDAT, vals[offs]); + iwl_release_nic_access(trans); } else result = -EBUSY; - spin_unlock_irqrestore(&bus->reg_lock, flags); + spin_unlock_irqrestore(&trans->reg_lock, flags); return result; } -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val) +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val) { - return _iwl_write_targ_mem_words(bus, addr, &val, 1); + return _iwl_write_targ_mem_words(trans, addr, &val, 1); } diff --git a/drivers/net/wireless/iwlwifi/iwl-io.h b/drivers/net/wireless/iwlwifi/iwl-io.h index b8e00cd7b1f..782486fc2f8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-io.h +++ b/drivers/net/wireless/iwlwifi/iwl-io.h @@ -31,68 +31,63 @@ #include "iwl-devtrace.h" #include "iwl-shared.h" -/* TODO: remove when not needed any more */ -#include "iwl-bus.h" #include "iwl-trans.h" -static inline void iwl_write8(struct iwl_bus *bus, u32 ofs, u8 val) +static inline void iwl_write8(struct iwl_trans *trans, u32 ofs, u8 val) { - /* TODO: get trans instead of bus */ - trace_iwlwifi_dev_iowrite8(priv(bus), ofs, val); - iwl_trans_write8(trans(bus), ofs, val); + trace_iwlwifi_dev_iowrite8(priv(trans), ofs, val); + iwl_trans_write8(trans, ofs, val); } -static inline void iwl_write32(struct iwl_bus *bus, u32 ofs, u32 val) +static inline void iwl_write32(struct iwl_trans *trans, u32 ofs, u32 val) { - /* TODO: get trans instead of bus */ - trace_iwlwifi_dev_iowrite32(priv(bus), ofs, val); - iwl_trans_write32(trans(bus), ofs, val); + trace_iwlwifi_dev_iowrite32(priv(trans), ofs, val); + iwl_trans_write32(trans, ofs, val); } -static inline u32 iwl_read32(struct iwl_bus *bus, u32 ofs) +static inline u32 iwl_read32(struct iwl_trans *trans, u32 ofs) { - /* TODO: get trans instead of bus */ - u32 val = iwl_trans_read32(trans(bus), ofs); - trace_iwlwifi_dev_ioread32(priv(bus), ofs, val); + u32 val = iwl_trans_read32(trans, ofs); + trace_iwlwifi_dev_ioread32(priv(trans), ofs, val); return val; } -void iwl_set_bit(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_clear_bit(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_set_bit(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_clear_bit(struct iwl_trans *trans, u32 reg, u32 mask); -int iwl_poll_bit(struct iwl_bus *bus, u32 addr, +int iwl_poll_bit(struct iwl_trans *trans, u32 addr, u32 bits, u32 mask, int timeout); -int iwl_poll_direct_bit(struct iwl_bus *bus, u32 addr, u32 mask, +int iwl_poll_direct_bit(struct iwl_trans *trans, u32 addr, u32 mask, int timeout); -int iwl_grab_nic_access_silent(struct iwl_bus *bus); -int iwl_grab_nic_access(struct iwl_bus *bus); -void iwl_release_nic_access(struct iwl_bus *bus); +int iwl_grab_nic_access_silent(struct iwl_trans *trans); +int iwl_grab_nic_access(struct iwl_trans *trans); +void iwl_release_nic_access(struct iwl_trans *trans); -u32 iwl_read_direct32(struct iwl_bus *bus, u32 reg); -void iwl_write_direct32(struct iwl_bus *bus, u32 reg, u32 value); +u32 iwl_read_direct32(struct iwl_trans *trans, u32 reg); +void iwl_write_direct32(struct iwl_trans *trans, u32 reg, u32 value); -u32 iwl_read_prph(struct iwl_bus *bus, u32 reg); -void iwl_write_prph(struct iwl_bus *bus, u32 addr, u32 val); -void iwl_set_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); -void iwl_set_bits_mask_prph(struct iwl_bus *bus, u32 reg, +u32 iwl_read_prph(struct iwl_trans *trans, u32 reg); +void iwl_write_prph(struct iwl_trans *trans, u32 addr, u32 val); +void iwl_set_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); +void iwl_set_bits_mask_prph(struct iwl_trans *trans, u32 reg, u32 bits, u32 mask); -void iwl_clear_bits_prph(struct iwl_bus *bus, u32 reg, u32 mask); +void iwl_clear_bits_prph(struct iwl_trans *trans, u32 reg, u32 mask); -void _iwl_read_targ_mem_words(struct iwl_bus *bus, u32 addr, +void _iwl_read_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -#define iwl_read_targ_mem_words(bus, addr, buf, bufsize) \ +#define iwl_read_targ_mem_words(trans, addr, buf, bufsize) \ do { \ BUILD_BUG_ON((bufsize) % sizeof(u32)); \ - _iwl_read_targ_mem_words(bus, addr, buf, \ + _iwl_read_targ_mem_words(trans, addr, buf, \ (bufsize) / sizeof(u32));\ } while (0) -int _iwl_write_targ_mem_words(struct iwl_bus *bus, u32 addr, +int _iwl_write_targ_mem_words(struct iwl_trans *trans, u32 addr, void *buf, int words); -u32 iwl_read_targ_mem(struct iwl_bus *bus, u32 addr); -int iwl_write_targ_mem(struct iwl_bus *bus, u32 addr, u32 val); +u32 iwl_read_targ_mem(struct iwl_trans *trans, u32 addr); +int iwl_write_targ_mem(struct iwl_trans *trans, u32 addr, u32 val); #endif diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c index 8761438f153..5c7741f07aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-led.c +++ b/drivers/net/wireless/iwlwifi/iwl-led.c @@ -71,7 +71,7 @@ static const struct ieee80211_tpt_blink iwl_blink[] = { /* Set led register off */ void iwlagn_led_enable(struct iwl_priv *priv) { - iwl_write32(bus(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); + iwl_write32(trans(priv), CSR_LED_REG, CSR_LED_REG_TRUN_ON); } /* @@ -107,9 +107,10 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd) }; u32 reg; - reg = iwl_read32(bus(priv), CSR_LED_REG); + reg = iwl_read32(trans(priv), CSR_LED_REG); if (reg != (reg & CSR_LED_BSM_CTRL_MSK)) - iwl_write32(bus(priv), CSR_LED_REG, reg & CSR_LED_BSM_CTRL_MSK); + iwl_write32(trans(priv), CSR_LED_REG, + reg & CSR_LED_BSM_CTRL_MSK); return iwl_trans_send_cmd(trans(priv), &cmd); } @@ -206,7 +207,7 @@ void iwl_leds_init(struct iwl_priv *priv) break; } - ret = led_classdev_register(bus(priv)->dev, &priv->led); + ret = led_classdev_register(trans(priv)->dev, &priv->led); if (ret) { kfree(priv->led.name); return; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 965d0475aff..b911837b04f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -196,7 +196,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, WIPHY_FLAG_IBSS_RSN; if (trans(priv)->ucode_wowlan.code.len && - device_can_wakeup(bus(priv)->dev)) { + device_can_wakeup(trans(priv)->dev)) { hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT | WIPHY_WOWLAN_EAP_IDENTITY_REQ | @@ -347,7 +347,7 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) /* User space software may expect getting rfkill changes * even if interface is down */ - iwl_write32(bus(priv), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans(priv), CSR_INT, 0xFFFFFFFF); iwl_enable_rfkill_int(priv); IWL_DEBUG_MAC80211(priv, "leave\n"); @@ -405,10 +405,10 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw, if (ret) goto error; - device_set_wakeup_enable(bus(priv)->dev, true); + device_set_wakeup_enable(trans(priv)->dev, true); /* Now let the ucode operate on its own */ - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_SET, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_SET, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); goto out; @@ -436,19 +436,19 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) IWL_DEBUG_MAC80211(priv, "enter\n"); mutex_lock(&priv->shrd->mutex); - iwl_write32(bus(priv), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans(priv), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_D3_CFG_COMPLETE); base = priv->shrd->device_pointers.error_event_table; if (iwlagn_hw_valid_rtc_data_addr(base)) { - spin_lock_irqsave(&bus(priv)->reg_lock, flags); - ret = iwl_grab_nic_access_silent(bus(priv)); + spin_lock_irqsave(&trans(priv)->reg_lock, flags); + ret = iwl_grab_nic_access_silent(trans(priv)); if (ret == 0) { - iwl_write32(bus(priv), HBUS_TARG_MEM_RADDR, base); - status = iwl_read32(bus(priv), HBUS_TARG_MEM_RDAT); - iwl_release_nic_access(bus(priv)); + iwl_write32(trans(priv), HBUS_TARG_MEM_RADDR, base); + status = iwl_read32(trans(priv), HBUS_TARG_MEM_RDAT); + iwl_release_nic_access(trans(priv)); } - spin_unlock_irqrestore(&bus(priv)->reg_lock, flags); + spin_unlock_irqrestore(&trans(priv)->reg_lock, flags); #ifdef CONFIG_IWLWIFI_DEBUGFS if (ret == 0) { @@ -460,7 +460,8 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) if (priv->wowlan_sram) _iwl_read_targ_mem_words( - bus(priv), 0x800000, priv->wowlan_sram, + trans(priv), 0x800000, + priv->wowlan_sram, trans->ucode_wowlan.data.len / 4); } #endif @@ -471,7 +472,7 @@ static int iwlagn_mac_resume(struct ieee80211_hw *hw) priv->shrd->wowlan = false; - device_set_wakeup_enable(bus(priv)->dev, false); + device_set_wakeup_enable(trans(priv)->dev, false); iwlagn_prepare_restart(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index ab462337d7a..7bab8192848 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -121,12 +121,12 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == PCI_CFG_LINK_CTRL_VAL_L1_EN) { /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(bus, CSR_GIO_REG, + iwl_set_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(bus, CSR_GIO_REG, + iwl_clear_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index a56a77b8f92..922d841faba 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -208,7 +208,7 @@ static void iwl_trace_cleanup(struct iwl_priv *priv) if (priv->testmode_trace.trace_enabled) { if (priv->testmode_trace.cpu_addr && priv->testmode_trace.dma_addr) - dma_free_coherent(bus(priv)->dev, + dma_free_coherent(trans(priv)->dev, priv->testmode_trace.total_size, priv->testmode_trace.cpu_addr, priv->testmode_trace.dma_addr); @@ -302,7 +302,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: - val32 = iwl_read_direct32(bus(priv), ofs); + val32 = iwl_read_direct32(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -324,7 +324,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_direct32(bus(priv), ofs, val32); + iwl_write_direct32(trans(priv), ofs, val32); } break; case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8: @@ -334,11 +334,11 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]); IWL_INFO(priv, "8bit value to write 0x%x\n", val8); - iwl_write8(bus(priv), ofs, val8); + iwl_write8(trans(priv), ofs, val8); } break; case IWL_TM_CMD_APP2DEV_INDIRECT_REG_READ32: - val32 = iwl_read_prph(bus(priv), ofs); + val32 = iwl_read_prph(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); @@ -360,7 +360,7 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) } else { val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]); IWL_INFO(priv, "32bit value to write 0x%x\n", val32); - iwl_write_prph(bus(priv), ofs, val32); + iwl_write_prph(trans(priv), ofs, val32); } break; default: @@ -615,7 +615,7 @@ static int iwl_testmode_trace(struct ieee80211_hw *hw, struct nlattr **tb) struct iwl_priv *priv = hw->priv; struct sk_buff *skb; int status = 0; - struct device *dev = bus(priv)->dev; + struct device *dev = trans(priv)->dev; switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { case IWL_TM_CMD_APP2DEV_BEGIN_TRACE: @@ -814,7 +814,7 @@ static int iwl_testmode_sram(struct ieee80211_hw *hw, struct nlattr **tb) IWL_ERR(priv, "Error allocating memory\n"); return -ENOMEM; } - _iwl_read_targ_mem_words(bus(priv), ofs, + _iwl_read_targ_mem_words(trans(priv), ofs, priv->testmode_sram.buff_addr, priv->testmode_sram.buff_size / 4); priv->testmode_sram.num_chunks = diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 47d27bdf2df..555175ff4f9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -317,12 +317,12 @@ static inline void iwl_disable_interrupts(struct iwl_trans *trans) clear_bit(STATUS_INT_ENABLED, &trans->shrd->status); /* disable interrupts from uCode/NIC to host */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* acknowledge/clear/reset any interrupts still pending * from uCode or flow handler (Rx/Tx DMA) */ - iwl_write32(bus(trans), CSR_INT, 0xffffffff); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, 0xffffffff); + iwl_write32(trans, CSR_INT, 0xffffffff); + iwl_write32(trans, CSR_FH_INT_STATUS, 0xffffffff); IWL_DEBUG_ISR(trans, "Disabled interrupts\n"); } @@ -333,7 +333,7 @@ static inline void iwl_enable_interrupts(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "Enabling interrupts\n"); set_bit(STATUS_INT_ENABLED, &trans->shrd->status); - iwl_write32(bus(trans), CSR_INT_MASK, trans_pcie->inta_mask); + iwl_write32(trans, CSR_INT_MASK, trans_pcie->inta_mask); } /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index b94c95370b7..ebea2435dac 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -144,30 +144,30 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, /* shadow register enabled */ /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write32(bus(trans), FH_RSCSR_CHNL0_WPTR, q->write_actual); + iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } else { /* If power-saving is in use, make sure device is awake */ if (test_bit(STATUS_POWER_PMI, &trans->shrd->status)) { - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Rx queue requesting wakeup," " GP1 = 0x%x\n", reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); goto exit_unlock; } q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); /* Else device is assumed to be awake */ } else { /* Device expects a multiple of 8 */ q->write_actual = (q->write & ~0x7); - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_WPTR, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); } } @@ -312,7 +312,7 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) BUG_ON(rxb->page); rxb->page = page; /* Get physical address of the RB */ - rxb->page_dma = dma_map_page(bus(trans)->dev, page, 0, + rxb->page_dma = dma_map_page(trans->dev, page, 0, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); /* dma address must be no more than 36 bits */ @@ -418,7 +418,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) rxq->queue[i] = NULL; - dma_unmap_page(bus(trans)->dev, rxb->page_dma, + dma_unmap_page(trans->dev, rxb->page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); pkt = rxb_addr(rxb); @@ -489,7 +489,7 @@ static void iwl_rx_handle(struct iwl_trans *trans) * rx_free list for reuse later. */ spin_lock_irqsave(&rxq->lock, flags); if (rxb->page != NULL) { - rxb->page_dma = dma_map_page(bus(trans)->dev, rxb->page, + rxb->page_dma = dma_map_page(trans->dev, rxb->page, 0, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); @@ -616,7 +616,7 @@ static void iwl_dump_nic_error_log(struct iwl_trans *trans) return; } - iwl_read_targ_mem_words(bus(priv), base, &table, sizeof(table)); + iwl_read_targ_mem_words(trans(priv), base, &table, sizeof(table)); if (ERROR_START_OFFSET <= table.valid * ERROR_ELEM_SIZE) { IWL_ERR(trans, "Start IWL Error Log Dump:\n"); @@ -677,9 +677,9 @@ static void iwl_irq_handle_error(struct iwl_trans *trans) struct iwl_priv *priv = priv(trans); /* W/A for WiFi/WiMAX coex and WiMAX own the RF */ if (cfg(priv)->internal_wimax_coex && - (!(iwl_read_prph(bus(trans), APMG_CLK_CTRL_REG) & + (!(iwl_read_prph(trans, APMG_CLK_CTRL_REG) & APMS_CLK_VAL_MRB_FUNC_MODE) || - (iwl_read_prph(bus(trans), APMG_PS_CTRL_REG) & + (iwl_read_prph(trans, APMG_PS_CTRL_REG) & APMG_PS_CTRL_VAL_RESET_REQ))) { /* * Keep the restart process from trying to send host @@ -745,18 +745,18 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, ptr = base + EVENT_START_OFFSET + (start_idx * event_size); /* Make sure device is powered up for SRAM reads */ - spin_lock_irqsave(&bus(trans)->reg_lock, reg_flags); - iwl_grab_nic_access(bus(trans)); + spin_lock_irqsave(&trans->reg_lock, reg_flags); + iwl_grab_nic_access(trans); /* Set starting address; reads will auto-increment */ - iwl_write32(bus(trans), HBUS_TARG_MEM_RADDR, ptr); + iwl_write32(trans, HBUS_TARG_MEM_RADDR, ptr); rmb(); /* "time" is actually "data" for mode 0 (no timestamp). * place event id # at far right for easier visual parsing. */ for (i = 0; i < num_events; i++) { - ev = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); - time = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + ev = iwl_read32(trans, HBUS_TARG_MEM_RDAT); + time = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (mode == 0) { /* data, ev */ if (bufsz) { @@ -770,7 +770,7 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, time, ev); } } else { - data = iwl_read32(bus(trans), HBUS_TARG_MEM_RDAT); + data = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (bufsz) { pos += scnprintf(*buf + pos, bufsz - pos, "EVT_LOGT:%010u:0x%08x:%04u\n", @@ -785,8 +785,8 @@ static int iwl_print_event_log(struct iwl_trans *trans, u32 start_idx, } /* Allow device to power down */ - iwl_release_nic_access(bus(trans)); - spin_unlock_irqrestore(&bus(trans)->reg_lock, reg_flags); + iwl_release_nic_access(trans); + spin_unlock_irqrestore(&trans->reg_lock, reg_flags); return pos; } @@ -863,10 +863,10 @@ int iwl_dump_nic_event_log(struct iwl_trans *trans, bool full_log, } /* event log header */ - capacity = iwl_read_targ_mem(bus(trans), base); - mode = iwl_read_targ_mem(bus(trans), base + (1 * sizeof(u32))); - num_wraps = iwl_read_targ_mem(bus(trans), base + (2 * sizeof(u32))); - next_entry = iwl_read_targ_mem(bus(trans), base + (3 * sizeof(u32))); + capacity = iwl_read_targ_mem(trans, base); + mode = iwl_read_targ_mem(trans, base + (1 * sizeof(u32))); + num_wraps = iwl_read_targ_mem(trans, base + (2 * sizeof(u32))); + next_entry = iwl_read_targ_mem(trans, base + (3 * sizeof(u32))); if (capacity > logsize) { IWL_ERR(trans, "Log capacity %d is bogus, limit to %d " @@ -962,7 +962,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * hardware bugs here by ACKing all the possible interrupts so that * interrupt coalescing can still be achieved. */ - iwl_write32(bus(trans), CSR_INT, + iwl_write32(trans, CSR_INT, trans_pcie->inta | ~trans_pcie->inta_mask); inta = trans_pcie->inta; @@ -970,7 +970,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(trans->shrd) & IWL_DL_ISR) { /* just for debug */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); + inta_mask = iwl_read32(trans, CSR_INT_MASK); IWL_DEBUG_ISR(trans, "inta 0x%08x, enabled 0x%08x\n ", inta, inta_mask); } @@ -1018,7 +1018,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* HW RF KILL switch toggled */ if (inta & CSR_INT_BIT_RF_KILL) { int hw_rf_kill = 0; - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (!(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rf_kill = 1; @@ -1082,12 +1082,12 @@ void iwl_irq_tasklet(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "Rx interrupt\n"); if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) { handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX); - iwl_write32(bus(trans), CSR_FH_INT_STATUS, + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_RX_MASK); } if (inta & CSR_INT_BIT_RX_PERIODIC) { handled |= CSR_INT_BIT_RX_PERIODIC; - iwl_write32(bus(trans), + iwl_write32(trans, CSR_INT, CSR_INT_BIT_RX_PERIODIC); } /* Sending RX interrupt require many steps to be done in the @@ -1102,7 +1102,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) */ /* Disable periodic interrupt; we use it as just a one-shot. */ - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_DIS); #ifdef CONFIG_IWLWIFI_IDI iwl_amfh_rx_handler(); @@ -1117,7 +1117,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) * to extend the periodic interrupt; one-shot is enough. */ if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) - iwl_write8(bus(trans), CSR_INT_PERIODIC_REG, + iwl_write8(trans, CSR_INT_PERIODIC_REG, CSR_INT_PERIODIC_ENA); isr_stats->rx++; @@ -1125,7 +1125,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) /* This "Tx" DMA channel is used only for loading uCode */ if (inta & CSR_INT_BIT_FH_TX) { - iwl_write32(bus(trans), CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); + iwl_write32(trans, CSR_FH_INT_STATUS, CSR_FH_INT_TX_MASK); IWL_DEBUG_ISR(trans, "uCode load interrupt\n"); isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; @@ -1175,7 +1175,7 @@ void iwl_free_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); if (trans_pcie->ict_tbl) { - dma_free_coherent(bus(trans)->dev, ICT_SIZE, + dma_free_coherent(trans->dev, ICT_SIZE, trans_pcie->ict_tbl, trans_pcie->ict_tbl_dma); trans_pcie->ict_tbl = NULL; @@ -1195,7 +1195,7 @@ int iwl_alloc_isr_ict(struct iwl_trans *trans) IWL_TRANS_GET_PCIE_TRANS(trans); trans_pcie->ict_tbl = - dma_alloc_coherent(bus(trans)->dev, ICT_SIZE, + dma_alloc_coherent(trans->dev, ICT_SIZE, &trans_pcie->ict_tbl_dma, GFP_KERNEL); if (!trans_pcie->ict_tbl) @@ -1246,10 +1246,10 @@ void iwl_reset_ict(struct iwl_trans *trans) IWL_DEBUG_ISR(trans, "CSR_DRAM_INT_TBL_REG =0x%x\n", val); - iwl_write32(bus(trans), CSR_DRAM_INT_TBL_REG, val); + iwl_write32(trans, CSR_DRAM_INT_TBL_REG, val); trans_pcie->use_ict = true; trans_pcie->ict_index = 0; - iwl_write32(bus(trans), CSR_INT, trans_pcie->inta_mask); + iwl_write32(trans, CSR_INT, trans_pcie->inta_mask); iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans->shrd->lock, flags); } @@ -1289,11 +1289,11 @@ static irqreturn_t iwl_isr(int irq, void *data) * back-to-back ISRs and sporadic interrupts from our NIC. * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Discover which interrupts are active/pending */ - inta = iwl_read32(bus(trans), CSR_INT); + inta = iwl_read32(trans, CSR_INT); /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, @@ -1312,7 +1312,7 @@ static irqreturn_t iwl_isr(int irq, void *data) #ifdef CONFIG_IWLWIFI_DEBUG if (iwl_get_debug_level(trans->shrd) & (IWL_DL_ISR)) { - inta_fh = iwl_read32(bus(trans), CSR_FH_INT_STATUS); + inta_fh = iwl_read32(trans, CSR_FH_INT_STATUS); IWL_DEBUG_ISR(trans, "ISR inta 0x%08x, enabled 0x%08x, " "fh 0x%08x\n", inta, inta_mask, inta_fh); } @@ -1378,8 +1378,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data) * If we have something to service, the tasklet will re-enable ints. * If we *don't* have something, we'll re-enable before leaving here. */ - inta_mask = iwl_read32(bus(trans), CSR_INT_MASK); /* just for debug */ - iwl_write32(bus(trans), CSR_INT_MASK, 0x00000000); + inta_mask = iwl_read32(trans, CSR_INT_MASK); /* just for debug */ + iwl_write32(trans, CSR_INT_MASK, 0x00000000); /* Ignore interrupt if there's nothing in NIC to service. diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 30814b55705..5e095ac5076 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -100,7 +100,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) if (hw_params(trans).shadow_reg_enable) { /* shadow register enabled */ - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } else { /* if we're trying to save power */ @@ -108,18 +108,18 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) /* wake up nic if it's powered down ... * uCode will wake up, and interrupt us again, so next * time we'll skip this part. */ - reg = iwl_read32(bus(trans), CSR_UCODE_DRV_GP1); + reg = iwl_read32(trans, CSR_UCODE_DRV_GP1); if (reg & CSR_UCODE_DRV_GP1_BIT_MAC_SLEEP) { IWL_DEBUG_INFO(trans, "Tx queue %d requesting wakeup," " GP1 = 0x%x\n", txq_id, reg); - iwl_set_bit(bus(trans), CSR_GP_CNTRL, + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); return; } - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); /* @@ -128,7 +128,7 @@ void iwl_txq_update_write_ptr(struct iwl_trans *trans, struct iwl_tx_queue *txq) * trying to tx (during RFKILL, we're not trying to tx). */ } else - iwl_write32(bus(trans), HBUS_TARG_WRPTR, + iwl_write32(trans, HBUS_TARG_WRPTR, txq->q.write_ptr | (txq_id << 8)); } txq->need_update = 0; @@ -190,14 +190,14 @@ static void iwlagn_unmap_tfd(struct iwl_trans *trans, struct iwl_cmd_meta *meta, /* Unmap tx_cmd */ if (num_tbs) - dma_unmap_single(bus(trans)->dev, + dma_unmap_single(trans->dev, dma_unmap_addr(meta, mapping), dma_unmap_len(meta, len), DMA_BIDIRECTIONAL); /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) - dma_unmap_single(bus(trans)->dev, iwl_tfd_tb_get_addr(tfd, i), + dma_unmap_single(trans->dev, iwl_tfd_tb_get_addr(tfd, i), iwl_tfd_tb_get_len(tfd, i), dma_dir); } @@ -383,14 +383,14 @@ static int iwlagn_tx_queue_set_q2ratid(struct iwl_trans *trans, u16 ra_tid, tbl_dw_addr = trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(txq_id); - tbl_dw = iwl_read_targ_mem(bus(trans), tbl_dw_addr); + tbl_dw = iwl_read_targ_mem(trans, tbl_dw_addr); if (txq_id & 0x1) tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF); else tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000); - iwl_write_targ_mem(bus(trans), tbl_dw_addr, tbl_dw); + iwl_write_targ_mem(trans, tbl_dw_addr, tbl_dw); return 0; } @@ -399,7 +399,7 @@ static void iwlagn_tx_queue_stop_scheduler(struct iwl_trans *trans, u16 txq_id) { /* Simply stop the queue, but don't change any configuration; * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */ - iwl_write_prph(bus(trans), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (0 << SCD_QUEUE_STTS_REG_POS_ACTIVE)| (1 << SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); @@ -409,9 +409,9 @@ void iwl_trans_set_wr_ptrs(struct iwl_trans *trans, int txq_id, u32 index) { IWL_DEBUG_TX_QUEUES(trans, "Q %d WrPtr: %d", txq_id, index & 0xff); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, + iwl_write_direct32(trans, HBUS_TARG_WRPTR, (index & 0xff) | (txq_id << 8)); - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(txq_id), index); + iwl_write_prph(trans, SCD_QUEUE_RDPTR(txq_id), index); } void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, @@ -423,7 +423,7 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, int active = test_bit(txq_id, &trans_pcie->txq_ctx_active_msk) ? 1 : 0; - iwl_write_prph(bus(trans), SCD_QUEUE_STATUS_BITS(txq_id), + iwl_write_prph(trans, SCD_QUEUE_STATUS_BITS(txq_id), (active << SCD_QUEUE_STTS_REG_POS_ACTIVE) | (tx_fifo_id << SCD_QUEUE_STTS_REG_POS_TXF) | (1 << SCD_QUEUE_STTS_REG_POS_WSL) | @@ -498,10 +498,10 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, iwlagn_tx_queue_set_q2ratid(trans, ra_tid, txq_id); /* Set this queue as a chain-building queue */ - iwl_set_bits_prph(bus(trans), SCD_QUEUECHAIN_SEL, (1<scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32), ((frame_limit << @@ -520,7 +520,7 @@ void iwl_trans_pcie_tx_agg_setup(struct iwl_trans *trans, SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) & SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); - iwl_set_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_set_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */ iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], @@ -584,7 +584,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) iwlagn_tx_queue_stop_scheduler(trans, txq_id); - iwl_clear_bits_prph(bus(trans), SCD_AGGR_SEL, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_AGGR_SEL, (1 << txq_id)); trans_pcie->agg_txq[sta_id][tid] = 0; trans_pcie->txq[txq_id].q.read_ptr = 0; @@ -592,7 +592,7 @@ int iwl_trans_pcie_tx_agg_disable(struct iwl_trans *trans, int sta_id, int tid) /* supposes that ssn_idx is valid (!= 0xFFF) */ iwl_trans_set_wr_ptrs(trans, txq_id, 0); - iwl_clear_bits_prph(bus(trans), SCD_INTERRUPT_MASK, (1 << txq_id)); + iwl_clear_bits_prph(trans, SCD_INTERRUPT_MASK, (1 << txq_id)); iwl_txq_ctx_deactivate(trans_pcie, txq_id); iwl_trans_tx_queue_set_status(trans, &trans_pcie->txq[txq_id], 0, 0); return 0; @@ -725,9 +725,9 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans->shrd->cmd_queue); - phys_addr = dma_map_single(bus(trans)->dev, &out_cmd->hdr, copy_size, + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; goto out; } @@ -748,10 +748,10 @@ static int iwl_enqueue_hcmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd) continue; if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) continue; - phys_addr = dma_map_single(bus(trans)->dev, + phys_addr = dma_map_single(trans->dev, (void *)cmd->data[i], cmd->len[i], DMA_BIDIRECTIONAL); - if (dma_mapping_error(bus(trans)->dev, phys_addr)) { + if (dma_mapping_error(trans->dev, phys_addr)) { iwlagn_unmap_tfd(trans, out_meta, &txq->tfds[q->write_ptr], DMA_BIDIRECTIONAL); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 80f531844f3..a1ee2e4b0ce 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -80,7 +80,7 @@ static int iwl_trans_rx_alloc(struct iwl_trans *trans) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_rx_queue *rxq = &trans_pcie->rxq; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; memset(&trans_pcie->rxq, 0, sizeof(trans_pcie->rxq)); @@ -124,7 +124,7 @@ static void iwl_trans_rxq_free_rx_bufs(struct iwl_trans *trans) /* In the reset function, these buffers may have been allocated * to an SKB, so we need to unmap and free potential storage */ if (rxq->pool[i].page != NULL) { - dma_unmap_page(bus(trans)->dev, rxq->pool[i].page_dma, + dma_unmap_page(trans->dev, rxq->pool[i].page_dma, PAGE_SIZE << hw_params(trans).rx_page_order, DMA_FROM_DEVICE); __free_pages(rxq->pool[i].page, @@ -148,17 +148,17 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; /* Stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); /* Reset driver's Rx queue write index */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); /* Tell device where to find RBD circular buffer in DRAM */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_RBDCB_BASE_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_RBDCB_BASE_REG, (u32)(rxq->bd_dma >> 8)); /* Tell device where in DRAM to update its Rx status */ - iwl_write_direct32(bus(trans), FH_RSCSR_CHNL0_STTS_WPTR_REG, + iwl_write_direct32(trans, FH_RSCSR_CHNL0_STTS_WPTR_REG, rxq->rb_stts_dma >> 4); /* Enable Rx DMA @@ -169,7 +169,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, * RB timeout 0x10 * 256 RBDs */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | @@ -179,7 +179,7 @@ static void iwl_trans_rx_hw_init(struct iwl_trans *trans, (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS)); /* Set interrupt coalescing timer to default (2048 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); } static int iwl_rx_init(struct iwl_trans *trans) @@ -244,13 +244,13 @@ static void iwl_trans_pcie_rx_free(struct iwl_trans *trans) iwl_trans_rxq_free_rx_bufs(trans); spin_unlock_irqrestore(&rxq->lock, flags); - dma_free_coherent(bus(trans)->dev, sizeof(__le32) * RX_QUEUE_SIZE, + dma_free_coherent(trans->dev, sizeof(__le32) * RX_QUEUE_SIZE, rxq->bd, rxq->bd_dma); memset(&rxq->bd_dma, 0, sizeof(rxq->bd_dma)); rxq->bd = NULL; if (rxq->rb_stts) - dma_free_coherent(bus(trans)->dev, + dma_free_coherent(trans->dev, sizeof(struct iwl_rb_status), rxq->rb_stts, rxq->rb_stts_dma); else @@ -263,8 +263,8 @@ static int iwl_trans_rx_stop(struct iwl_trans *trans) { /* stop Rx DMA */ - iwl_write_direct32(bus(trans), FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); - return iwl_poll_direct_bit(bus(trans), FH_MEM_RSSR_RX_STATUS_REG, + iwl_write_direct32(trans, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); + return iwl_poll_direct_bit(trans, FH_MEM_RSSR_RX_STATUS_REG, FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE, 1000); } @@ -274,7 +274,7 @@ static inline int iwlagn_alloc_dma_ptr(struct iwl_trans *trans, if (WARN_ON(ptr->addr)) return -EINVAL; - ptr->addr = dma_alloc_coherent(bus(trans)->dev, size, + ptr->addr = dma_alloc_coherent(trans->dev, size, &ptr->dma, GFP_KERNEL); if (!ptr->addr) return -ENOMEM; @@ -288,7 +288,7 @@ static inline void iwlagn_free_dma_ptr(struct iwl_trans *trans, if (unlikely(!ptr->addr)) return; - dma_free_coherent(bus(trans)->dev, ptr->size, ptr->addr, ptr->dma); + dma_free_coherent(trans->dev, ptr->size, ptr->addr, ptr->dma); memset(ptr, 0, sizeof(*ptr)); } @@ -335,7 +335,7 @@ static int iwl_trans_txq_alloc(struct iwl_trans *trans, /* Circular buffer of transmit frame descriptors (TFDs), * shared with device */ - txq->tfds = dma_alloc_coherent(bus(trans)->dev, tfd_sz, + txq->tfds = dma_alloc_coherent(trans->dev, tfd_sz, &txq->q.dma_addr, GFP_KERNEL); if (!txq->tfds) { IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); @@ -391,7 +391,7 @@ static int iwl_trans_txq_init(struct iwl_trans *trans, struct iwl_tx_queue *txq, * Tell nic where to find circular buffer of Tx Frame Descriptors for * given Tx queue, and enable the DMA channel used for that queue. * Circular buffer (TFD queue in DRAM) physical base address */ - iwl_write_direct32(bus(trans), FH_MEM_CBBC_QUEUE(txq_id), + iwl_write_direct32(trans, FH_MEM_CBBC_QUEUE(txq_id), txq->q.dma_addr >> 8); return 0; @@ -445,7 +445,7 @@ static void iwl_tx_queue_free(struct iwl_trans *trans, int txq_id) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_tx_queue *txq = &trans_pcie->txq[txq_id]; - struct device *dev = bus(trans)->dev; + struct device *dev = trans->dev; int i; if (WARN_ON(!txq)) return; @@ -586,10 +586,10 @@ static int iwl_tx_init(struct iwl_trans *trans) spin_lock_irqsave(&trans->shrd->lock, flags); /* Turn off all Tx DMA fifos */ - iwl_write_prph(bus(trans), SCD_TXFACT, 0); + iwl_write_prph(trans, SCD_TXFACT, 0); /* Tell NIC where to find the "keep warm" buffer */ - iwl_write_direct32(bus(trans), FH_KW_MEM_ADDR_REG, + iwl_write_direct32(trans, FH_KW_MEM_ADDR_REG, trans_pcie->kw.dma >> 4); spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -621,12 +621,12 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) * to set power to V_AUX, do: if (pci_pme_capable(priv->pci_dev, PCI_D3cold)) - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VAUX, ~APMG_PS_CTRL_MSK_PWR_SRC); */ - iwl_set_bits_mask_prph(bus(trans), APMG_PS_CTRL_REG, + iwl_set_bits_mask_prph(trans, APMG_PS_CTRL_REG, APMG_PS_CTRL_VAL_PWR_SRC_VMAIN, ~APMG_PS_CTRL_MSK_PWR_SRC); } @@ -640,7 +640,7 @@ static int iwl_nic_init(struct iwl_trans *trans) iwl_apm_init(priv(trans)); /* Set interrupt coalescing calibration timer to default (512 usecs) */ - iwl_write8(bus(trans), CSR_INT_COALESCING, + iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF); spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -660,7 +660,7 @@ static int iwl_nic_init(struct iwl_trans *trans) if (hw_params(trans).shadow_reg_enable) { /* enable shadow regs in HW */ - iwl_set_bit(bus(trans), CSR_MAC_SHADOW_REG_CTRL, + iwl_set_bit(trans, CSR_MAC_SHADOW_REG_CTRL, 0x800FFFFF); } @@ -676,11 +676,11 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) { int ret; - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY); /* See if we got it */ - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, CSR_HW_IF_CONFIG_REG_BIT_NIC_READY, HW_READY_TIMEOUT); @@ -701,10 +701,10 @@ static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) return 0; /* If HW is not ready, prepare the conditions to check again */ - iwl_set_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_PREPARE); - ret = iwl_poll_bit(bus(trans), CSR_HW_IF_CONFIG_REG, + ret = iwl_poll_bit(trans, CSR_HW_IF_CONFIG_REG, ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000); @@ -794,7 +794,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) } /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); else @@ -806,7 +806,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) return -ERFKILL; } - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); ret = iwl_nic_init(trans); if (ret) { @@ -815,17 +815,17 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) } /* make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); /* clear (again), then enable host interrupts */ - iwl_write32(bus(trans), CSR_INT, 0xFFFFFFFF); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); iwl_enable_interrupts(trans); /* really make sure rfkill handshake bits are cleared */ - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); - iwl_write32(bus(trans), CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); return 0; } @@ -836,7 +836,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) */ static void iwl_trans_txq_set_sched(struct iwl_trans *trans, u32 mask) { - iwl_write_prph(bus(trans), SCD_TXFACT, mask); + iwl_write_prph(trans, SCD_TXFACT, mask); } static void iwl_tx_start(struct iwl_trans *trans) @@ -852,46 +852,46 @@ static void iwl_tx_start(struct iwl_trans *trans) spin_lock_irqsave(&trans->shrd->lock, flags); trans_pcie->scd_base_addr = - iwl_read_prph(bus(trans), SCD_SRAM_BASE_ADDR); + iwl_read_prph(trans, SCD_SRAM_BASE_ADDR); a = trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_LOWER_BOUND; /* reset conext data memory */ for (; a < trans_pcie->scd_base_addr + SCD_CONTEXT_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); /* reset tx status memory */ for (; a < trans_pcie->scd_base_addr + SCD_TX_STTS_MEM_UPPER_BOUND; a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); for (; a < trans_pcie->scd_base_addr + SCD_TRANS_TBL_OFFSET_QUEUE(hw_params(trans).max_txq_num); a += 4) - iwl_write_targ_mem(bus(trans), a, 0); + iwl_write_targ_mem(trans, a, 0); - iwl_write_prph(bus(trans), SCD_DRAM_BASE_ADDR, + iwl_write_prph(trans, SCD_DRAM_BASE_ADDR, trans_pcie->scd_bc_tbls.dma >> 10); /* Enable DMA channel */ for (chan = 0; chan < FH_TCSR_CHNL_NUM ; chan++) - iwl_write_direct32(bus(trans), FH_TCSR_CHNL_TX_CONFIG_REG(chan), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(chan), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE); /* Update FH chicken bits */ - reg_val = iwl_read_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG); - iwl_write_direct32(bus(trans), FH_TX_CHICKEN_BITS_REG, + reg_val = iwl_read_direct32(trans, FH_TX_CHICKEN_BITS_REG); + iwl_write_direct32(trans, FH_TX_CHICKEN_BITS_REG, reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN); - iwl_write_prph(bus(trans), SCD_QUEUECHAIN_SEL, + iwl_write_prph(trans, SCD_QUEUECHAIN_SEL, SCD_QUEUECHAIN_SEL_ALL(trans)); - iwl_write_prph(bus(trans), SCD_AGGR_SEL, 0); + iwl_write_prph(trans, SCD_AGGR_SEL, 0); /* initiate the queues */ for (i = 0; i < hw_params(trans).max_txq_num; i++) { - iwl_write_prph(bus(trans), SCD_QUEUE_RDPTR(i), 0); - iwl_write_direct32(bus(trans), HBUS_TARG_WRPTR, 0 | (i << 8)); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_prph(trans, SCD_QUEUE_RDPTR(i), 0); + iwl_write_direct32(trans, HBUS_TARG_WRPTR, 0 | (i << 8)); + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i), 0); - iwl_write_targ_mem(bus(trans), trans_pcie->scd_base_addr + + iwl_write_targ_mem(trans, trans_pcie->scd_base_addr + SCD_CONTEXT_QUEUE_OFFSET(i) + sizeof(u32), ((SCD_WIN_SIZE << @@ -902,7 +902,7 @@ static void iwl_tx_start(struct iwl_trans *trans) SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK)); } - iwl_write_prph(bus(trans), SCD_INTERRUPT_MASK, + iwl_write_prph(trans, SCD_INTERRUPT_MASK, IWL_MASK(0, hw_params(trans).max_txq_num)); /* Activate all Tx DMA/FIFO channels */ @@ -948,7 +948,7 @@ static void iwl_tx_start(struct iwl_trans *trans) spin_unlock_irqrestore(&trans->shrd->lock, flags); /* Enable L1-Active */ - iwl_clear_bits_prph(bus(trans), APMG_PCIDEV_STT_REG, + iwl_clear_bits_prph(trans, APMG_PCIDEV_STT_REG, APMG_PCIDEV_STT_VAL_L1_ACT_DIS); } @@ -974,14 +974,14 @@ static int iwl_trans_tx_stop(struct iwl_trans *trans) /* Stop each Tx DMA channel, and wait for it to be idle */ for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { - iwl_write_direct32(bus(trans), + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0); - if (iwl_poll_direct_bit(bus(trans), FH_TSSR_TX_STATUS_REG, + if (iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG, FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000)) IWL_ERR(trans, "Failing on timeout while stopping" " DMA channel %d [0x%08x]", ch, - iwl_read_direct32(bus(trans), + iwl_read_direct32(trans, FH_TSSR_TX_STATUS_REG)); } spin_unlock_irqrestore(&trans->shrd->lock, flags); @@ -1024,13 +1024,13 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) iwl_trans_rx_stop(trans); #endif /* Power-down device's busmaster DMA clocks */ - iwl_write_prph(bus(trans), APMG_CLK_DIS_REG, + iwl_write_prph(trans, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT); udelay(5); } /* Make sure (redundant) we've released our request to stay awake */ - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ @@ -1048,7 +1048,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) tasklet_kill(&trans_pcie->irq_tasklet); /* stop and reset the on-board processor */ - iwl_write32(bus(trans), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); + iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); } static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, @@ -1145,10 +1145,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ - txcmd_phys = dma_map_single(bus(trans)->dev, + txcmd_phys = dma_map_single(trans->dev, &dev_cmd->hdr, firstlen, DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(bus(trans)->dev, txcmd_phys))) + if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) return -1; dma_unmap_addr_set(out_meta, mapping, txcmd_phys); dma_unmap_len_set(out_meta, len, firstlen); @@ -1164,10 +1164,10 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, * if any (802.11 null frames have no payload). */ secondlen = skb->len - hdr_len; if (secondlen > 0) { - phys_addr = dma_map_single(bus(trans)->dev, skb->data + hdr_len, + phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(bus(trans)->dev, phys_addr))) { - dma_unmap_single(bus(trans)->dev, + if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { + dma_unmap_single(trans->dev, dma_unmap_addr(out_meta, mapping), dma_unmap_len(out_meta, len), DMA_BIDIRECTIONAL); @@ -1185,7 +1185,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, offsetof(struct iwl_tx_cmd, scratch); /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(bus(trans)->dev, txcmd_phys, firstlen, + dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); @@ -1199,7 +1199,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, /* Set up entry for this TFD in Tx byte-count array */ iwl_trans_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(bus(trans)->dev, txcmd_phys, firstlen, + dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, DMA_BIDIRECTIONAL); trace_iwlwifi_dev_tx(priv(trans), @@ -1232,7 +1232,7 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) { /* Remove all resets to allow NIC to operate */ - iwl_write32(bus(trans), CSR_RESET, 0); + iwl_write32(trans, CSR_RESET, 0); } static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) @@ -1355,7 +1355,7 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) iwl_apm_stop(priv(trans)); } else { iwl_disable_interrupts(trans); - iwl_clear_bit(bus(trans), CSR_GP_CNTRL, + iwl_clear_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); } @@ -1368,7 +1368,7 @@ static int iwl_trans_pcie_resume(struct iwl_trans *trans) iwl_enable_interrupts(trans); - if (!(iwl_read32(bus(trans), CSR_GP_CNTRL) & + if (!(iwl_read32(trans, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) hw_rfkill = true; @@ -1464,9 +1464,9 @@ static int iwl_trans_pcie_check_stuck_queue(struct iwl_trans *trans, int cnt) IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", q->read_ptr, q->write_ptr); IWL_ERR(trans, "Current HW read_ptr %d write_ptr %d\n", - iwl_read_prph(bus(trans), SCD_QUEUE_RDPTR(cnt)) + iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) & (TFD_QUEUE_SIZE_MAX - 1), - iwl_read_prph(bus(trans), SCD_QUEUE_WRPTR(cnt))); + iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); return 1; } @@ -1520,7 +1520,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) pos += scnprintf(*buf + pos, bufsz - pos, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return pos; } @@ -1529,7 +1529,7 @@ int iwl_dump_fh(struct iwl_trans *trans, char **buf, bool display) for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) { IWL_ERR(trans, " %34s: 0X%08x\n", get_fh_string(fh_tbl[i]), - iwl_read_direct32(bus(trans), fh_tbl[i])); + iwl_read_direct32(trans, fh_tbl[i])); } return 0; } @@ -1599,7 +1599,7 @@ void iwl_dump_csr(struct iwl_trans *trans) for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) { IWL_ERR(trans, " %25s: 0X%08x\n", get_csr_string(csr_tbl[i]), - iwl_read32(bus(trans), csr_tbl[i])); + iwl_read32(trans, csr_tbl[i])); } } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0a3727dac6a..dec935a84a7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,7 @@ struct iwl_calib_result { * @ops - pointer to iwl_trans_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * @hcmd_lock: protects HCMD + * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device * @ucode_write_complete: indicates that the ucode has been copied. @@ -247,6 +248,7 @@ struct iwl_trans { const struct iwl_trans_ops *ops; struct iwl_shared *shrd; spinlock_t hcmd_lock; + spinlock_t reg_lock; struct device *dev; unsigned int irq; diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 0d7f207ac61..5de8b5beb09 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -126,42 +126,41 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, static int iwl_load_section(struct iwl_trans *trans, const char *name, struct fw_desc *image, u32 dst_addr) { - struct iwl_bus *bus = bus(trans); dma_addr_t phy_addr = image->p_addr; u32 byte_cnt = image->len; int ret; trans->ucode_write_complete = 0; - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), (iwl_get_dma_hi_addr(phy_addr) << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); - iwl_write_direct32(bus, + iwl_write_direct32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - IWL_DEBUG_FW(bus, "%s uCode section being loaded...\n", name); + IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); ret = wait_event_timeout(trans->shrd->wait_command_queue, trans->ucode_write_complete, 5 * HZ); if (!ret) { @@ -470,7 +469,7 @@ static int iwl_alive_notify(struct iwl_trans *trans) * using sample data 100 bytes apart. If these sample points are good, * it's a pretty good bet that everything between them is good, too. */ -static int iwl_verify_inst_sparse(struct iwl_bus *bus, +static int iwl_verify_inst_sparse(struct iwl_trans *trans, struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -478,15 +477,15 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, u32 val; u32 i; - IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); for (i = 0; i < len; i += 100, image += 100/sizeof(u32)) { /* read data comes through single port, auto-incr addr */ /* NOTE: Use the debugless read so we don't flood kernel log * if IWL_DL_IO is set */ - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, i + IWLAGN_RTC_INST_LOWER_BOUND); - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) return -EIO; } @@ -494,7 +493,7 @@ static int iwl_verify_inst_sparse(struct iwl_bus *bus, return 0; } -static void iwl_print_mismatch_inst(struct iwl_bus *bus, +static void iwl_print_mismatch_inst(struct iwl_trans *trans, struct fw_desc *fw_desc) { __le32 *image = (__le32 *)fw_desc->v_addr; @@ -503,18 +502,18 @@ static void iwl_print_mismatch_inst(struct iwl_bus *bus, u32 offs; int errors = 0; - IWL_DEBUG_FW(bus, "ucode inst image size is %u\n", len); + IWL_DEBUG_FW(trans, "ucode inst image size is %u\n", len); - iwl_write_direct32(bus, HBUS_TARG_MEM_RADDR, + iwl_write_direct32(trans, HBUS_TARG_MEM_RADDR, IWLAGN_RTC_INST_LOWER_BOUND); for (offs = 0; offs < len && errors < 20; offs += sizeof(u32), image++) { /* read data comes through single port, auto-incr addr */ - val = iwl_read32(bus, HBUS_TARG_MEM_RDAT); + val = iwl_read32(trans, HBUS_TARG_MEM_RDAT); if (val != le32_to_cpu(*image)) { - IWL_ERR(bus, "uCode INST section at " + IWL_ERR(trans, "uCode INST section at " "offset 0x%x, is 0x%x, s/b 0x%x\n", offs, val, le32_to_cpu(*image)); errors++; @@ -536,14 +535,14 @@ static int iwl_verify_ucode(struct iwl_trans *trans, return -EINVAL; } - if (!iwl_verify_inst_sparse(bus(trans), &img->code)) { + if (!iwl_verify_inst_sparse(trans, &img->code)) { IWL_DEBUG_FW(trans, "uCode is good in inst SRAM\n"); return 0; } IWL_ERR(trans, "UCODE IMAGE IN INSTRUCTION SRAM NOT VALID!!\n"); - iwl_print_mismatch_inst(bus(trans), &img->code); + iwl_print_mismatch_inst(trans, &img->code); return -EIO; } -- cgit v1.2.3-70-g09d2 From ea4caade104490de0fadb64660f9e228c050fb3d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 4 Jan 2012 14:23:20 +0200 Subject: iwlwifi: remove the pointer to dev from the bus layer Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++-- drivers/net/wireless/iwlwifi/iwl-bus.h | 2 -- drivers/net/wireless/iwlwifi/iwl-debug.h | 16 ++++++++-------- drivers/net/wireless/iwlwifi/iwl-pci.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-ucode.c | 4 ++-- 5 files changed, 16 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index f79791500a9..d890b6481b8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1146,7 +1146,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) iwl_dealloc_ucode(trans(priv)); out_unbind: complete(&priv->firmware_loading_complete); - device_release_driver(bus(priv)->dev); + device_release_driver(trans(priv)->dev); release_firmware(ucode_raw); } @@ -1785,7 +1785,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* At this point both hw and priv are allocated. */ - SET_IEEE80211_DEV(hw, bus(priv)->dev); + SET_IEEE80211_DEV(hw, trans(priv)->dev); /* what debugging capabilities we have */ iwl_debug_config(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index ce1a9cc106e..2065c5b7416 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -137,14 +137,12 @@ struct iwl_bus_ops { * * This data is common to all bus layer implementations. * - * @dev - pointer to struct device * that represents the device * @ops - pointer to iwl_bus_ops * @shrd - pointer to iwl_shared which holds shared data from the upper layer * NB: for the time being this needs to be set by the upper layer since * it allocates the shared data */ struct iwl_bus { - struct device *dev; const struct iwl_bus_ops *ops; struct iwl_shared *shrd; diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h index 6f7612781e0..351b41d7f4f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-debug.h +++ b/drivers/net/wireless/iwlwifi/iwl-debug.h @@ -35,10 +35,10 @@ struct iwl_priv; /*No matter what is m (priv, bus, trans), this will work */ -#define IWL_ERR(m, f, a...) dev_err(bus(m)->dev, f, ## a) -#define IWL_WARN(m, f, a...) dev_warn(bus(m)->dev, f, ## a) -#define IWL_INFO(m, f, a...) dev_info(bus(m)->dev, f, ## a) -#define IWL_CRIT(m, f, a...) dev_crit(bus(m)->dev, f, ## a) +#define IWL_ERR(m, f, a...) dev_err(trans(m)->dev, f, ## a) +#define IWL_WARN(m, f, a...) dev_warn(trans(m)->dev, f, ## a) +#define IWL_INFO(m, f, a...) dev_info(trans(m)->dev, f, ## a) +#define IWL_CRIT(m, f, a...) dev_crit(trans(m)->dev, f, ## a) #define iwl_print_hex_error(m, p, len) \ do { \ @@ -50,7 +50,7 @@ do { \ #define IWL_DEBUG(m, level, fmt, ...) \ do { \ if (iwl_get_debug_level((m)->shrd) & (level)) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ + dev_err(trans(m)->dev, "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ } while (0) @@ -59,7 +59,7 @@ do { \ do { \ if (iwl_get_debug_level((m)->shrd) & (level) && \ net_ratelimit()) \ - dev_err(bus(m)->dev, "%c %s " fmt, \ + dev_err(trans(m)->dev, "%c %s " fmt, \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ } while (0) @@ -74,12 +74,12 @@ do { \ #define IWL_DEBUG_QUIET_RFKILL(p, fmt, ...) \ do { \ if (!iwl_is_rfkill(p->shrd)) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ + dev_err(trans(p)->dev, "%s%c %s " fmt, \ "", \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ else if (iwl_get_debug_level(p->shrd) & IWL_DL_RADIO) \ - dev_err(bus(p)->dev, "%s%c %s " fmt, \ + dev_err(trans(p)->dev, "%s%c %s " fmt, \ "(RFKILL) ", \ in_interrupt() ? 'I' : 'U', __func__, \ ##__VA_ARGS__); \ diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 7bab8192848..6451739aed2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -123,12 +123,14 @@ static void iwl_pci_apm_config(struct iwl_bus *bus) /* L1-ASPM enabled; disable(!) L0S */ iwl_set_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Enabled; Disabling L0S\n"); + dev_printk(KERN_INFO, trans(bus)->dev, + "L1 Enabled; Disabling L0S\n"); } else { /* L1-ASPM disabled; enable(!) L0S */ iwl_clear_bit(trans(bus), CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, bus->dev, "L1 Disabled; Enabling L0S\n"); + dev_printk(KERN_INFO, trans(bus)->dev, + "L1 Disabled; Enabling L0S\n"); } } @@ -368,7 +370,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, bus); - bus->dev = &pdev->dev; bus->ops = &bus_ops_pci; #ifdef CONFIG_IWLWIFI_IDI diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 5de8b5beb09..08483d785e2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -83,7 +83,7 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(bus->dev, desc->len, + dma_free_coherent(trans(bus)->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; @@ -110,7 +110,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(bus->dev, len, + desc->v_addr = dma_alloc_coherent(trans(bus)->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 8467ab4f42396a3714b59ca187f470542970ff9d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Tue, 3 Jan 2012 16:28:12 +0200 Subject: iwlwifi: don't use the bus for ucode fw_desc any more This is transport related Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ++++++++------ drivers/net/wireless/iwlwifi/iwl-trans.h | 2 +- drivers/net/wireless/iwlwifi/iwl-ucode.c | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d890b6481b8..8b1839aec40 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1023,31 +1023,33 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) /* Runtime instructions and 2 copies of data: * 1) unmodified from disk * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.code, + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, pieces.inst, pieces.inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_rt.data, + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, pieces.data, pieces.data_size)) goto err_pci_alloc; /* Initialization instructions and data */ if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.code, + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.code, pieces.init, pieces.init_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), &trans(priv)->ucode_init.data, + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.data, pieces.init_data, pieces.init_data_size)) goto err_pci_alloc; } /* WoWLAN instructions and data */ if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(bus(priv), + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_wowlan.code, pieces.wowlan_inst, pieces.wowlan_inst_size)) goto err_pci_alloc; - if (iwl_alloc_fw_desc(bus(priv), + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_wowlan.data, pieces.wowlan_data, pieces.wowlan_data_size)) diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index dec935a84a7..d5195998417 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -408,7 +408,7 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) /***************************************************** * Utils functions ******************************************************/ -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, +int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 08483d785e2..793524a3ed7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -80,29 +80,29 @@ static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = { * ******************************************************************************/ -static void iwl_free_fw_desc(struct iwl_bus *bus, struct fw_desc *desc) +static void iwl_free_fw_desc(struct iwl_trans *trans, struct fw_desc *desc) { if (desc->v_addr) - dma_free_coherent(trans(bus)->dev, desc->len, + dma_free_coherent(trans->dev, desc->len, desc->v_addr, desc->p_addr); desc->v_addr = NULL; desc->len = 0; } -static void iwl_free_fw_img(struct iwl_bus *bus, struct fw_img *img) +static void iwl_free_fw_img(struct iwl_trans *trans, struct fw_img *img) { - iwl_free_fw_desc(bus, &img->code); - iwl_free_fw_desc(bus, &img->data); + iwl_free_fw_desc(trans, &img->code); + iwl_free_fw_desc(trans, &img->data); } void iwl_dealloc_ucode(struct iwl_trans *trans) { - iwl_free_fw_img(bus(trans), &trans->ucode_rt); - iwl_free_fw_img(bus(trans), &trans->ucode_init); - iwl_free_fw_img(bus(trans), &trans->ucode_wowlan); + iwl_free_fw_img(trans, &trans->ucode_rt); + iwl_free_fw_img(trans, &trans->ucode_init); + iwl_free_fw_img(trans, &trans->ucode_wowlan); } -int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, +int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -110,7 +110,7 @@ int iwl_alloc_fw_desc(struct iwl_bus *bus, struct fw_desc *desc, return -EINVAL; } - desc->v_addr = dma_alloc_coherent(trans(bus)->dev, len, + desc->v_addr = dma_alloc_coherent(trans->dev, len, &desc->p_addr, GFP_KERNEL); if (!desc->v_addr) return -ENOMEM; -- cgit v1.2.3-70-g09d2 From 57a1dc89097982874f50a0e6f68ab08f62e9e5aa Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:22:16 +0200 Subject: iwlwifi: rename trans_ops->request_irq to trans_ops->start_hw This handler will become thicker, reflect its real role now. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 36 ++++++++++++++--------- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 ++--- 4 files changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 8b1839aec40..1c00691c9f0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1829,7 +1829,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, IWL_INFO(priv, "Detected %s, REV=0x%X\n", cfg(priv)->name, hw_rev); - err = iwl_trans_request_irq(trans(priv)); + err = iwl_trans_start_hw(trans(priv)); if (err) goto out_free_traffic_mem; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h index 555175ff4f9..561865f29d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-int.h @@ -201,6 +201,7 @@ struct iwl_tx_queue { * @rxq: all the RX queue data * @rx_replenish: work that will be called when buffers need to be allocated * @trans: pointer to the generic transport area + * @irq_requested: true when the irq has been requested * @scd_base_addr: scheduler sram base address in SRAM * @scd_bc_tbls: pointer to the byte count table of the scheduler * @kw: keep warm address @@ -225,6 +226,7 @@ struct iwl_trans_pcie { int ict_index; u32 inta; bool use_ict; + bool irq_requested; struct tasklet_struct irq_tasklet; struct isr_statistics isr_stats; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index a1ee2e4b0ce..ffbafb9e447 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1235,7 +1235,7 @@ static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) iwl_write32(trans, CSR_RESET, 0); } -static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) +static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); @@ -1243,20 +1243,26 @@ static int iwl_trans_pcie_request_irq(struct iwl_trans *trans) trans_pcie->inta_mask = CSR_INI_SET_MASK; - tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) - iwl_irq_tasklet, (unsigned long)trans); + if (!trans_pcie->irq_requested) { + tasklet_init(&trans_pcie->irq_tasklet, (void (*)(unsigned long)) + iwl_irq_tasklet, (unsigned long)trans); - iwl_alloc_isr_ict(trans); + iwl_alloc_isr_ict(trans); - err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, - DRV_NAME, trans); - if (err) { - IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); - iwl_free_isr_ict(trans); - return err; + err = request_irq(trans->irq, iwl_isr_ict, IRQF_SHARED, + DRV_NAME, trans); + if (err) { + IWL_ERR(trans, "Error allocating IRQ %d\n", + trans->irq); + iwl_free_isr_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; + } + + INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); + trans_pcie->irq_requested = true; } - INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); return 0; } @@ -1325,8 +1331,10 @@ static void iwl_trans_pcie_free(struct iwl_trans *trans) #ifndef CONFIG_IWLWIFI_IDI iwl_trans_pcie_rx_free(trans); #endif - free_irq(trans->irq, trans); - iwl_free_isr_ict(trans); + if (trans_pcie->irq_requested == true) { + free_irq(trans->irq, trans); + iwl_free_isr_ict(trans); + } pci_disable_msi(trans_pcie->pci_dev); pci_iounmap(trans_pcie->pci_dev, trans_pcie->hw_base); @@ -1920,7 +1928,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, #endif /*CONFIG_IWLWIFI_DEBUGFS */ const struct iwl_trans_ops trans_ops_pcie = { - .request_irq = iwl_trans_pcie_request_irq, + .start_hw = iwl_trans_pcie_start_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index d5195998417..ddc3a0627dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -133,7 +133,7 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations - * @request_irq: requests IRQ - will be called before the FW load in probe flow + * @start_hw: starts the HW- from that point on, the HW can send interrupts * @start_device: allocates and inits all the resources for the transport * layer. * @prepare_card_hw: claim the ownership on the HW. Will be called during @@ -164,7 +164,7 @@ struct iwl_host_cmd { */ struct iwl_trans_ops { - int (*request_irq)(struct iwl_trans *iwl_trans); + int (*start_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); int (*prepare_card_hw)(struct iwl_trans *trans); @@ -269,9 +269,9 @@ struct iwl_trans { char trans_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline int iwl_trans_request_irq(struct iwl_trans *trans) +static inline int iwl_trans_start_hw(struct iwl_trans *trans) { - return trans->ops->request_irq(trans); + return trans->ops->start_hw(trans); } static inline void iwl_trans_fw_alive(struct iwl_trans *trans) -- cgit v1.2.3-70-g09d2 From ebb7678d00b2fa0d7db76b5303a5bf46a5aed8f3 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:24:57 +0200 Subject: iwlwifi: move prepare_card_hw to start_hw Kill the trans_ops->prepare_card_hw which is now useless. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ------ drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 22 +++++++++++++++------- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 -------- 3 files changed, 15 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 1c00691c9f0..5ab7f681991 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1833,12 +1833,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, if (err) goto out_free_traffic_mem; - if (iwl_trans_prepare_card_hw(trans(priv))) { - err = -EIO; - IWL_WARN(priv, "Failed, HW not ready\n"); - goto out_free_traffic_mem; - } - /***************** * 4. Read EEPROM *****************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ffbafb9e447..d1ab57a7988 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -690,13 +690,14 @@ static int iwl_set_hw_ready(struct iwl_trans *trans) } /* Note: returns standard 0/-ERROR code */ -static int iwl_trans_pcie_prepare_card_hw(struct iwl_trans *trans) +static int iwl_prepare_card_hw(struct iwl_trans *trans) { int ret; IWL_DEBUG_INFO(trans, "iwl_trans_prepare_card_hw enter\n"); ret = iwl_set_hw_ready(trans); + /* If the card is ready, exit 0 */ if (ret >= 0) return 0; @@ -788,7 +789,7 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) trans_pcie->mcast_queue[IWL_RXON_CTX_PAN] = IWL_IPAN_MCAST_QUEUE; if ((hw_params(trans).sku & EEPROM_SKU_CAP_AMT_ENABLE) && - iwl_trans_pcie_prepare_card_hw(trans)) { + iwl_prepare_card_hw(trans)) { IWL_WARN(trans, "Exit HW not ready\n"); return -EIO; } @@ -1254,16 +1255,24 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) if (err) { IWL_ERR(trans, "Error allocating IRQ %d\n", trans->irq); - iwl_free_isr_ict(trans); - tasklet_kill(&trans_pcie->irq_tasklet); - return err; + goto error; } INIT_WORK(&trans_pcie->rx_replenish, iwl_bg_rx_replenish); trans_pcie->irq_requested = true; } - return 0; + err = iwl_prepare_card_hw(trans); + if (err) { + IWL_ERR(trans, "Error while preparing HW: %d", err); + goto error; + } + return err; + +error: + iwl_free_isr_ict(trans); + tasklet_kill(&trans_pcie->irq_tasklet); + return err; } static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, @@ -1931,7 +1940,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, - .prepare_card_hw = iwl_trans_pcie_prepare_card_hw, .stop_device = iwl_trans_pcie_stop_device, .wake_any_queue = iwl_trans_pcie_wake_any_queue, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index ddc3a0627dd..55b5dc3b5dd 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -136,8 +136,6 @@ struct iwl_host_cmd { * @start_hw: starts the HW- from that point on, the HW can send interrupts * @start_device: allocates and inits all the resources for the transport * layer. - * @prepare_card_hw: claim the ownership on the HW. Will be called during - * probe. * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) @@ -167,7 +165,6 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); - int (*prepare_card_hw)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); void (*wake_any_queue)(struct iwl_trans *trans, @@ -284,11 +281,6 @@ static inline int iwl_trans_start_device(struct iwl_trans *trans) return trans->ops->start_device(trans); } -static inline int iwl_trans_prepare_card_hw(struct iwl_trans *trans) -{ - return trans->ops->prepare_card_hw(trans); -} - static inline void iwl_trans_stop_device(struct iwl_trans *trans) { trans->ops->stop_device(trans); -- cgit v1.2.3-70-g09d2 From a6c684ee489a99a54f978aa92a9bf1e82f8c633b Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:24:57 +0200 Subject: iwlwifi: move apm_init to start_hw This is transport related Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 - drivers/net/wireless/iwlwifi/iwl-core.c | 85 -------------------------- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 88 ++++++++++++++++++++++++++- 4 files changed, 87 insertions(+), 89 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 5ab7f681991..3aeaa890e64 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1836,8 +1836,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /***************** * 4. Read EEPROM *****************/ - /* switch the NIC on before accessing the EEPROM */ - iwl_apm_init(priv); /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); /* Reset chip to save power until we load uCode during "up". */ diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index c9022c5fa81..3ba59fa3108 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -923,91 +923,6 @@ void iwl_apm_stop(struct iwl_priv *priv) CSR_GP_CNTRL_REG_FLAG_INIT_DONE); } - -/* - * Start up NIC's basic functionality after it has been reset - * (e.g. after platform boot, or shutdown via iwl_apm_stop()) - * NOTE: This does not load uCode nor start the embedded processor - */ -int iwl_apm_init(struct iwl_priv *priv) -{ - int ret = 0; - IWL_DEBUG_INFO(priv, "Init card's basic functions\n"); - - /* - * Use "set_bit" below rather than "write", to preserve any hardware - * bits already set by default after reset. - */ - - /* Disable L0S exit timer (platform NMI Work/Around) */ - iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); - - /* - * Disable L0s without affecting L1; - * don't wait for ICH L0s (ICH bug W/A) - */ - iwl_set_bit(trans(priv), CSR_GIO_CHICKEN_BITS, - CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); - - /* Set FH wait threshold to maximum (HW error during stress W/A) */ - iwl_set_bit(trans(priv), CSR_DBG_HPET_MEM_REG, - CSR_DBG_HPET_MEM_REG_VAL); - - /* - * Enable HAP INTA (interrupt from management bus) to - * wake device's PCI Express link L1a -> L0s - */ - iwl_set_bit(trans(priv), CSR_HW_IF_CONFIG_REG, - CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - - bus_apm_config(bus(priv)); - - /* Configure analog phase-lock-loop before activating to D0A */ - if (cfg(priv)->base_params->pll_cfg_val) - iwl_set_bit(trans(priv), CSR_ANA_PLL_CFG, - cfg(priv)->base_params->pll_cfg_val); - - /* - * Set "initialization complete" bit to move adapter from - * D0U* --> D0A* (powered-up active) state. - */ - iwl_set_bit(trans(priv), CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); - - /* - * Wait for clock stabilization; once stabilized, access to - * device-internal resources is supported, e.g. iwl_write_prph() - * and accesses to uCode SRAM. - */ - ret = iwl_poll_bit(trans(priv), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, - CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); - if (ret < 0) { - IWL_DEBUG_INFO(priv, "Failed to init the card\n"); - goto out; - } - - /* - * Enable DMA clock and wait for it to stabilize. - * - * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits - * do not disable clocks. This preserves any hardware bits already - * set by default in "CLK_CTRL_REG" after reset. - */ - iwl_write_prph(trans(priv), APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); - udelay(20); - - /* Disable L1-Active */ - iwl_set_bits_prph(trans(priv), APMG_PCIDEV_STT_REG, - APMG_PCIDEV_STT_VAL_L1_ACT_DIS); - - set_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - -out: - return ret; -} - - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 04975b7b65b..338a55f403d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -544,7 +544,6 @@ void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); void iwl_nic_config(struct iwl_priv *priv); void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); void iwl_apm_stop(struct iwl_priv *priv); -int iwl_apm_init(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); bool iwl_check_for_ct_kill(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index d1ab57a7988..335d4b1508c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -74,6 +74,7 @@ #include "iwl-shared.h" #include "iwl-eeprom.h" #include "iwl-agn-hw.h" +#include "iwl-core.h" static int iwl_trans_rx_alloc(struct iwl_trans *trans) { @@ -631,13 +632,95 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) ~APMG_PS_CTRL_MSK_PWR_SRC); } +/* + * Start up NIC's basic functionality after it has been reset + * (e.g. after platform boot, or shutdown via iwl_apm_stop()) + * NOTE: This does not load uCode nor start the embedded processor + */ +static int iwl_apm_init(struct iwl_trans *trans) +{ + int ret = 0; + IWL_DEBUG_INFO(trans, "Init card's basic functions\n"); + + /* + * Use "set_bit" below rather than "write", to preserve any hardware + * bits already set by default after reset. + */ + + /* Disable L0S exit timer (platform NMI Work/Around) */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER); + + /* + * Disable L0s without affecting L1; + * don't wait for ICH L0s (ICH bug W/A) + */ + iwl_set_bit(trans, CSR_GIO_CHICKEN_BITS, + CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX); + + /* Set FH wait threshold to maximum (HW error during stress W/A) */ + iwl_set_bit(trans, CSR_DBG_HPET_MEM_REG, CSR_DBG_HPET_MEM_REG_VAL); + + /* + * Enable HAP INTA (interrupt from management bus) to + * wake device's PCI Express link L1a -> L0s + */ + iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, + CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); + + bus_apm_config(bus(trans)); + + /* Configure analog phase-lock-loop before activating to D0A */ + if (cfg(trans)->base_params->pll_cfg_val) + iwl_set_bit(trans, CSR_ANA_PLL_CFG, + cfg(trans)->base_params->pll_cfg_val); + + /* + * Set "initialization complete" bit to move adapter from + * D0U* --> D0A* (powered-up active) state. + */ + iwl_set_bit(trans, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE); + + /* + * Wait for clock stabilization; once stabilized, access to + * device-internal resources is supported, e.g. iwl_write_prph() + * and accesses to uCode SRAM. + */ + ret = iwl_poll_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, + CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000); + if (ret < 0) { + IWL_DEBUG_INFO(trans, "Failed to init the card\n"); + goto out; + } + + /* + * Enable DMA clock and wait for it to stabilize. + * + * Write to "CLK_EN_REG"; "1" bits enable clocks, while "0" bits + * do not disable clocks. This preserves any hardware bits already + * set by default in "CLK_CTRL_REG" after reset. + */ + iwl_write_prph(trans, APMG_CLK_EN_REG, APMG_CLK_VAL_DMA_CLK_RQT); + udelay(20); + + /* Disable L1-Active */ + iwl_set_bits_prph(trans, APMG_PCIDEV_STT_REG, + APMG_PCIDEV_STT_VAL_L1_ACT_DIS); + + set_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + +out: + return ret; +} + static int iwl_nic_init(struct iwl_trans *trans) { unsigned long flags; /* nic_init */ spin_lock_irqsave(&trans->shrd->lock, flags); - iwl_apm_init(priv(trans)); + iwl_apm_init(trans); /* Set interrupt coalescing calibration timer to default (512 usecs) */ iwl_write8(trans, CSR_INT_COALESCING, @@ -1267,6 +1350,9 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) IWL_ERR(trans, "Error while preparing HW: %d", err); goto error; } + + iwl_apm_init(trans); + return err; error: -- cgit v1.2.3-70-g09d2 From cc56feb2eb06a0a80a8f07e4adab7e6626009cca Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:37:59 +0200 Subject: iwlwifi: introduce trans_ops->stop_hw This handler stops the HW and puts it in low power state. It will allow to clean up the flows in the upper layers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- drivers/net/wireless/iwlwifi/iwl-core.c | 40 -------------------- drivers/net/wireless/iwlwifi/iwl-shared.h | 1 - drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 54 ++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 ++++ 5 files changed, 61 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 3aeaa890e64..88462467a95 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1839,7 +1839,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /* Read the EEPROM */ err = iwl_eeprom_init(priv, hw_rev); /* Reset chip to save power until we load uCode during "up". */ - iwl_apm_stop(priv); + iwl_trans_stop_hw(trans(priv)); if (err) { IWL_ERR(priv, "Unable to init EEPROM\n"); goto out_free_traffic_mem; diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 3ba59fa3108..95f2c33695b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -883,46 +883,6 @@ void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand) } } -static int iwl_apm_stop_master(struct iwl_priv *priv) -{ - int ret = 0; - - /* stop device's busmaster DMA activity */ - iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); - - ret = iwl_poll_bit(trans(priv), CSR_RESET, - CSR_RESET_REG_FLAG_MASTER_DISABLED, - CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); - if (ret) - IWL_WARN(priv, "Master Disable Timed Out, 100 usec\n"); - - IWL_DEBUG_INFO(priv, "stop master\n"); - - return ret; -} - -void iwl_apm_stop(struct iwl_priv *priv) -{ - IWL_DEBUG_INFO(priv, "Stop card, put in low power state\n"); - - clear_bit(STATUS_DEVICE_ENABLED, &priv->shrd->status); - - /* Stop device's DMA activity */ - iwl_apm_stop_master(priv); - - /* Reset the entire device */ - iwl_set_bit(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); - - udelay(10); - - /* - * Clear "initialization complete" bit to move adapter from - * D0A* (powered-up Active) --> D0U* (Uninitialized) state. - */ - iwl_clear_bit(trans(priv), CSR_GP_CNTRL, - CSR_GP_CNTRL_REG_FLAG_INIT_DONE); -} - int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force) { int ret; diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h index 338a55f403d..63d4a4fc5b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-shared.h +++ b/drivers/net/wireless/iwlwifi/iwl-shared.h @@ -543,7 +543,6 @@ int iwlagn_hw_valid_rtc_data_addr(u32 addr); void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state); void iwl_nic_config(struct iwl_priv *priv); void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb); -void iwl_apm_stop(struct iwl_priv *priv); void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand); const char *get_cmd_string(u8 cmd); bool iwl_check_for_ct_kill(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 335d4b1508c..43e894f6737 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -714,6 +714,46 @@ out: return ret; } +static int iwl_apm_stop_master(struct iwl_trans *trans) +{ + int ret = 0; + + /* stop device's busmaster DMA activity */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER); + + ret = iwl_poll_bit(trans, CSR_RESET, + CSR_RESET_REG_FLAG_MASTER_DISABLED, + CSR_RESET_REG_FLAG_MASTER_DISABLED, 100); + if (ret) + IWL_WARN(trans, "Master Disable Timed Out, 100 usec\n"); + + IWL_DEBUG_INFO(trans, "stop master\n"); + + return ret; +} + +static void iwl_apm_stop(struct iwl_trans *trans) +{ + IWL_DEBUG_INFO(trans, "Stop card, put in low power state\n"); + + clear_bit(STATUS_DEVICE_ENABLED, &trans->shrd->status); + + /* Stop device's DMA activity */ + iwl_apm_stop_master(trans); + + /* Reset the entire device */ + iwl_set_bit(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET); + + udelay(10); + + /* + * Clear "initialization complete" bit to move adapter from + * D0A* (powered-up Active) --> D0U* (Uninitialized) state. + */ + iwl_clear_bit(trans, CSR_GP_CNTRL, + CSR_GP_CNTRL_REG_FLAG_INIT_DONE); +} + static int iwl_nic_init(struct iwl_trans *trans) { unsigned long flags; @@ -1118,7 +1158,7 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans) CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); /* Stop the device, and put it in low power state */ - iwl_apm_stop(priv(trans)); + iwl_apm_stop(trans); /* Upon stop, the APM issues an interrupt if HW RF kill is set. * Clean again the interrupt here @@ -1361,6 +1401,15 @@ error: return err; } +static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) +{ + iwl_apm_stop(trans); + + /* Even if we stop the HW, we still want the RF kill interrupt */ + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); +} + static int iwl_trans_pcie_reclaim(struct iwl_trans *trans, int sta_id, int tid, int txq_id, int ssn, u32 status, struct sk_buff_head *skbs) @@ -1455,7 +1504,7 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans) * things already :-) */ if (!trans->shrd->wowlan) { - iwl_apm_stop(priv(trans)); + iwl_apm_stop(trans); } else { iwl_disable_interrupts(trans); iwl_clear_bit(trans, CSR_GP_CNTRL, @@ -2024,6 +2073,7 @@ static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, + .stop_hw = iwl_trans_pcie_stop_hw, .fw_alive = iwl_trans_pcie_fw_alive, .start_device = iwl_trans_pcie_start_device, .stop_device = iwl_trans_pcie_stop_device, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 55b5dc3b5dd..d0b6146b097 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -134,6 +134,8 @@ struct iwl_host_cmd { /** * struct iwl_trans_ops - transport specific operations * @start_hw: starts the HW- from that point on, the HW can send interrupts + * @stop_hw: stops the HW- from that point on, the HW will be in low power but + * will still issue interrupt if the HW RF kill is triggered. * @start_device: allocates and inits all the resources for the transport * layer. * @fw_alive: called when the fw sends alive notification @@ -163,6 +165,7 @@ struct iwl_host_cmd { struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); + void (*stop_hw)(struct iwl_trans *iwl_trans); int (*start_device)(struct iwl_trans *trans); void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); @@ -271,6 +274,11 @@ static inline int iwl_trans_start_hw(struct iwl_trans *trans) return trans->ops->start_hw(trans); } +static inline void iwl_trans_stop_hw(struct iwl_trans *trans) +{ + trans->ops->stop_hw(trans); +} + static inline void iwl_trans_fw_alive(struct iwl_trans *trans) { trans->ops->fw_alive(trans); -- cgit v1.2.3-70-g09d2 From d48e2074e240192e8a0396e1ae0082dd0e78aa8e Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 13:48:21 +0200 Subject: iwlwifi: move the RF kill logic from iwl_probe to transport This is another clean up of the proble flow. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 23 ----------------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 11 +++++++++++ 2 files changed, 11 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 88462467a95..14f8b750c7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1815,13 +1815,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, spin_lock_init(&trans(priv)->reg_lock); spin_lock_init(&priv->shrd->lock); - /* - * stop and reset the on-board processor just in case it is in a - * strange state ... like being left stranded by a primary kernel - * and this is now the kdump kernel trying to start up - */ - iwl_write32(trans(priv), CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET); - /*********************** * 3. Read REV register ***********************/ @@ -1890,22 +1883,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, iwl_setup_rx_handlers(priv); iwl_testmode_init(priv); - /********************************************* - * 8. Enable interrupts - *********************************************/ - - iwl_enable_rfkill_int(priv); - - /* If platform's RF_KILL switch is NOT set to KILL */ - if (iwl_read32(trans(priv), - CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) - clear_bit(STATUS_RF_KILL_HW, &priv->shrd->status); - else - set_bit(STATUS_RF_KILL_HW, &priv->shrd->status); - - wiphy_rfkill_set_hw_state(priv->hw->wiphy, - test_bit(STATUS_RF_KILL_HW, &priv->shrd->status)); - iwl_power_initialize(priv); iwl_tt_initialize(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 43e894f6737..362444a7ed5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1393,6 +1393,17 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) iwl_apm_init(trans); + /* If platform's RF_KILL switch is NOT set to KILL */ + if (iwl_read32(trans, + CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW) + clear_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + else + set_bit(STATUS_RF_KILL_HW, &trans->shrd->status); + + iwl_set_hw_rfkill_state(priv(trans), + test_bit(STATUS_RF_KILL_HW, + &trans->shrd->status)); + return err; error: -- cgit v1.2.3-70-g09d2 From cf6142975bcbb731bc131ee9d2a68b7561076545 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 16:33:58 +0200 Subject: iwlwifi: consolidate the start_device flow Now there is only one transport function that launch a specific fw: trans_ops->start_fw. This one replaces trans_ops->start_device and trans_ops->kick_nic. The code that actually loads the fw to the device has been moved to the transport specific code. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 4 -- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 88 +++++++++++++++++++++--- drivers/net/wireless/iwlwifi/iwl-trans.h | 44 +++++------- drivers/net/wireless/iwlwifi/iwl-ucode.c | 87 ++--------------------- 4 files changed, 103 insertions(+), 120 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index ebea2435dac..731f287c0f3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1130,11 +1130,7 @@ void iwl_irq_tasklet(struct iwl_trans *trans) isr_stats->tx++; handled |= CSR_INT_BIT_FH_TX; /* Wake up uCode load routine, now that load is complete */ -#ifdef CONFIG_IWLWIFI_IDI - trans->shrd->trans->ucode_write_complete = 1; -#else trans->ucode_write_complete = 1; -#endif wake_up(&trans->shrd->wait_command_queue); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 362444a7ed5..1030a252405 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -64,6 +64,7 @@ #include #include #include +#include #include #include @@ -895,7 +896,79 @@ static const u8 iwlagn_pan_ac_to_queue[] = { 7, 6, 5, 4, }; -static int iwl_trans_pcie_start_device(struct iwl_trans *trans) +/* + * ucode + */ +static int iwl_load_section(struct iwl_trans *trans, const char *name, + struct fw_desc *image, u32 dst_addr) +{ + dma_addr_t phy_addr = image->p_addr; + u32 byte_cnt = image->len; + int ret; + + trans->ucode_write_complete = 0; + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); + + iwl_write_direct32(trans, + FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), + phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); + + iwl_write_direct32(trans, + FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), + (iwl_get_dma_hi_addr(phy_addr) + << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | + 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | + FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); + + iwl_write_direct32(trans, + FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | + FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | + FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); + + IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); + ret = wait_event_timeout(trans->shrd->wait_command_queue, + trans->ucode_write_complete, 5 * HZ); + if (!ret) { + IWL_ERR(trans, "Could not load the %s uCode section\n", + name); + return -ETIMEDOUT; + } + + return 0; +} + +static int iwl_load_given_ucode(struct iwl_trans *trans, struct fw_img *image) +{ + int ret = 0; + + ret = iwl_load_section(trans, "INST", &image->code, + IWLAGN_RTC_INST_LOWER_BOUND); + if (ret) + return ret; + + ret = iwl_load_section(trans, "DATA", &image->data, + IWLAGN_RTC_DATA_LOWER_BOUND); + if (ret) + return ret; + + /* Remove all resets to allow NIC to operate */ + iwl_write32(trans, CSR_RESET, 0); + + return 0; +} + +static int iwl_trans_pcie_start_fw(struct iwl_trans *trans, struct fw_img *fw) { int ret; struct iwl_trans_pcie *trans_pcie = @@ -951,6 +1024,9 @@ static int iwl_trans_pcie_start_device(struct iwl_trans *trans) iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); iwl_write32(trans, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL); + /* Load the given image to the HW */ + iwl_load_given_ucode(trans, fw); + return 0; } @@ -1353,12 +1429,6 @@ static int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, return 0; } -static void iwl_trans_pcie_kick_nic(struct iwl_trans *trans) -{ - /* Remove all resets to allow NIC to operate */ - iwl_write32(trans, CSR_RESET, 0); -} - static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) { struct iwl_trans_pcie *trans_pcie = @@ -2086,7 +2156,7 @@ const struct iwl_trans_ops trans_ops_pcie = { .start_hw = iwl_trans_pcie_start_hw, .stop_hw = iwl_trans_pcie_stop_hw, .fw_alive = iwl_trans_pcie_fw_alive, - .start_device = iwl_trans_pcie_start_device, + .start_fw = iwl_trans_pcie_start_fw, .stop_device = iwl_trans_pcie_stop_device, .wake_any_queue = iwl_trans_pcie_wake_any_queue, @@ -2100,8 +2170,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .tx_agg_alloc = iwl_trans_pcie_tx_agg_alloc, .tx_agg_setup = iwl_trans_pcie_tx_agg_setup, - .kick_nic = iwl_trans_pcie_kick_nic, - .free = iwl_trans_pcie_free, .stop_queue = iwl_trans_pcie_stop_queue, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index d0b6146b097..4d1ae65b68e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -131,13 +131,25 @@ struct iwl_host_cmd { u8 id; }; +/* one for each uCode image (inst/data, boot/init/runtime) */ +struct fw_desc { + dma_addr_t p_addr; /* hardware address */ + void *v_addr; /* software address */ + u32 len; /* size in bytes */ +}; + +struct fw_img { + struct fw_desc code; /* firmware code image */ + struct fw_desc data; /* firmware data image */ +}; + /** * struct iwl_trans_ops - transport specific operations * @start_hw: starts the HW- from that point on, the HW can send interrupts * @stop_hw: stops the HW- from that point on, the HW will be in low power but * will still issue interrupt if the HW RF kill is triggered. - * @start_device: allocates and inits all the resources for the transport - * layer. + * @start_fw: allocates and inits all the resources for the transport + * layer. Also kick a fw image. This handler may sleep. * @fw_alive: called when the fw sends alive notification * @wake_any_queue: wake all the queues of a specfic context IWL_RXON_CTX_* * @stop_device:stops the whole device (embedded CPU put to reset) @@ -148,7 +160,6 @@ struct iwl_host_cmd { * @tx_agg_setup: setup a tx queue for AMPDU - will be called once the HW is * ready and a successful ADDBA response has been received. * @tx_agg_disable: de-configure a Tx queue to send AMPDUs - * @kick_nic: remove the RESET from the embedded CPU and let it run * @free: release all the ressource for the transport layer itself such as * irq, tasklet etc... * @stop_queue: stop a specific queue @@ -166,7 +177,7 @@ struct iwl_trans_ops { int (*start_hw)(struct iwl_trans *iwl_trans); void (*stop_hw)(struct iwl_trans *iwl_trans); - int (*start_device)(struct iwl_trans *trans); + int (*start_fw)(struct iwl_trans *trans, struct fw_img *fw); void (*fw_alive)(struct iwl_trans *trans); void (*stop_device)(struct iwl_trans *trans); @@ -191,8 +202,6 @@ struct iwl_trans_ops { enum iwl_rxon_context_id ctx, int sta_id, int tid, int frame_limit, u16 ssn); - void (*kick_nic)(struct iwl_trans *trans); - void (*free)(struct iwl_trans *trans); void (*stop_queue)(struct iwl_trans *trans, int q, const char *msg); @@ -209,18 +218,6 @@ struct iwl_trans_ops { u32 (*read32)(struct iwl_trans *trans, u32 ofs); }; -/* one for each uCode image (inst/data, boot/init/runtime) */ -struct fw_desc { - dma_addr_t p_addr; /* hardware address */ - void *v_addr; /* software address */ - u32 len; /* size in bytes */ -}; - -struct fw_img { - struct fw_desc code; /* firmware code image */ - struct fw_desc data; /* firmware data image */ -}; - /* Opaque calibration results */ struct iwl_calib_result { struct list_head list; @@ -284,9 +281,11 @@ static inline void iwl_trans_fw_alive(struct iwl_trans *trans) trans->ops->fw_alive(trans); } -static inline int iwl_trans_start_device(struct iwl_trans *trans) +static inline int iwl_trans_start_fw(struct iwl_trans *trans, struct fw_img *fw) { - return trans->ops->start_device(trans); + might_sleep(); + + return trans->ops->start_fw(trans, fw); } static inline void iwl_trans_stop_device(struct iwl_trans *trans) @@ -347,11 +346,6 @@ static inline void iwl_trans_tx_agg_setup(struct iwl_trans *trans, trans->ops->tx_agg_setup(trans, ctx, sta_id, tid, frame_limit, ssn); } -static inline void iwl_trans_kick_nic(struct iwl_trans *trans) -{ - trans->ops->kick_nic(trans); -} - static inline void iwl_trans_free(struct iwl_trans *trans) { trans->ops->free(trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 793524a3ed7..87ce587d7d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -120,58 +120,6 @@ int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, return 0; } -/* - * ucode - */ -static int iwl_load_section(struct iwl_trans *trans, const char *name, - struct fw_desc *image, u32 dst_addr) -{ - dma_addr_t phy_addr = image->p_addr; - u32 byte_cnt = image->len; - int ret; - - trans->ucode_write_complete = 0; - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_PAUSE); - - iwl_write_direct32(trans, - FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr); - - iwl_write_direct32(trans, - FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), - phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); - - iwl_write_direct32(trans, - FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), - (iwl_get_dma_hi_addr(phy_addr) - << FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt); - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL), - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM | - 1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_IDX | - FH_TCSR_CHNL_TX_BUF_STS_REG_VAL_TFDB_VALID); - - iwl_write_direct32(trans, - FH_TCSR_CHNL_TX_CONFIG_REG(FH_SRVC_CHNL), - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | - FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | - FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); - - IWL_DEBUG_FW(trans, "%s uCode section being loaded...\n", name); - ret = wait_event_timeout(trans->shrd->wait_command_queue, - trans->ucode_write_complete, 5 * HZ); - if (!ret) { - IWL_ERR(trans, "Could not load the %s uCode section\n", - name); - return -ETIMEDOUT; - } - - return 0; -} - static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, enum iwl_ucode_type ucode_type) { @@ -188,28 +136,6 @@ static inline struct fw_img *iwl_get_ucode_image(struct iwl_trans *trans, return NULL; } -static int iwl_load_given_ucode(struct iwl_trans *trans, - enum iwl_ucode_type ucode_type) -{ - int ret = 0; - struct fw_img *image = iwl_get_ucode_image(trans, ucode_type); - - - if (!image) { - IWL_ERR(trans, "Invalid ucode requested (%d)\n", - ucode_type); - return -EINVAL; - } - - ret = iwl_load_section(trans, "INST", &image->code, - IWLAGN_RTC_INST_LOWER_BOUND); - if (ret) - return ret; - - return iwl_load_section(trans, "DATA", &image->data, - IWLAGN_RTC_DATA_LOWER_BOUND); -} - /* * Calibration */ @@ -646,28 +572,27 @@ int iwl_load_ucode_wait_alive(struct iwl_trans *trans, { struct iwl_notification_wait alive_wait; struct iwl_alive_data alive_data; + struct fw_img *fw; int ret; enum iwl_ucode_type old_type; - ret = iwl_trans_start_device(trans); - if (ret) - return ret; - iwl_init_notification_wait(trans->shrd, &alive_wait, REPLY_ALIVE, iwl_alive_fn, &alive_data); old_type = trans->shrd->ucode_type; trans->shrd->ucode_type = ucode_type; + fw = iwl_get_ucode_image(trans, ucode_type); - ret = iwl_load_given_ucode(trans, ucode_type); + if (!fw) + return -EINVAL; + + ret = iwl_trans_start_fw(trans, fw); if (ret) { trans->shrd->ucode_type = old_type; iwl_remove_notification(trans->shrd, &alive_wait); return ret; } - iwl_trans_kick_nic(trans); - /* * Some things may run in the background now, but we * just wait for the ALIVE notification here. -- cgit v1.2.3-70-g09d2 From af634bee8c4a15629da5e114c491acb8ee50e1e9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:12:22 +0200 Subject: iwlwifi: kill bus_apm_config This handler was called from the transport layer only. Merge it to the transport's apm_init. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 7 ---- drivers/net/wireless/iwlwifi/iwl-pci.c | 29 ---------------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 50 ++++++++++++++++++++++++--- 3 files changed, 46 insertions(+), 40 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 2065c5b7416..d385f692ef1 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -121,13 +121,11 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations * @get_pm_support: must returns true if the bus can go to sleep - * @apm_config: will be called during the config of the APM * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { bool (*get_pm_support)(struct iwl_bus *bus); - void (*apm_config)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -156,11 +154,6 @@ static inline bool bus_get_pm_support(struct iwl_bus *bus) return bus->ops->get_pm_support(bus); } -static inline void bus_apm_config(struct iwl_bus *bus) -{ - bus->ops->apm_config(bus); -} - static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 6451739aed2..353022d406e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -106,34 +106,6 @@ static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } -static void iwl_pci_apm_config(struct iwl_bus *bus) -{ - /* - * HW bug W/A for instability in PCIe bus L0S->L1 transition. - * Check if BIOS (or OS) enabled L1-ASPM on this device. - * If so (likely), disable L0S, so device moves directly L0->L1; - * costs negligible amount of power savings. - * If not (unlikely), enable L0S, so there is at least some - * power savings, even without L1. - */ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == - PCI_CFG_LINK_CTRL_VAL_L1_EN) { - /* L1-ASPM enabled; disable(!) L0S */ - iwl_set_bit(trans(bus), CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, trans(bus)->dev, - "L1 Enabled; Disabling L0S\n"); - } else { - /* L1-ASPM disabled; enable(!) L0S */ - iwl_clear_bit(trans(bus), CSR_GIO_REG, - CSR_GIO_REG_VAL_L0S_ENABLED); - dev_printk(KERN_INFO, trans(bus)->dev, - "L1 Disabled; Enabling L0S\n"); - } -} - static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { @@ -152,7 +124,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) static const struct iwl_bus_ops bus_ops_pci = { .get_pm_support = iwl_pci_is_pm_supported, - .apm_config = iwl_pci_apm_config, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 1030a252405..c9fe8889ad8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -633,6 +633,51 @@ static void iwl_set_pwr_vmain(struct iwl_trans *trans) ~APMG_PS_CTRL_MSK_PWR_SRC); } +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 +#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 +#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 + +static u16 iwl_pciexp_link_ctrl(struct iwl_trans *trans) +{ + int pos; + u16 pci_lnk_ctl; + struct iwl_trans_pcie *trans_pcie = + IWL_TRANS_GET_PCIE_TRANS(trans); + + struct pci_dev *pci_dev = trans_pcie->pci_dev; + + pos = pci_pcie_cap(pci_dev); + pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); + return pci_lnk_ctl; +} + +static void iwl_apm_config(struct iwl_trans *trans) +{ + /* + * HW bug W/A for instability in PCIe bus L0S->L1 transition. + * Check if BIOS (or OS) enabled L1-ASPM on this device. + * If so (likely), disable L0S, so device moves directly L0->L1; + * costs negligible amount of power savings. + * If not (unlikely), enable L0S, so there is at least some + * power savings, even without L1. + */ + u16 lctl = iwl_pciexp_link_ctrl(trans); + + if ((lctl & PCI_CFG_LINK_CTRL_VAL_L1_EN) == + PCI_CFG_LINK_CTRL_VAL_L1_EN) { + /* L1-ASPM enabled; disable(!) L0S */ + iwl_set_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Enabled; Disabling L0S\n"); + } else { + /* L1-ASPM disabled; enable(!) L0S */ + iwl_clear_bit(trans, CSR_GIO_REG, CSR_GIO_REG_VAL_L0S_ENABLED); + dev_printk(KERN_INFO, trans->dev, + "L1 Disabled; Enabling L0S\n"); + } +} + /* * Start up NIC's basic functionality after it has been reset * (e.g. after platform boot, or shutdown via iwl_apm_stop()) @@ -669,7 +714,7 @@ static int iwl_apm_init(struct iwl_trans *trans) iwl_set_bit(trans, CSR_HW_IF_CONFIG_REG, CSR_HW_IF_CONFIG_REG_BIT_HAP_WAKE_L1A); - bus_apm_config(bus(trans)); + iwl_apm_config(trans); /* Configure analog phase-lock-loop before activating to D0A */ if (cfg(trans)->base_params->pll_cfg_val) @@ -2187,9 +2232,6 @@ const struct iwl_trans_ops trans_ops_pcie = { .read32 = iwl_trans_pcie_read32, }; -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 - struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, struct pci_dev *pdev, const struct pci_device_id *ent) -- cgit v1.2.3-70-g09d2 From f6d0e9be6580ba607f730d7e056518c95a864601 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_is_pm_supported Get this information from the transport layer which is now in charge of the APM too. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 7 ------- drivers/net/wireless/iwlwifi/iwl-pci.c | 20 -------------------- drivers/net/wireless/iwlwifi/iwl-power.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 2 ++ 5 files changed, 4 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index d385f692ef1..2b0b48edf28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -120,12 +120,10 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations - * @get_pm_support: must returns true if the bus can go to sleep * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { - bool (*get_pm_support)(struct iwl_bus *bus); void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -149,11 +147,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline bool bus_get_pm_support(struct iwl_bus *bus) -{ - return bus->ops->get_pm_support(bus); -} - static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 353022d406e..0c16efebf93 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -87,25 +87,6 @@ struct iwl_pci_bus { #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) -static u16 iwl_pciexp_link_ctrl(struct iwl_bus *bus) -{ - int pos; - u16 pci_lnk_ctl; - - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - pos = pci_pcie_cap(pci_dev); - pci_read_config_word(pci_dev, pos + PCI_EXP_LNKCTL, &pci_lnk_ctl); - return pci_lnk_ctl; -} - -static bool iwl_pci_is_pm_supported(struct iwl_bus *bus) -{ - u16 lctl = iwl_pciexp_link_ctrl(bus); - - return !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); -} - static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], int buf_len) { @@ -123,7 +104,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) } static const struct iwl_bus_ops bus_ops_pci = { - .get_pm_support = iwl_pci_is_pm_supported, .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c index c7394ef2e49..fd008c4e41f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-power.c +++ b/drivers/net/wireless/iwlwifi/iwl-power.c @@ -436,7 +436,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force) /* initialize to default */ void iwl_power_initialize(struct iwl_priv *priv) { - priv->power_data.bus_pm = bus_get_pm_support(bus(priv)); + priv->power_data.bus_pm = trans(priv)->pm_support; priv->power_data.debug_sleep_level_override = -1; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index c9fe8889ad8..8ebb5a54441 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -676,6 +676,7 @@ static void iwl_apm_config(struct iwl_trans *trans) dev_printk(KERN_INFO, trans->dev, "L1 Disabled; Enabling L0S\n"); } + trans->pm_support = !(lctl & PCI_CFG_LINK_CTRL_VAL_L0S_EN); } /* diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 4d1ae65b68e..7f6963ffa7c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -239,6 +239,7 @@ struct iwl_calib_result { * @ucode_init: init ucode image * @ucode_wowlan: wake on wireless ucode image (optional) * @nvm_device_type: indicates OTP or eeprom + * @pm_support: set to true in start_hw if link pm is supported * @calib_results: list head for init calibration results */ struct iwl_trans { @@ -257,6 +258,7 @@ struct iwl_trans { /* eeprom related variables */ int nvm_device_type; + bool pm_support; /* init calibration results */ struct list_head calib_results; -- cgit v1.2.3-70-g09d2 From 9ca859615212deb7dd0aee26972799d1910d050f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_get_hw_id_string Get this information from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 8 -------- drivers/net/wireless/iwlwifi/iwl-core.c | 5 ++--- drivers/net/wireless/iwlwifi/iwl-pci.c | 10 ---------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 ++ drivers/net/wireless/iwlwifi/iwl-trans.h | 2 ++ 5 files changed, 6 insertions(+), 21 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 2b0b48edf28..61130895428 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -120,11 +120,9 @@ struct iwl_bus; /** * struct iwl_bus_ops - bus specific operations - * @get_hw_id_string: prints the hw_id in the provided buffer * @get_hw_id: get hw_id in u32 */ struct iwl_bus_ops { - void (*get_hw_id_string)(struct iwl_bus *bus, char buf[], int buf_len); u32 (*get_hw_id)(struct iwl_bus *bus); }; @@ -147,12 +145,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline void bus_get_hw_id_string(struct iwl_bus *bus, char buf[], - int buf_len) -{ - bus->ops->get_hw_id_string(bus, buf, buf_len); -} - static inline u32 bus_get_hw_id(struct iwl_bus *bus) { return bus->ops->get_hw_id(bus); diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 95f2c33695b..0677b3dfbfb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c @@ -203,10 +203,9 @@ int iwl_init_geos(struct iwl_priv *priv) if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) && cfg(priv)->sku & EEPROM_SKU_CAP_BAND_52GHZ) { - char buf[32]; - bus_get_hw_id_string(bus(priv), buf, sizeof(buf)); IWL_INFO(priv, "Incorrectly detected BG card as ABG. " - "Please send your %s to maintainer.\n", buf); + "Please send your %s to maintainer.\n", + trans(priv)->hw_id_str); cfg(priv)->sku &= ~EEPROM_SKU_CAP_BAND_52GHZ; } diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 0c16efebf93..15864760733 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -87,15 +87,6 @@ struct iwl_pci_bus { #define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) -static void iwl_pci_get_hw_id_string(struct iwl_bus *bus, char buf[], - int buf_len) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - snprintf(buf, buf_len, "PCI ID: 0x%04X:0x%04X", pci_dev->device, - pci_dev->subsystem_device); -} - static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) { struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); @@ -104,7 +95,6 @@ static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) } static const struct iwl_bus_ops bus_ops_pci = { - .get_hw_id_string = iwl_pci_get_hw_id_string, .get_hw_id = iwl_pci_get_hw_id, }; diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 8ebb5a54441..73ff68ac7c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), + "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); /* TODO: Move this away, not needed if not MSI */ /* enable rfkill interrupt: hw bug w/a */ diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 7f6963ffa7c..593102d89c7 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,7 @@ struct iwl_calib_result { * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device + * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image * @ucode_init: init ucode image @@ -250,6 +251,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + char hw_id_str[52]; u8 ucode_write_complete; /* the image write is complete */ struct fw_img ucode_rt; -- cgit v1.2.3-70-g09d2 From 99673ee556fce2fb973eaa571adb12663330caa9 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 8 Jan 2012 21:19:45 +0200 Subject: iwlwifi: kill bus_get_hw_id Get this information from the transport layer. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-bus.h | 14 ---------- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-pci.c | 37 +++------------------------ drivers/net/wireless/iwlwifi/iwl-testmode.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 3 +++ 6 files changed, 10 insertions(+), 49 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-bus.h b/drivers/net/wireless/iwlwifi/iwl-bus.h index 61130895428..30965e0e8ab 100644 --- a/drivers/net/wireless/iwlwifi/iwl-bus.h +++ b/drivers/net/wireless/iwlwifi/iwl-bus.h @@ -118,14 +118,6 @@ struct iwl_shared; struct iwl_bus; -/** - * struct iwl_bus_ops - bus specific operations - * @get_hw_id: get hw_id in u32 - */ -struct iwl_bus_ops { - u32 (*get_hw_id)(struct iwl_bus *bus); -}; - /** * struct iwl_bus - bus common data * @@ -137,7 +129,6 @@ struct iwl_bus_ops { * it allocates the shared data */ struct iwl_bus { - const struct iwl_bus_ops *ops; struct iwl_shared *shrd; /* pointer to bus specific struct */ @@ -145,11 +136,6 @@ struct iwl_bus { char bus_specific[0] __attribute__((__aligned__(sizeof(void *)))); }; -static inline u32 bus_get_hw_id(struct iwl_bus *bus) -{ - return bus->ops->get_hw_id(bus); -} - /***************************************************** * Bus layer registration functions ******************************************************/ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index b911837b04f..78bc1e857b0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -234,7 +234,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv, priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->bands[IEEE80211_BAND_5GHZ]; - hw->wiphy->hw_version = bus_get_hw_id(bus(priv)); + hw->wiphy->hw_version = trans(priv)->hw_id; iwl_leds_init(priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c index 15864760733..3e2fce4ce00 100644 --- a/drivers/net/wireless/iwlwifi/iwl-pci.c +++ b/drivers/net/wireless/iwlwifi/iwl-pci.c @@ -71,33 +71,6 @@ #include "iwl-csr.h" #include "iwl-cfg.h" -/* PCI registers */ -#define PCI_CFG_RETRY_TIMEOUT 0x041 -#define PCI_CFG_LINK_CTRL_VAL_L0S_EN 0x01 -#define PCI_CFG_LINK_CTRL_VAL_L1_EN 0x02 - -struct iwl_pci_bus { - /* basic pci-network driver stuff */ - struct pci_dev *pci_dev; -}; - -#define IWL_BUS_GET_PCI_BUS(_iwl_bus) \ - ((struct iwl_pci_bus *) ((_iwl_bus)->bus_specific)) - -#define IWL_BUS_GET_PCI_DEV(_iwl_bus) \ - ((IWL_BUS_GET_PCI_BUS(_iwl_bus))->pci_dev) - -static u32 iwl_pci_get_hw_id(struct iwl_bus *bus) -{ - struct pci_dev *pci_dev = IWL_BUS_GET_PCI_DEV(bus); - - return (pci_dev->device << 16) + pci_dev->subsystem_device; -} - -static const struct iwl_bus_ops bus_ops_pci = { - .get_hw_id = iwl_pci_get_hw_id, -}; - #define IWL_PCI_DEVICE(dev, subdev, cfg) \ .vendor = PCI_VENDOR_ID_INTEL, .device = (dev), \ .subvendor = PCI_ANY_ID, .subdevice = (subdev), \ @@ -283,14 +256,16 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { }; MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids); +/* PCI registers */ +#define PCI_CFG_RETRY_TIMEOUT 0x041 + static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); struct iwl_bus *bus; - struct iwl_pci_bus *pci_bus; int err; - bus = kzalloc(sizeof(*bus) + sizeof(*pci_bus), GFP_KERNEL); + bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (!bus) { dev_printk(KERN_ERR, &pdev->dev, "Couldn't allocate iwl_pci_bus"); @@ -306,13 +281,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } bus->shrd->bus = bus; - pci_bus = IWL_BUS_GET_PCI_BUS(bus); - pci_bus->pci_dev = pdev; pci_set_drvdata(pdev, bus); - bus->ops = &bus_ops_pci; - #ifdef CONFIG_IWLWIFI_IDI trans(bus) = iwl_trans_idi_alloc(bus->shrd, pdev, ent); if (trans(bus) == NULL) { diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 922d841faba..7c17b9d5217 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -536,7 +536,7 @@ static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb) break; case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: - devid = bus_get_hw_id(bus(priv)); + devid = trans(priv)->hw_id; IWL_INFO(priv, "hw version: 0x%x\n", devid); skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 73ff68ac7c4..4b711b790a9 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 593102d89c7..0359d71e554 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -234,6 +234,8 @@ struct iwl_calib_result { * @reg_lock - protect hw register access * @dev - pointer to struct device * that represents the device * @irq - the irq number for the device + * @hw_id: a u32 with the ID of the device / subdevice. + * Set during transport alloaction. * @hw_id_str: a string with info about HW ID. Set during transport allocation. * @ucode_write_complete: indicates that the ucode has been copied. * @ucode_rt: run time ucode image @@ -251,6 +253,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + u32 hw_id; char hw_id_str[52]; u8 ucode_write_complete; /* the image write is complete */ -- cgit v1.2.3-70-g09d2 From 08079a4919ca960c0f46d244cae3a6ec2c39041d Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 9 Jan 2012 16:23:00 +0200 Subject: iwlwifi: move hw_rev to transport layer The HW revision is now read by the transport layer in its allocation. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 13 ++----------- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 1 + drivers/net/wireless/iwlwifi/iwl-trans.h | 1 + 3 files changed, 4 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 14f8b750c7c..36f7adeb176 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1691,13 +1691,6 @@ static void iwl_uninit_drv(struct iwl_priv *priv) #endif } - - -static u32 iwl_hw_detect(struct iwl_priv *priv) -{ - return iwl_read32(trans(priv), CSR_HW_REV); -} - /* Size of one Rx buffer in host DRAM */ #define IWL_RX_BUF_SIZE_4K (4 * 1024) #define IWL_RX_BUF_SIZE_8K (8 * 1024) @@ -1769,7 +1762,6 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, struct iwl_priv *priv; struct ieee80211_hw *hw; u16 num_mac; - u32 hw_rev; /************************ * 1. Allocating HW data @@ -1818,9 +1810,8 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, /*********************** * 3. Read REV register ***********************/ - hw_rev = iwl_hw_detect(priv); IWL_INFO(priv, "Detected %s, REV=0x%X\n", - cfg(priv)->name, hw_rev); + cfg(priv)->name, trans(priv)->hw_rev); err = iwl_trans_start_hw(trans(priv)); if (err) @@ -1830,7 +1821,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, * 4. Read EEPROM *****************/ /* Read the EEPROM */ - err = iwl_eeprom_init(priv, hw_rev); + err = iwl_eeprom_init(priv, trans(priv)->hw_rev); /* Reset chip to save power until we load uCode during "up". */ iwl_trans_stop_hw(trans(priv)); if (err) { diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index 4b711b790a9..ed2a9216d80 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -2317,6 +2317,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct iwl_shared *shrd, trans->dev = &pdev->dev; trans->irq = pdev->irq; trans_pcie->pci_dev = pdev; + trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 0359d71e554..a305e96d82a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -253,6 +253,7 @@ struct iwl_trans { struct device *dev; unsigned int irq; + u32 hw_rev; u32 hw_id; char hw_id_str[52]; -- cgit v1.2.3-70-g09d2 From 1df06bdc6fb26d13af18c5dbb3144f13cf55de3c Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 9 Jan 2012 16:35:08 +0200 Subject: iwlwifi: stop_hw replace enable_rfkill_int This trans_ops->stop_hw leaves the RFKILL interrupt enabled, we can call that one instead of enable_rfkill_int. By that, we reduce the numbers of acceesses to the NIC from the upper layers. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-core.h | 6 ------ drivers/net/wireless/iwlwifi/iwl-mac80211.c | 7 ++++--- drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 6 ++++-- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 2 ++ 4 files changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index e74bfb7bbb2..8d60dcf6f2e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h @@ -297,12 +297,6 @@ static inline bool iwl_advanced_bt_coexist(struct iwl_priv *priv) cfg(priv)->bt_params->advanced_bt_coexist; } -static inline void iwl_enable_rfkill_int(struct iwl_priv *priv) -{ - IWL_DEBUG_ISR(priv, "Enabling rfkill interrupt\n"); - iwl_write32(trans(priv), CSR_INT_MASK, CSR_INT_BIT_RF_KILL); -} - extern bool bt_siso_mode; #endif /* __iwl_core_h__ */ diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 78bc1e857b0..7177fd76e28 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -346,9 +346,10 @@ static void iwlagn_mac_stop(struct ieee80211_hw *hw) flush_workqueue(priv->shrd->workqueue); /* User space software may expect getting rfkill changes - * even if interface is down */ - iwl_write32(trans(priv), CSR_INT, 0xFFFFFFFF); - iwl_enable_rfkill_int(priv); + * even if interface is down, trans->down will leave the RF + * kill interrupt enabled + */ + iwl_trans_stop_hw(trans(priv)); IWL_DEBUG_MAC80211(priv, "leave\n"); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 731f287c0f3..78abff00453 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1149,8 +1149,10 @@ void iwl_irq_tasklet(struct iwl_trans *trans) if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status)) iwl_enable_interrupts(trans); /* Re-enable RF_KILL if it occurred */ - else if (handled & CSR_INT_BIT_RF_KILL) - iwl_enable_rfkill_int(priv(trans)); + else if (handled & CSR_INT_BIT_RF_KILL) { + IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); + iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); + } } /****************************************************************************** diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ed2a9216d80..ec26950ebb5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1532,6 +1532,8 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans) { iwl_apm_stop(trans); + iwl_write32(trans, CSR_INT, 0xFFFFFFFF); + /* Even if we stop the HW, we still want the RF kill interrupt */ IWL_DEBUG_ISR(trans, "Enabling rfkill interrupt\n"); iwl_write32(trans, CSR_INT_MASK, CSR_INT_BIT_RF_KILL); -- cgit v1.2.3-70-g09d2 From 1dcedc8e07902b32027e4cf00dc8150774a492e2 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 19 Jan 2012 08:27:03 +0200 Subject: iwlwifi: debug print in tx_queue_set_status is more clear The message was misleading when a queue is deactivated. The fifo number is irrelevant then, so don't print it. Signed-off-by: Emmanuel Grumbach Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c index 5e095ac5076..08e0a7da48a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-tx.c @@ -431,9 +431,12 @@ void iwl_trans_tx_queue_set_status(struct iwl_trans *trans, txq->sched_retry = scd_retry; - IWL_DEBUG_TX_QUEUES(trans, "%s %s Queue %d on FIFO %d\n", - active ? "Activate" : "Deactivate", - scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + if (active) + IWL_DEBUG_TX_QUEUES(trans, "Activate %s Queue %d on FIFO %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id, tx_fifo_id); + else + IWL_DEBUG_TX_QUEUES(trans, "Deactivate %s Queue %d\n", + scd_retry ? "BA" : "AC/CMD", txq_id); } static inline int get_fifo_from_tid(struct iwl_trans_pcie *trans_pcie, -- cgit v1.2.3-70-g09d2 From 1589c5629c336dbb813accec03619940695339ec Mon Sep 17 00:00:00 2001 From: Don Fry Date: Fri, 27 Jan 2012 13:15:54 -0800 Subject: iwlwifi: clarify comment change a comment to be a little more clear Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 36f7adeb176..82f8836f304 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -1781,7 +1781,7 @@ int iwl_probe(struct iwl_bus *bus, const struct iwl_trans_ops *trans_ops, SET_IEEE80211_DEV(hw, trans(priv)->dev); - /* what debugging capabilities we have */ + /* show what debugging capabilities we have */ iwl_debug_config(priv); IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); -- cgit v1.2.3-70-g09d2 From 87272af74e98225672c9165a20b0604a7db758cf Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 25 Jan 2012 15:26:34 -0800 Subject: iwlwifi: move bcast_sta_id init to common routine There is nothing device specific in the initialization of the bcast_sta_id so move it to the common inititalization routine. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-1000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-2000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-5000.c | 4 ---- drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -- drivers/net/wireless/iwlwifi/iwl-agn.c | 1 + 5 files changed, 1 insertion(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index f7a555b9d24..8c1466c907f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c @@ -128,8 +128,6 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 87600345010..d4f5f3b8757 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c @@ -124,8 +124,6 @@ static int iwl2000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index 5245a1422a6..dc9317d0343 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c @@ -170,8 +170,6 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; @@ -199,8 +197,6 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWLAGN_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWLAGN_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 464b8878467..c36fb858a45 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c @@ -145,8 +145,6 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv) iwlagn_mod_params.num_of_queues; hw_params(priv).max_txq_num = cfg(priv)->base_params->num_of_queues; - priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; - hw_params(priv).max_data_size = IWL60_RTC_DATA_SIZE; hw_params(priv).max_inst_size = IWL60_RTC_INST_SIZE; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 82f8836f304..c41c394de2c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -513,6 +513,7 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM; priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID; priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY; + priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID; priv->contexts[IWL_RXON_CTX_BSS].exclusive_interface_modes = BIT(NL80211_IFTYPE_ADHOC); priv->contexts[IWL_RXON_CTX_BSS].interface_modes = -- cgit v1.2.3-70-g09d2 From edf38334061cb87c68cfc7fdc192c850b7e02320 Mon Sep 17 00:00:00 2001 From: Don Fry Date: Wed, 25 Jan 2012 16:18:52 -0800 Subject: iwlwifi: move all ucode routines to iwl-ucode.c The routines dealing with the ucode are spread through several files. Move them all to the same file and create a iwl-ucode.h file with the ucode file definitions. Signed-off-by: Don Fry Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-agn.c | 609 +-------------------------- drivers/net/wireless/iwlwifi/iwl-agn.h | 1 + drivers/net/wireless/iwlwifi/iwl-dev.h | 108 ----- drivers/net/wireless/iwlwifi/iwl-mac80211.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 2 - drivers/net/wireless/iwlwifi/iwl-ucode.c | 610 +++++++++++++++++++++++++++- drivers/net/wireless/iwlwifi/iwl-ucode.h | 178 ++++++++ 7 files changed, 791 insertions(+), 719 deletions(-) create mode 100644 drivers/net/wireless/iwlwifi/iwl-ucode.h (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index c41c394de2c..8837171ad55 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -42,6 +41,7 @@ #include +#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" @@ -490,7 +490,7 @@ static void iwl_bg_tx_flush(struct work_struct *work) iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); } -static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) +void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) { int i; @@ -548,611 +548,6 @@ static void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags) BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2); } -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); - -#define UCODE_EXPERIMENTAL_INDEX 100 -#define UCODE_EXPERIMENTAL_TAG "exp" - -static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) -{ - const char *name_pre = cfg(priv)->fw_name_pre; - char tag[8]; - - if (first) { -#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE - priv->fw_index = UCODE_EXPERIMENTAL_INDEX; - strcpy(tag, UCODE_EXPERIMENTAL_TAG); - } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { -#endif - priv->fw_index = cfg(priv)->ucode_api_max; - sprintf(tag, "%d", priv->fw_index); - } else { - priv->fw_index--; - sprintf(tag, "%d", priv->fw_index); - } - - if (priv->fw_index < cfg(priv)->ucode_api_min) { - IWL_ERR(priv, "no suitable firmware found!\n"); - return -ENOENT; - } - - sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); - - IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? "EXPERIMENTAL " : "", - priv->firmware_name); - - return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, - trans(priv)->dev, - GFP_KERNEL, priv, iwl_ucode_callback); -} - -struct iwlagn_firmware_pieces { - const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; - size_t inst_size, data_size, init_size, init_data_size, - wowlan_inst_size, wowlan_data_size; - - u32 build; - - u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; - u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; -}; - -static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces) -{ - struct iwl_ucode_header *ucode = (void *)ucode_raw->data; - u32 api_ver, hdr_size; - const u8 *src; - - priv->ucode_ver = le32_to_cpu(ucode->ver); - api_ver = IWL_UCODE_API(priv->ucode_ver); - - switch (api_ver) { - default: - hdr_size = 28; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = le32_to_cpu(ucode->u.v2.build); - pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); - src = ucode->u.v2.data; - break; - case 0: - case 1: - case 2: - hdr_size = 24; - if (ucode_raw->size < hdr_size) { - IWL_ERR(priv, "File size too small!\n"); - return -EINVAL; - } - pieces->build = 0; - pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); - pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); - pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); - pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); - src = ucode->u.v1.data; - break; - } - - /* Verify size of file vs. image size info in file's header */ - if (ucode_raw->size != hdr_size + pieces->inst_size + - pieces->data_size + pieces->init_size + - pieces->init_data_size) { - - IWL_ERR(priv, - "uCode file size %d does not match expected size\n", - (int)ucode_raw->size); - return -EINVAL; - } - - pieces->inst = src; - src += pieces->inst_size; - pieces->data = src; - src += pieces->data_size; - pieces->init = src; - src += pieces->init_size; - pieces->init_data = src; - src += pieces->init_data_size; - - return 0; -} - -static int iwlagn_load_firmware(struct iwl_priv *priv, - const struct firmware *ucode_raw, - struct iwlagn_firmware_pieces *pieces, - struct iwlagn_ucode_capabilities *capa) -{ - struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; - struct iwl_ucode_tlv *tlv; - size_t len = ucode_raw->size; - const u8 *data; - int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; - int tmp; - u64 alternatives; - u32 tlv_len; - enum iwl_ucode_tlv_type tlv_type; - const u8 *tlv_data; - - if (len < sizeof(*ucode)) { - IWL_ERR(priv, "uCode has invalid length: %zd\n", len); - return -EINVAL; - } - - if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { - IWL_ERR(priv, "invalid uCode magic: 0X%x\n", - le32_to_cpu(ucode->magic)); - return -EINVAL; - } - - /* - * Check which alternatives are present, and "downgrade" - * when the chosen alternative is not present, warning - * the user when that happens. Some files may not have - * any alternatives, so don't warn in that case. - */ - alternatives = le64_to_cpu(ucode->alternatives); - tmp = wanted_alternative; - if (wanted_alternative > 63) - wanted_alternative = 63; - while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) - wanted_alternative--; - if (wanted_alternative && wanted_alternative != tmp) - IWL_WARN(priv, - "uCode alternative %d not available, choosing %d\n", - tmp, wanted_alternative); - - priv->ucode_ver = le32_to_cpu(ucode->ver); - pieces->build = le32_to_cpu(ucode->build); - data = ucode->data; - - len -= sizeof(*ucode); - - while (len >= sizeof(*tlv)) { - u16 tlv_alt; - - len -= sizeof(*tlv); - tlv = (void *)data; - - tlv_len = le32_to_cpu(tlv->length); - tlv_type = le16_to_cpu(tlv->type); - tlv_alt = le16_to_cpu(tlv->alternative); - tlv_data = tlv->data; - - if (len < tlv_len) { - IWL_ERR(priv, "invalid TLV len: %zd/%u\n", - len, tlv_len); - return -EINVAL; - } - len -= ALIGN(tlv_len, 4); - data += sizeof(*tlv) + ALIGN(tlv_len, 4); - - /* - * Alternative 0 is always valid. - * - * Skip alternative TLVs that are not selected. - */ - if (tlv_alt != 0 && tlv_alt != wanted_alternative) - continue; - - switch (tlv_type) { - case IWL_UCODE_TLV_INST: - pieces->inst = tlv_data; - pieces->inst_size = tlv_len; - break; - case IWL_UCODE_TLV_DATA: - pieces->data = tlv_data; - pieces->data_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT: - pieces->init = tlv_data; - pieces->init_size = tlv_len; - break; - case IWL_UCODE_TLV_INIT_DATA: - pieces->init_data = tlv_data; - pieces->init_data_size = tlv_len; - break; - case IWL_UCODE_TLV_BOOT: - IWL_ERR(priv, "Found unexpected BOOT ucode\n"); - break; - case IWL_UCODE_TLV_PROBE_MAX_LEN: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->max_probe_length = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_PAN: - if (tlv_len) - goto invalid_tlv_len; - capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; - break; - case IWL_UCODE_TLV_FLAGS: - /* must be at least one u32 */ - if (tlv_len < sizeof(u32)) - goto invalid_tlv_len; - /* and a proper number of u32s */ - if (tlv_len % sizeof(u32)) - goto invalid_tlv_len; - /* - * This driver only reads the first u32 as - * right now no more features are defined, - * if that changes then either the driver - * will not work with the new firmware, or - * it'll not take advantage of new features. - */ - capa->flags = le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_INIT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->init_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_evtlog_size = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - pieces->inst_errlog_ptr = - le32_to_cpup((__le32 *)tlv_data); - break; - case IWL_UCODE_TLV_ENHANCE_SENS_TBL: - if (tlv_len) - goto invalid_tlv_len; - priv->enhance_sensitivity_table = true; - break; - case IWL_UCODE_TLV_WOWLAN_INST: - pieces->wowlan_inst = tlv_data; - pieces->wowlan_inst_size = tlv_len; - break; - case IWL_UCODE_TLV_WOWLAN_DATA: - pieces->wowlan_data = tlv_data; - pieces->wowlan_data_size = tlv_len; - break; - case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: - if (tlv_len != sizeof(u32)) - goto invalid_tlv_len; - capa->standard_phy_calibration_size = - le32_to_cpup((__le32 *)tlv_data); - break; - default: - IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); - break; - } - } - - if (len) { - IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); - iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); - return -EINVAL; - } - - return 0; - - invalid_tlv_len: - IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); - iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); - - return -EINVAL; -} - -/** - * iwl_ucode_callback - callback when firmware was loaded - * - * If loaded successfully, copies the firmware into buffers - * for the card to fetch (via DMA). - */ -static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) -{ - struct iwl_priv *priv = context; - struct iwl_ucode_header *ucode; - int err; - struct iwlagn_firmware_pieces pieces; - const unsigned int api_max = cfg(priv)->ucode_api_max; - unsigned int api_ok = cfg(priv)->ucode_api_ok; - const unsigned int api_min = cfg(priv)->ucode_api_min; - u32 api_ver; - char buildstr[25]; - u32 build; - struct iwlagn_ucode_capabilities ucode_capa = { - .max_probe_length = 200, - .standard_phy_calibration_size = - IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, - }; - - if (!api_ok) - api_ok = api_max; - - memset(&pieces, 0, sizeof(pieces)); - - if (!ucode_raw) { - if (priv->fw_index <= api_ok) - IWL_ERR(priv, - "request for firmware file '%s' failed.\n", - priv->firmware_name); - goto try_again; - } - - IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", - priv->firmware_name, ucode_raw->size); - - /* Make sure that we got at least the API version number */ - if (ucode_raw->size < 4) { - IWL_ERR(priv, "File size way too small!\n"); - goto try_again; - } - - /* Data from ucode file: header followed by uCode images */ - ucode = (struct iwl_ucode_header *)ucode_raw->data; - - if (ucode->ver) - err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); - else - err = iwlagn_load_firmware(priv, ucode_raw, &pieces, - &ucode_capa); - - if (err) - goto try_again; - - api_ver = IWL_UCODE_API(priv->ucode_ver); - build = pieces.build; - - /* - * api_ver should match the api version forming part of the - * firmware filename ... but we don't check for that and only rely - * on the API version read from firmware header from here on forward - */ - /* no api version check required for experimental uCode */ - if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { - if (api_ver < api_min || api_ver > api_max) { - IWL_ERR(priv, - "Driver unable to support your firmware API. " - "Driver supports v%u, firmware is v%u.\n", - api_max, api_ver); - goto try_again; - } - - if (api_ver < api_ok) { - if (api_ok != api_max) - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u through v%u, got v%u.\n", - api_ok, api_max, api_ver); - else - IWL_ERR(priv, "Firmware has old API version, " - "expected v%u, got v%u.\n", - api_max, api_ver); - IWL_ERR(priv, "New firmware can be obtained from " - "http://www.intellinuxwireless.org/.\n"); - } - } - - if (build) - sprintf(buildstr, " build %u%s", build, - (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) - ? " (EXP)" : ""); - else - buildstr[0] = '\0'; - - IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - snprintf(priv->hw->wiphy->fw_version, - sizeof(priv->hw->wiphy->fw_version), - "%u.%u.%u.%u%s", - IWL_UCODE_MAJOR(priv->ucode_ver), - IWL_UCODE_MINOR(priv->ucode_ver), - IWL_UCODE_API(priv->ucode_ver), - IWL_UCODE_SERIAL(priv->ucode_ver), - buildstr); - - /* - * For any of the failures below (before allocating pci memory) - * we will try to load a version with a smaller API -- maybe the - * user just got a corrupted version of the latest API. - */ - - IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", - priv->ucode_ver); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", - pieces.inst_size); - IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", - pieces.data_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", - pieces.init_size); - IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", - pieces.init_data_size); - - /* Verify that uCode images will fit in card's SRAM */ - if (pieces.inst_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", - pieces.inst_size); - goto try_again; - } - - if (pieces.data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", - pieces.data_size); - goto try_again; - } - - if (pieces.init_size > hw_params(priv).max_inst_size) { - IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", - pieces.init_size); - goto try_again; - } - - if (pieces.init_data_size > hw_params(priv).max_data_size) { - IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", - pieces.init_data_size); - goto try_again; - } - - /* Allocate ucode buffers for card's bus-master loading ... */ - - /* Runtime instructions and 2 copies of data: - * 1) unmodified from disk - * 2) backup cache for save/restore during power-downs */ - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, - pieces.inst, pieces.inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, - pieces.data, pieces.data_size)) - goto err_pci_alloc; - - /* Initialization instructions and data */ - if (pieces.init_size && pieces.init_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.code, - pieces.init, pieces.init_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_init.data, - pieces.init_data, pieces.init_data_size)) - goto err_pci_alloc; - } - - /* WoWLAN instructions and data */ - if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.code, - pieces.wowlan_inst, - pieces.wowlan_inst_size)) - goto err_pci_alloc; - if (iwl_alloc_fw_desc(trans(priv), - &trans(priv)->ucode_wowlan.data, - pieces.wowlan_data, - pieces.wowlan_data_size)) - goto err_pci_alloc; - } - - /* Now that we can no longer fail, copy information */ - - /* - * The (size - 16) / 12 formula is based on the information recorded - * for each event, which is of mode 1 (including timestamp) for all - * new microcodes that include this information. - */ - priv->init_evtlog_ptr = pieces.init_evtlog_ptr; - if (pieces.init_evtlog_size) - priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; - else - priv->init_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->init_errlog_ptr = pieces.init_errlog_ptr; - priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; - if (pieces.inst_evtlog_size) - priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; - else - priv->inst_evtlog_size = - cfg(priv)->base_params->max_event_log_size; - priv->inst_errlog_ptr = pieces.inst_errlog_ptr; -#ifndef CONFIG_IWLWIFI_P2P - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; -#endif - - priv->new_scan_threshold_behaviour = - !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); - - if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; - - /* - * if not PAN, then don't support P2P -- might be a uCode - * packaging bug or due to the eeprom check above - */ - if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) - ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; - - if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { - priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; - priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; - } else { - priv->sta_key_max_num = STA_KEY_MAX_NUM; - priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; - } - /* - * figure out the offset of chain noise reset and gain commands - * base on the size of standard phy calibration commands table size - */ - if (ucode_capa.standard_phy_calibration_size > - IWL_MAX_PHY_CALIBRATE_TBL_SIZE) - ucode_capa.standard_phy_calibration_size = - IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; - - priv->phy_calib_chain_noise_reset_cmd = - ucode_capa.standard_phy_calibration_size; - priv->phy_calib_chain_noise_gain_cmd = - ucode_capa.standard_phy_calibration_size + 1; - - /* initialize all valid contexts */ - iwl_init_context(priv, ucode_capa.flags); - - /************************************************** - * This is still part of probe() in a sense... - * - * 9. Setup and register with mac80211 and debugfs - **************************************************/ - err = iwlagn_mac_setup_register(priv, &ucode_capa); - if (err) - goto out_unbind; - - err = iwl_dbgfs_register(priv, DRV_NAME); - if (err) - IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); - - /* We have our copies now, allow OS release its copies */ - release_firmware(ucode_raw); - complete(&priv->firmware_loading_complete); - return; - - try_again: - /* try next, if any */ - if (iwl_request_firmware(priv, false)) - goto out_unbind; - release_firmware(ucode_raw); - return; - - err_pci_alloc: - IWL_ERR(priv, "failed to allocate pci memory\n"); - iwl_dealloc_ucode(trans(priv)); - out_unbind: - complete(&priv->firmware_loading_complete); - device_release_driver(trans(priv)->dev); - release_firmware(ucode_raw); -} - static void iwl_rf_kill_ct_config(struct iwl_priv *priv) { struct iwl_ct_kill_config cmd; diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h index 0f5133ac357..37c325ff6e8 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.h +++ b/drivers/net/wireless/iwlwifi/iwl-agn.h @@ -107,6 +107,7 @@ void iwlagn_config_ht40(struct ieee80211_conf *conf, int iwlagn_rx_calib_result(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb, struct iwl_device_cmd *cmd); +void iwl_init_context(struct iwl_priv *priv, u32 ucode_flags); /* lib */ int iwlagn_send_tx_power(struct iwl_priv *priv); diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index fff5b620927..aa99457c3a5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h @@ -292,114 +292,6 @@ struct iwl_vif_priv { u8 ibss_bssid_sta_id; }; -/* v1/v2 uCode file layout */ -struct iwl_ucode_header { - __le32 ver; /* major/minor/API/serial */ - union { - struct { - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v1; - struct { - __le32 build; /* build number */ - __le32 inst_size; /* bytes of runtime code */ - __le32 data_size; /* bytes of runtime data */ - __le32 init_size; /* bytes of init code */ - __le32 init_data_size; /* bytes of init data */ - __le32 boot_size; /* bytes of bootstrap code */ - u8 data[0]; /* in same order as sizes */ - } v2; - } u; -}; - -/* - * new TLV uCode file layout - * - * The new TLV file format contains TLVs, that each specify - * some piece of data. To facilitate "groups", for example - * different instruction image with different capabilities, - * bundled with the same init image, an alternative mechanism - * is provided: - * When the alternative field is 0, that means that the item - * is always valid. When it is non-zero, then it is only - * valid in conjunction with items of the same alternative, - * in which case the driver (user) selects one alternative - * to use. - */ - -enum iwl_ucode_tlv_type { - IWL_UCODE_TLV_INVALID = 0, /* unused */ - IWL_UCODE_TLV_INST = 1, - IWL_UCODE_TLV_DATA = 2, - IWL_UCODE_TLV_INIT = 3, - IWL_UCODE_TLV_INIT_DATA = 4, - IWL_UCODE_TLV_BOOT = 5, - IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ - IWL_UCODE_TLV_PAN = 7, - IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, - IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, - IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, - IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, - IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, - IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, - IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, - IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, - IWL_UCODE_TLV_WOWLAN_INST = 16, - IWL_UCODE_TLV_WOWLAN_DATA = 17, - IWL_UCODE_TLV_FLAGS = 18, -}; - -/** - * enum iwl_ucode_tlv_flag - ucode API flags - * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously - * was a separate TLV but moved here to save space. - * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, - * treats good CRC threshold as a boolean - * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). - * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. - */ -enum iwl_ucode_tlv_flag { - IWL_UCODE_TLV_FLAGS_PAN = BIT(0), - IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), - IWL_UCODE_TLV_FLAGS_MFP = BIT(2), - IWL_UCODE_TLV_FLAGS_P2P = BIT(3), -}; - -struct iwl_ucode_tlv { - __le16 type; /* see above */ - __le16 alternative; /* see comment */ - __le32 length; /* not including type/length fields */ - u8 data[0]; -} __packed; - -#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 - -struct iwl_tlv_ucode_header { - /* - * The TLV style ucode header is distinguished from - * the v1/v2 style header by first four bytes being - * zero, as such is an invalid combination of - * major/minor/API/serial versions. - */ - __le32 zero; - __le32 magic; - u8 human_readable[64]; - __le32 ver; /* major/minor/API/serial */ - __le32 build; - __le64 alternatives; /* bitmask of valid alternatives */ - /* - * The data contained herein has a TLV layout, - * see above for the TLV header and types. - * Note that each TLV is padded to a length - * that is a multiple of 4 for alignment. - */ - u8 data[0]; -}; - struct iwl_sensitivity_ranges { u16 min_nrg_cck; u16 max_nrg_cck; diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c index 7177fd76e28..d8025fee7e0 100644 --- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c +++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include @@ -43,6 +42,7 @@ #include +#include "iwl-ucode.h" #include "iwl-eeprom.h" #include "iwl-wifi.h" #include "iwl-dev.h" diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index a305e96d82a..ae68c51e532 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -410,8 +410,6 @@ static inline u32 iwl_trans_read32(struct iwl_trans *trans, u32 ofs) /***************************************************** * Utils functions ******************************************************/ -int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, - const void *data, size_t len); void iwl_dealloc_ucode(struct iwl_trans *trans); int iwl_send_calib_results(struct iwl_trans *trans); diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.c b/drivers/net/wireless/iwlwifi/iwl-ucode.c index 87ce587d7d5..11b659ab261 100644 --- a/drivers/net/wireless/iwlwifi/iwl-ucode.c +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.c @@ -32,7 +32,9 @@ #include #include #include +#include +#include "iwl-ucode.h" #include "iwl-wifi.h" #include "iwl-dev.h" #include "iwl-core.h" @@ -102,7 +104,7 @@ void iwl_dealloc_ucode(struct iwl_trans *trans) iwl_free_fw_img(trans, &trans->ucode_wowlan); } -int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, +static int iwl_alloc_fw_desc(struct iwl_trans *trans, struct fw_desc *desc, const void *data, size_t len) { if (!len) { @@ -680,3 +682,609 @@ int iwl_run_init_ucode(struct iwl_trans *trans) iwl_trans_stop_device(trans); return ret; } + +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context); + +#define UCODE_EXPERIMENTAL_INDEX 100 +#define UCODE_EXPERIMENTAL_TAG "exp" + +int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first) +{ + const char *name_pre = cfg(priv)->fw_name_pre; + char tag[8]; + + if (first) { +#ifdef CONFIG_IWLWIFI_DEBUG_EXPERIMENTAL_UCODE + priv->fw_index = UCODE_EXPERIMENTAL_INDEX; + strcpy(tag, UCODE_EXPERIMENTAL_TAG); + } else if (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) { +#endif + priv->fw_index = cfg(priv)->ucode_api_max; + sprintf(tag, "%d", priv->fw_index); + } else { + priv->fw_index--; + sprintf(tag, "%d", priv->fw_index); + } + + if (priv->fw_index < cfg(priv)->ucode_api_min) { + IWL_ERR(priv, "no suitable firmware found!\n"); + return -ENOENT; + } + + sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode"); + + IWL_DEBUG_INFO(priv, "attempting to load firmware %s'%s'\n", + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? "EXPERIMENTAL " : "", + priv->firmware_name); + + return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name, + trans(priv)->dev, + GFP_KERNEL, priv, iwl_ucode_callback); +} + +struct iwlagn_firmware_pieces { + const void *inst, *data, *init, *init_data, *wowlan_inst, *wowlan_data; + size_t inst_size, data_size, init_size, init_data_size, + wowlan_inst_size, wowlan_data_size; + + u32 build; + + u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr; + u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr; +}; + +static int iwlagn_load_legacy_firmware(struct iwl_priv *priv, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces) +{ + struct iwl_ucode_header *ucode = (void *)ucode_raw->data; + u32 api_ver, hdr_size; + const u8 *src; + + priv->ucode_ver = le32_to_cpu(ucode->ver); + api_ver = IWL_UCODE_API(priv->ucode_ver); + + switch (api_ver) { + default: + hdr_size = 28; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; + } + pieces->build = le32_to_cpu(ucode->u.v2.build); + pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v2.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v2.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size); + src = ucode->u.v2.data; + break; + case 0: + case 1: + case 2: + hdr_size = 24; + if (ucode_raw->size < hdr_size) { + IWL_ERR(priv, "File size too small!\n"); + return -EINVAL; + } + pieces->build = 0; + pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size); + pieces->data_size = le32_to_cpu(ucode->u.v1.data_size); + pieces->init_size = le32_to_cpu(ucode->u.v1.init_size); + pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size); + src = ucode->u.v1.data; + break; + } + + /* Verify size of file vs. image size info in file's header */ + if (ucode_raw->size != hdr_size + pieces->inst_size + + pieces->data_size + pieces->init_size + + pieces->init_data_size) { + + IWL_ERR(priv, + "uCode file size %d does not match expected size\n", + (int)ucode_raw->size); + return -EINVAL; + } + + pieces->inst = src; + src += pieces->inst_size; + pieces->data = src; + src += pieces->data_size; + pieces->init = src; + src += pieces->init_size; + pieces->init_data = src; + src += pieces->init_data_size; + + return 0; +} + +static int iwlagn_load_firmware(struct iwl_priv *priv, + const struct firmware *ucode_raw, + struct iwlagn_firmware_pieces *pieces, + struct iwlagn_ucode_capabilities *capa) +{ + struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data; + struct iwl_ucode_tlv *tlv; + size_t len = ucode_raw->size; + const u8 *data; + int wanted_alternative = iwlagn_mod_params.wanted_ucode_alternative; + int tmp; + u64 alternatives; + u32 tlv_len; + enum iwl_ucode_tlv_type tlv_type; + const u8 *tlv_data; + + if (len < sizeof(*ucode)) { + IWL_ERR(priv, "uCode has invalid length: %zd\n", len); + return -EINVAL; + } + + if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC)) { + IWL_ERR(priv, "invalid uCode magic: 0X%x\n", + le32_to_cpu(ucode->magic)); + return -EINVAL; + } + + /* + * Check which alternatives are present, and "downgrade" + * when the chosen alternative is not present, warning + * the user when that happens. Some files may not have + * any alternatives, so don't warn in that case. + */ + alternatives = le64_to_cpu(ucode->alternatives); + tmp = wanted_alternative; + if (wanted_alternative > 63) + wanted_alternative = 63; + while (wanted_alternative && !(alternatives & BIT(wanted_alternative))) + wanted_alternative--; + if (wanted_alternative && wanted_alternative != tmp) + IWL_WARN(priv, + "uCode alternative %d not available, choosing %d\n", + tmp, wanted_alternative); + + priv->ucode_ver = le32_to_cpu(ucode->ver); + pieces->build = le32_to_cpu(ucode->build); + data = ucode->data; + + len -= sizeof(*ucode); + + while (len >= sizeof(*tlv)) { + u16 tlv_alt; + + len -= sizeof(*tlv); + tlv = (void *)data; + + tlv_len = le32_to_cpu(tlv->length); + tlv_type = le16_to_cpu(tlv->type); + tlv_alt = le16_to_cpu(tlv->alternative); + tlv_data = tlv->data; + + if (len < tlv_len) { + IWL_ERR(priv, "invalid TLV len: %zd/%u\n", + len, tlv_len); + return -EINVAL; + } + len -= ALIGN(tlv_len, 4); + data += sizeof(*tlv) + ALIGN(tlv_len, 4); + + /* + * Alternative 0 is always valid. + * + * Skip alternative TLVs that are not selected. + */ + if (tlv_alt != 0 && tlv_alt != wanted_alternative) + continue; + + switch (tlv_type) { + case IWL_UCODE_TLV_INST: + pieces->inst = tlv_data; + pieces->inst_size = tlv_len; + break; + case IWL_UCODE_TLV_DATA: + pieces->data = tlv_data; + pieces->data_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT: + pieces->init = tlv_data; + pieces->init_size = tlv_len; + break; + case IWL_UCODE_TLV_INIT_DATA: + pieces->init_data = tlv_data; + pieces->init_data_size = tlv_len; + break; + case IWL_UCODE_TLV_BOOT: + IWL_ERR(priv, "Found unexpected BOOT ucode\n"); + break; + case IWL_UCODE_TLV_PROBE_MAX_LEN: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->max_probe_length = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_PAN: + if (tlv_len) + goto invalid_tlv_len; + capa->flags |= IWL_UCODE_TLV_FLAGS_PAN; + break; + case IWL_UCODE_TLV_FLAGS: + /* must be at least one u32 */ + if (tlv_len < sizeof(u32)) + goto invalid_tlv_len; + /* and a proper number of u32s */ + if (tlv_len % sizeof(u32)) + goto invalid_tlv_len; + /* + * This driver only reads the first u32 as + * right now no more features are defined, + * if that changes then either the driver + * will not work with the new firmware, or + * it'll not take advantage of new features. + */ + capa->flags = le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_INIT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->init_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_evtlog_size = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_RUNT_ERRLOG_PTR: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + pieces->inst_errlog_ptr = + le32_to_cpup((__le32 *)tlv_data); + break; + case IWL_UCODE_TLV_ENHANCE_SENS_TBL: + if (tlv_len) + goto invalid_tlv_len; + priv->enhance_sensitivity_table = true; + break; + case IWL_UCODE_TLV_WOWLAN_INST: + pieces->wowlan_inst = tlv_data; + pieces->wowlan_inst_size = tlv_len; + break; + case IWL_UCODE_TLV_WOWLAN_DATA: + pieces->wowlan_data = tlv_data; + pieces->wowlan_data_size = tlv_len; + break; + case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE: + if (tlv_len != sizeof(u32)) + goto invalid_tlv_len; + capa->standard_phy_calibration_size = + le32_to_cpup((__le32 *)tlv_data); + break; + default: + IWL_DEBUG_INFO(priv, "unknown TLV: %d\n", tlv_type); + break; + } + } + + if (len) { + IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len); + iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len); + return -EINVAL; + } + + return 0; + + invalid_tlv_len: + IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len); + iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len); + + return -EINVAL; +} + +/** + * iwl_ucode_callback - callback when firmware was loaded + * + * If loaded successfully, copies the firmware into buffers + * for the card to fetch (via DMA). + */ +static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context) +{ + struct iwl_priv *priv = context; + struct iwl_ucode_header *ucode; + int err; + struct iwlagn_firmware_pieces pieces; + const unsigned int api_max = cfg(priv)->ucode_api_max; + unsigned int api_ok = cfg(priv)->ucode_api_ok; + const unsigned int api_min = cfg(priv)->ucode_api_min; + u32 api_ver; + char buildstr[25]; + u32 build; + struct iwlagn_ucode_capabilities ucode_capa = { + .max_probe_length = 200, + .standard_phy_calibration_size = + IWL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE, + }; + + if (!api_ok) + api_ok = api_max; + + memset(&pieces, 0, sizeof(pieces)); + + if (!ucode_raw) { + if (priv->fw_index <= api_ok) + IWL_ERR(priv, + "request for firmware file '%s' failed.\n", + priv->firmware_name); + goto try_again; + } + + IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n", + priv->firmware_name, ucode_raw->size); + + /* Make sure that we got at least the API version number */ + if (ucode_raw->size < 4) { + IWL_ERR(priv, "File size way too small!\n"); + goto try_again; + } + + /* Data from ucode file: header followed by uCode images */ + ucode = (struct iwl_ucode_header *)ucode_raw->data; + + if (ucode->ver) + err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces); + else + err = iwlagn_load_firmware(priv, ucode_raw, &pieces, + &ucode_capa); + + if (err) + goto try_again; + + api_ver = IWL_UCODE_API(priv->ucode_ver); + build = pieces.build; + + /* + * api_ver should match the api version forming part of the + * firmware filename ... but we don't check for that and only rely + * on the API version read from firmware header from here on forward + */ + /* no api version check required for experimental uCode */ + if (priv->fw_index != UCODE_EXPERIMENTAL_INDEX) { + if (api_ver < api_min || api_ver > api_max) { + IWL_ERR(priv, + "Driver unable to support your firmware API. " + "Driver supports v%u, firmware is v%u.\n", + api_max, api_ver); + goto try_again; + } + + if (api_ver < api_ok) { + if (api_ok != api_max) + IWL_ERR(priv, "Firmware has old API version, " + "expected v%u through v%u, got v%u.\n", + api_ok, api_max, api_ver); + else + IWL_ERR(priv, "Firmware has old API version, " + "expected v%u, got v%u.\n", + api_max, api_ver); + IWL_ERR(priv, "New firmware can be obtained from " + "http://www.intellinuxwireless.org/.\n"); + } + } + + if (build) + sprintf(buildstr, " build %u%s", build, + (priv->fw_index == UCODE_EXPERIMENTAL_INDEX) + ? " (EXP)" : ""); + else + buildstr[0] = '\0'; + + IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver), + buildstr); + + snprintf(priv->hw->wiphy->fw_version, + sizeof(priv->hw->wiphy->fw_version), + "%u.%u.%u.%u%s", + IWL_UCODE_MAJOR(priv->ucode_ver), + IWL_UCODE_MINOR(priv->ucode_ver), + IWL_UCODE_API(priv->ucode_ver), + IWL_UCODE_SERIAL(priv->ucode_ver), + buildstr); + + /* + * For any of the failures below (before allocating pci memory) + * we will try to load a version with a smaller API -- maybe the + * user just got a corrupted version of the latest API. + */ + + IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", + priv->ucode_ver); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n", + pieces.inst_size); + IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n", + pieces.data_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n", + pieces.init_size); + IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n", + pieces.init_data_size); + + /* Verify that uCode images will fit in card's SRAM */ + if (pieces.inst_size > hw_params(priv).max_inst_size) { + IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n", + pieces.inst_size); + goto try_again; + } + + if (pieces.data_size > hw_params(priv).max_data_size) { + IWL_ERR(priv, "uCode data len %Zd too large to fit in\n", + pieces.data_size); + goto try_again; + } + + if (pieces.init_size > hw_params(priv).max_inst_size) { + IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n", + pieces.init_size); + goto try_again; + } + + if (pieces.init_data_size > hw_params(priv).max_data_size) { + IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n", + pieces.init_data_size); + goto try_again; + } + + /* Allocate ucode buffers for card's bus-master loading ... */ + + /* Runtime instructions and 2 copies of data: + * 1) unmodified from disk + * 2) backup cache for save/restore during power-downs */ + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.code, + pieces.inst, pieces.inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), &trans(priv)->ucode_rt.data, + pieces.data, pieces.data_size)) + goto err_pci_alloc; + + /* Initialization instructions and data */ + if (pieces.init_size && pieces.init_data_size) { + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.code, + pieces.init, pieces.init_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_init.data, + pieces.init_data, pieces.init_data_size)) + goto err_pci_alloc; + } + + /* WoWLAN instructions and data */ + if (pieces.wowlan_inst_size && pieces.wowlan_data_size) { + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_wowlan.code, + pieces.wowlan_inst, + pieces.wowlan_inst_size)) + goto err_pci_alloc; + if (iwl_alloc_fw_desc(trans(priv), + &trans(priv)->ucode_wowlan.data, + pieces.wowlan_data, + pieces.wowlan_data_size)) + goto err_pci_alloc; + } + + /* Now that we can no longer fail, copy information */ + + /* + * The (size - 16) / 12 formula is based on the information recorded + * for each event, which is of mode 1 (including timestamp) for all + * new microcodes that include this information. + */ + priv->init_evtlog_ptr = pieces.init_evtlog_ptr; + if (pieces.init_evtlog_size) + priv->init_evtlog_size = (pieces.init_evtlog_size - 16)/12; + else + priv->init_evtlog_size = + cfg(priv)->base_params->max_event_log_size; + priv->init_errlog_ptr = pieces.init_errlog_ptr; + priv->inst_evtlog_ptr = pieces.inst_evtlog_ptr; + if (pieces.inst_evtlog_size) + priv->inst_evtlog_size = (pieces.inst_evtlog_size - 16)/12; + else + priv->inst_evtlog_size = + cfg(priv)->base_params->max_event_log_size; + priv->inst_errlog_ptr = pieces.inst_errlog_ptr; +#ifndef CONFIG_IWLWIFI_P2P + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; +#endif + + priv->new_scan_threshold_behaviour = + !!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_NEWSCAN); + + if (!(cfg(priv)->sku & EEPROM_SKU_CAP_IPAN_ENABLE)) + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_PAN; + + /* + * if not PAN, then don't support P2P -- might be a uCode + * packaging bug or due to the eeprom check above + */ + if (!(ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN)) + ucode_capa.flags &= ~IWL_UCODE_TLV_FLAGS_P2P; + + if (ucode_capa.flags & IWL_UCODE_TLV_FLAGS_PAN) { + priv->sta_key_max_num = STA_KEY_MAX_NUM_PAN; + priv->shrd->cmd_queue = IWL_IPAN_CMD_QUEUE_NUM; + } else { + priv->sta_key_max_num = STA_KEY_MAX_NUM; + priv->shrd->cmd_queue = IWL_DEFAULT_CMD_QUEUE_NUM; + } + /* + * figure out the offset of chain noise reset and gain commands + * base on the size of standard phy calibration commands table size + */ + if (ucode_capa.standard_phy_calibration_size > + IWL_MAX_PHY_CALIBRATE_TBL_SIZE) + ucode_capa.standard_phy_calibration_size = + IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE; + + priv->phy_calib_chain_noise_reset_cmd = + ucode_capa.standard_phy_calibration_size; + priv->phy_calib_chain_noise_gain_cmd = + ucode_capa.standard_phy_calibration_size + 1; + + /* initialize all valid contexts */ + iwl_init_context(priv, ucode_capa.flags); + + /************************************************** + * This is still part of probe() in a sense... + * + * 9. Setup and register with mac80211 and debugfs + **************************************************/ + err = iwlagn_mac_setup_register(priv, &ucode_capa); + if (err) + goto out_unbind; + + err = iwl_dbgfs_register(priv, DRV_NAME); + if (err) + IWL_ERR(priv, "failed to create debugfs files. Ignoring error: %d\n", err); + + /* We have our copies now, allow OS release its copies */ + release_firmware(ucode_raw); + complete(&priv->firmware_loading_complete); + return; + + try_again: + /* try next, if any */ + if (iwl_request_firmware(priv, false)) + goto out_unbind; + release_firmware(ucode_raw); + return; + + err_pci_alloc: + IWL_ERR(priv, "failed to allocate pci memory\n"); + iwl_dealloc_ucode(trans(priv)); + out_unbind: + complete(&priv->firmware_loading_complete); + device_release_driver(trans(priv)->dev); + release_firmware(ucode_raw); +} + diff --git a/drivers/net/wireless/iwlwifi/iwl-ucode.h b/drivers/net/wireless/iwlwifi/iwl-ucode.h new file mode 100644 index 00000000000..eccf92519a8 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-ucode.h @@ -0,0 +1,178 @@ +/****************************************************************************** + * + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * GPL LICENSE SUMMARY + * + * Copyright(c) 2008 - 2012 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, + * USA + * + * The full GNU General Public License is included in this distribution + * in the file called LICENSE.GPL. + * + * Contact Information: + * Intel Linux Wireless + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + * + * BSD LICENSE + * + * Copyright(c) 2005 - 2012 Intel Corporation. All rights reserved. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef __iwl_ucode_h__ +#define __iwl_ucode_h__ + +/* v1/v2 uCode file layout */ +struct iwl_ucode_header { + __le32 ver; /* major/minor/API/serial */ + union { + struct { + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v1; + struct { + __le32 build; /* build number */ + __le32 inst_size; /* bytes of runtime code */ + __le32 data_size; /* bytes of runtime data */ + __le32 init_size; /* bytes of init code */ + __le32 init_data_size; /* bytes of init data */ + __le32 boot_size; /* bytes of bootstrap code */ + u8 data[0]; /* in same order as sizes */ + } v2; + } u; +}; + +/* + * new TLV uCode file layout + * + * The new TLV file format contains TLVs, that each specify + * some piece of data. To facilitate "groups", for example + * different instruction image with different capabilities, + * bundled with the same init image, an alternative mechanism + * is provided: + * When the alternative field is 0, that means that the item + * is always valid. When it is non-zero, then it is only + * valid in conjunction with items of the same alternative, + * in which case the driver (user) selects one alternative + * to use. + */ + +enum iwl_ucode_tlv_type { + IWL_UCODE_TLV_INVALID = 0, /* unused */ + IWL_UCODE_TLV_INST = 1, + IWL_UCODE_TLV_DATA = 2, + IWL_UCODE_TLV_INIT = 3, + IWL_UCODE_TLV_INIT_DATA = 4, + IWL_UCODE_TLV_BOOT = 5, + IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */ + IWL_UCODE_TLV_PAN = 7, + IWL_UCODE_TLV_RUNT_EVTLOG_PTR = 8, + IWL_UCODE_TLV_RUNT_EVTLOG_SIZE = 9, + IWL_UCODE_TLV_RUNT_ERRLOG_PTR = 10, + IWL_UCODE_TLV_INIT_EVTLOG_PTR = 11, + IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12, + IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13, + IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14, + IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15, + IWL_UCODE_TLV_WOWLAN_INST = 16, + IWL_UCODE_TLV_WOWLAN_DATA = 17, + IWL_UCODE_TLV_FLAGS = 18, +}; + +/** + * enum iwl_ucode_tlv_flag - ucode API flags + * @IWL_UCODE_TLV_FLAGS_PAN: This is PAN capable microcode; this previously + * was a separate TLV but moved here to save space. + * @IWL_UCODE_TLV_FLAGS_NEWSCAN: new uCode scan behaviour on hidden SSID, + * treats good CRC threshold as a boolean + * @IWL_UCODE_TLV_FLAGS_MFP: This uCode image supports MFP (802.11w). + * @IWL_UCODE_TLV_FLAGS_P2P: This uCode image supports P2P. + */ +enum iwl_ucode_tlv_flag { + IWL_UCODE_TLV_FLAGS_PAN = BIT(0), + IWL_UCODE_TLV_FLAGS_NEWSCAN = BIT(1), + IWL_UCODE_TLV_FLAGS_MFP = BIT(2), + IWL_UCODE_TLV_FLAGS_P2P = BIT(3), +}; + +struct iwl_ucode_tlv { + __le16 type; /* see above */ + __le16 alternative; /* see comment */ + __le32 length; /* not including type/length fields */ + u8 data[0]; +}; + +#define IWL_TLV_UCODE_MAGIC 0x0a4c5749 + +struct iwl_tlv_ucode_header { + /* + * The TLV style ucode header is distinguished from + * the v1/v2 style header by first four bytes being + * zero, as such is an invalid combination of + * major/minor/API/serial versions. + */ + __le32 zero; + __le32 magic; + u8 human_readable[64]; + __le32 ver; /* major/minor/API/serial */ + __le32 build; + __le64 alternatives; /* bitmask of valid alternatives */ + /* + * The data contained herein has a TLV layout, + * see above for the TLV header and types. + * Note that each TLV is padded to a length + * that is a multiple of 4 for alignment. + */ + u8 data[0]; +}; + +struct iwl_priv; + +int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first); + +#endif /* __iwl_ucode_h__ */ -- cgit v1.2.3-70-g09d2 From f057ac4ed77d3390b517ee2be8e88615b9994272 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Sun, 29 Jan 2012 18:36:01 -0800 Subject: iwlwifi: release IRQ in error path smatch correctly complains: iwl-trans-pcie.c +1528 iwl_trans_pcie_start_hw(50) warn: 'trans->irq' was not released on error Fix it. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi W Guy --- drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c index ec26950ebb5..836caf9c68b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c @@ -1504,7 +1504,7 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) err = iwl_prepare_card_hw(trans); if (err) { IWL_ERR(trans, "Error while preparing HW: %d", err); - goto error; + goto err_free_irq; } iwl_apm_init(trans); @@ -1522,6 +1522,8 @@ static int iwl_trans_pcie_start_hw(struct iwl_trans *trans) return err; +err_free_irq: + free_irq(trans->irq, trans); error: iwl_free_isr_ict(trans); tasklet_kill(&trans_pcie->irq_tasklet); -- cgit v1.2.3-70-g09d2 From 6fe7dd0db0af18a8792d8551fd19a184f39a732c Mon Sep 17 00:00:00 2001 From: Amit Beka Date: Wed, 25 Jan 2012 09:19:24 +0200 Subject: iwlwifi: range check to testmode direct reg access Added a check on the direct register access. Checks that the address is in the lower ragnge (0x0-0x2000), which belongs to CSR, HBUS and FH registers. Signed-off-by: Amit Beka Signed-off-by: Wey-Yi W Guy --- drivers/net/wireless/iwlwifi/iwl-testmode.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.c b/drivers/net/wireless/iwlwifi/iwl-testmode.c index 7c17b9d5217..df7ab332c83 100644 --- a/drivers/net/wireless/iwlwifi/iwl-testmode.c +++ b/drivers/net/wireless/iwlwifi/iwl-testmode.c @@ -79,6 +79,7 @@ #include "iwl-testmode.h" #include "iwl-trans.h" #include "iwl-bus.h" +#include "iwl-fh.h" /* The TLVs used in the gnl message policy between the kernel module and * user space application. iwl_testmode_gnl_msg_policy is to be carried @@ -288,7 +289,7 @@ static int iwl_testmode_ucode(struct ieee80211_hw *hw, struct nlattr **tb) static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) { struct iwl_priv *priv = hw->priv; - u32 ofs, val32; + u32 ofs, val32, cmd; u8 val8; struct sk_buff *skb; int status = 0; @@ -300,7 +301,20 @@ static int iwl_testmode_reg(struct ieee80211_hw *hw, struct nlattr **tb) ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]); IWL_INFO(priv, "testmode register access command offset 0x%x\n", ofs); - switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) { + /* Allow access only to FH/CSR/HBUS in direct mode. + Since we don't have the upper bounds for the CSR and HBUS segments, + we will use only the upper bound of FH for sanity check. */ + cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]); + if ((cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 || + cmd == IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8) && + (ofs >= FH_MEM_UPPER_BOUND)) { + IWL_DEBUG_INFO(priv, "offset out of segment (0x0 - 0x%x)\n", + FH_MEM_UPPER_BOUND); + return -EINVAL; + } + + switch (cmd) { case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32: val32 = iwl_read_direct32(trans(priv), ofs); IWL_INFO(priv, "32bit value to read 0x%x\n", val32); -- cgit v1.2.3-70-g09d2 From c898add51c7b5b99fcecdeaf4df2ca30949cacb6 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 11 Jan 2012 12:42:32 +0100 Subject: usb/uas: only bind if the hcd supports SG The UAS driver requires SG support by the HCD operating the device. This patch stops UAS from operating on a HCD without sg support and prints a message to let him know. The spec says: |For [USB2] backward compatibility, the device shall present [BOT] as |alternate interface zero (primary) and [UAS] as alternate interface one |(secondary). A device which does not need backward compatibility with |[BOT] shall present [UAS] as alternate interface zero. In [USB2] |systems, the [BOT] driver or an associated filter driver may need to |issue a SET INTERFACE request for alternate interface one and then allow |the [UAS] driver to load. If the user used usb_modeswitch to switch to UAS then he can go back to BOT or use a different HCD. In case UAS is the only interface then there is currently no way out. In future usb_sg_wait() should be extended to provide a non-blocking interface so it can work with the UAS driver. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e0133c9ab0b..e34c75970ed 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -621,22 +622,34 @@ static int uas_is_interface(struct usb_host_interface *intf) intf->desc.bInterfaceProtocol == USB_PR_UAS); } +static int uas_isnt_supported(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + dev_warn(&udev->dev, "The driver for the USB controller %s does not " + "support scatter-gather which is\n", + hcd->driver->description); + dev_warn(&udev->dev, "required by the UAS driver. Please try an" + "alternative USB controller if you wish to use UAS.\n"); + return -ENODEV; +} + static int uas_switch_interface(struct usb_device *udev, struct usb_interface *intf) { int i; - - if (uas_is_interface(intf->cur_altsetting)) - return 0; + int sg_supported = udev->bus->sg_tablesize != 0; for (i = 0; i < intf->num_altsetting; i++) { struct usb_host_interface *alt = &intf->altsetting[i]; - if (alt == intf->cur_altsetting) - continue; - if (uas_is_interface(alt)) + + if (uas_is_interface(alt)) { + if (!sg_supported) + return uas_isnt_supported(udev); return usb_set_interface(udev, alt->desc.bInterfaceNumber, alt->desc.bAlternateSetting); + } } return -ENODEV; -- cgit v1.2.3-70-g09d2 From 348748b0e8cccc675e2f3a1456460ffcd540e1a1 Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 11 Jan 2012 12:45:56 +0100 Subject: usb/uas: move UAS structs / defines into a header file The protocol specific structures and defines which are used by UAS are moved into a header files by this patch so it can be accessed by the UAS gadget as well. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 56 +------------------------------------------ include/linux/usb/uas.h | 61 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 55 deletions(-) create mode 100644 include/linux/usb/uas.h (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index e34c75970ed..f98ba40352c 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -23,49 +24,6 @@ #include #include -/* Common header for all IUs */ -struct iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; -}; - -enum { - IU_ID_COMMAND = 0x01, - IU_ID_STATUS = 0x03, - IU_ID_RESPONSE = 0x04, - IU_ID_TASK_MGMT = 0x05, - IU_ID_READ_READY = 0x06, - IU_ID_WRITE_READY = 0x07, -}; - -struct command_iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; - __u8 prio_attr; - __u8 rsvd5; - __u8 len; - __u8 rsvd7; - struct scsi_lun lun; - __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ -}; - -/* - * Also used for the Read Ready and Write Ready IUs since they have the - * same first four bytes - */ -struct sense_iu { - __u8 iu_id; - __u8 rsvd1; - __be16 tag; - __be16 status_qual; - __u8 status; - __u8 rsvd7[7]; - __be16 len; - __u8 sense[SCSI_SENSE_BUFFERSIZE]; -}; - /* * The r00-r01c specs define this version of the SENSE IU data structure. * It's still in use by several different firmware releases. @@ -80,18 +38,6 @@ struct sense_iu_old { __u8 sense[SCSI_SENSE_BUFFERSIZE]; }; -enum { - CMD_PIPE_ID = 1, - STATUS_PIPE_ID = 2, - DATA_IN_PIPE_ID = 3, - DATA_OUT_PIPE_ID = 4, - - UAS_SIMPLE_TAG = 0, - UAS_HEAD_TAG = 1, - UAS_ORDERED_TAG = 2, - UAS_ACA = 4, -}; - struct uas_dev_info { struct usb_interface *intf; struct usb_device *udev; diff --git a/include/linux/usb/uas.h b/include/linux/usb/uas.h new file mode 100644 index 00000000000..856be7fcbbd --- /dev/null +++ b/include/linux/usb/uas.h @@ -0,0 +1,61 @@ +#ifndef __USB_UAS_H__ +#define __USB_UAS_H__ + +#include +#include + +/* Common header for all IUs */ +struct iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; +}; + +enum { + IU_ID_COMMAND = 0x01, + IU_ID_STATUS = 0x03, + IU_ID_RESPONSE = 0x04, + IU_ID_TASK_MGMT = 0x05, + IU_ID_READ_READY = 0x06, + IU_ID_WRITE_READY = 0x07, +}; + +struct command_iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __u8 prio_attr; + __u8 rsvd5; + __u8 len; + __u8 rsvd7; + struct scsi_lun lun; + __u8 cdb[16]; /* XXX: Overflow-checking tools may misunderstand */ +}; + +/* + * Also used for the Read Ready and Write Ready IUs since they have the + * same first four bytes + */ +struct sense_iu { + __u8 iu_id; + __u8 rsvd1; + __be16 tag; + __be16 status_qual; + __u8 status; + __u8 rsvd7[7]; + __be16 len; + __u8 sense[SCSI_SENSE_BUFFERSIZE]; +}; + +enum { + CMD_PIPE_ID = 1, + STATUS_PIPE_ID = 2, + DATA_IN_PIPE_ID = 3, + DATA_OUT_PIPE_ID = 4, + + UAS_SIMPLE_TAG = 0, + UAS_HEAD_TAG = 1, + UAS_ORDERED_TAG = 2, + UAS_ACA = 4, +}; +#endif -- cgit v1.2.3-70-g09d2 From e4d8318a85779b25b880187b1b1c44e797bd7d4b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 25 Jan 2012 11:48:40 +0100 Subject: usb/uas: make sure data urb is gone if we receive status before that Just run into the following: - new disk arrived in the system - udev couldn't wait to get its hands on to to run ata_id /dev/sda - this sent the cdb 0xa1 to the device. - my UAS-gadget recevied the cdb and had no idea what to do with it. It decided to send a status URB back with sense set to invalid opcode. - the host side received it status and completed the scsi command. - the host sent another scsi with 4kib data buffer - Now I was confused why the data transfer is only 512 bytes instead of 4kib since the host is always allocating the complete transfer in one go. - Finally the system crashed while walking through the sg list. This patch adds three new flags in order to distinguish between DATA URB completed and outstanding. If we receive status before data, we cancel data and let data complete the command. This solves the problem for IN and OUT transfers but does not work for BIDI. Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Sarah Sharp --- drivers/usb/storage/uas.c | 90 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index f98ba40352c..8ec8a6e66f5 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -58,6 +58,9 @@ enum { SUBMIT_DATA_OUT_URB = (1 << 5), ALLOC_CMD_URB = (1 << 6), SUBMIT_CMD_URB = (1 << 7), + COMPLETED_DATA_IN = (1 << 8), + COMPLETED_DATA_OUT = (1 << 9), + DATA_COMPLETES_CMD = (1 << 10), }; /* Overrides scsi_pointer */ @@ -111,6 +114,7 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 16) { unsigned len = be16_to_cpup(&sense_iu->len); @@ -128,13 +132,15 @@ static void uas_sense(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - cmnd->scsi_done(cmnd); + if (!(cmdinfo->state & DATA_COMPLETES_CMD)) + cmnd->scsi_done(cmnd); } static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) { struct sense_iu_old *sense_iu = urb->transfer_buffer; struct scsi_device *sdev = cmnd->device; + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; if (urb->actual_length > 8) { unsigned len = be16_to_cpup(&sense_iu->len) - 2; @@ -152,7 +158,8 @@ static void uas_sense_old(struct urb *urb, struct scsi_cmnd *cmnd) } cmnd->result = sense_iu->status; - cmnd->scsi_done(cmnd); + if (!(cmdinfo->state & DATA_COMPLETES_CMD)) + cmnd->scsi_done(cmnd); } static void uas_xfer_data(struct urb *urb, struct scsi_cmnd *cmnd, @@ -177,6 +184,7 @@ static void uas_stat_cmplt(struct urb *urb) struct Scsi_Host *shost = urb->context; struct uas_dev_info *devinfo = (void *)shost->hostdata[0]; struct scsi_cmnd *cmnd; + struct uas_cmd_info *cmdinfo; u16 tag; int ret; @@ -202,12 +210,32 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); return; } + cmdinfo = (void *)&cmnd->SCp; switch (iu->iu_id) { case IU_ID_STATUS: if (devinfo->cmnd == cmnd) devinfo->cmnd = NULL; + if (!(cmdinfo->state & COMPLETED_DATA_IN) && + cmdinfo->data_in_urb) { + if (devinfo->use_streams) { + cmdinfo->state |= DATA_COMPLETES_CMD; + usb_unlink_urb(cmdinfo->data_in_urb); + } else { + usb_free_urb(cmdinfo->data_in_urb); + } + } + if (!(cmdinfo->state & COMPLETED_DATA_OUT) && + cmdinfo->data_out_urb) { + if (devinfo->use_streams) { + cmdinfo->state |= DATA_COMPLETES_CMD; + usb_unlink_urb(cmdinfo->data_in_urb); + } else { + usb_free_urb(cmdinfo->data_out_urb); + } + } + if (urb->actual_length < 16) devinfo->uas_sense_old = 1; if (devinfo->uas_sense_old) @@ -236,27 +264,59 @@ static void uas_stat_cmplt(struct urb *urb) dev_err(&urb->dev->dev, "failed submit status urb\n"); } -static void uas_data_cmplt(struct urb *urb) +static void uas_data_out_cmplt(struct urb *urb) +{ + struct scsi_cmnd *cmnd = urb->context; + struct scsi_data_buffer *sdb = scsi_out(cmnd); + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + + cmdinfo->state |= COMPLETED_DATA_OUT; + + sdb->resid = sdb->length - urb->actual_length; + usb_free_urb(urb); + + if (cmdinfo->state & DATA_COMPLETES_CMD) + cmnd->scsi_done(cmnd); +} + +static void uas_data_in_cmplt(struct urb *urb) { - struct scsi_data_buffer *sdb = urb->context; + struct scsi_cmnd *cmnd = urb->context; + struct scsi_data_buffer *sdb = scsi_in(cmnd); + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; + + cmdinfo->state |= COMPLETED_DATA_IN; + sdb->resid = sdb->length - urb->actual_length; usb_free_urb(urb); + + if (cmdinfo->state & DATA_COMPLETES_CMD) + cmnd->scsi_done(cmnd); } static struct urb *uas_alloc_data_urb(struct uas_dev_info *devinfo, gfp_t gfp, - unsigned int pipe, u16 stream_id, - struct scsi_data_buffer *sdb, - enum dma_data_direction dir) + unsigned int pipe, struct scsi_cmnd *cmnd, + enum dma_data_direction dir) { + struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp; struct usb_device *udev = devinfo->udev; struct urb *urb = usb_alloc_urb(0, gfp); + struct scsi_data_buffer *sdb; + usb_complete_t complete_fn; + u16 stream_id = cmdinfo->stream; if (!urb) goto out; - usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, uas_data_cmplt, - sdb); - if (devinfo->use_streams) - urb->stream_id = stream_id; + if (dir == DMA_FROM_DEVICE) { + sdb = scsi_in(cmnd); + complete_fn = uas_data_in_cmplt; + } else { + sdb = scsi_out(cmnd); + complete_fn = uas_data_out_cmplt; + } + usb_fill_bulk_urb(urb, udev, pipe, NULL, sdb->length, + complete_fn, cmnd); + urb->stream_id = stream_id; urb->num_sgs = udev->bus->sg_tablesize ? sdb->table.nents : 0; urb->sg = sdb->table.sgl; out: @@ -358,8 +418,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_IN_URB) { cmdinfo->data_in_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_in_pipe, cmdinfo->stream, - scsi_in(cmnd), DMA_FROM_DEVICE); + devinfo->data_in_pipe, cmnd, + DMA_FROM_DEVICE); if (!cmdinfo->data_in_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_IN_URB; @@ -376,8 +436,8 @@ static int uas_submit_urbs(struct scsi_cmnd *cmnd, if (cmdinfo->state & ALLOC_DATA_OUT_URB) { cmdinfo->data_out_urb = uas_alloc_data_urb(devinfo, gfp, - devinfo->data_out_pipe, cmdinfo->stream, - scsi_out(cmnd), DMA_TO_DEVICE); + devinfo->data_out_pipe, cmnd, + DMA_TO_DEVICE); if (!cmdinfo->data_out_urb) return SCSI_MLQUEUE_DEVICE_BUSY; cmdinfo->state &= ~ALLOC_DATA_OUT_URB; -- cgit v1.2.3-70-g09d2 From 66d450e84ec656ec4b774c41cd8d46b3e48d51df Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:28 +0100 Subject: TTY: provide tty_standard_install helper There are currently many cut&paste copies of what tty_driver_install_tty does when custom ->install method is not provided. Let's get rid of the copies and create a helper with this setup code. Signed-off-by: Jiri Slaby Cc: Havard Skinnemoen Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_io.c | 30 +++++++++++++++--------------- include/linux/tty.h | 2 ++ 2 files changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index fbcc1406380..44736f9e61d 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1271,6 +1271,19 @@ int tty_init_termios(struct tty_struct *tty) } EXPORT_SYMBOL_GPL(tty_init_termios); +int tty_standard_install(struct tty_driver *driver, struct tty_struct *tty) +{ + int ret = tty_init_termios(tty); + if (ret) + return ret; + + tty_driver_kref_get(driver); + tty->count++; + driver->ttys[tty->index] = tty; + return 0; +} +EXPORT_SYMBOL_GPL(tty_standard_install); + /** * tty_driver_install_tty() - install a tty entry in the driver * @driver: the driver for the tty @@ -1286,21 +1299,8 @@ EXPORT_SYMBOL_GPL(tty_init_termios); static int tty_driver_install_tty(struct tty_driver *driver, struct tty_struct *tty) { - int idx = tty->index; - int ret; - - if (driver->ops->install) { - ret = driver->ops->install(driver, tty); - return ret; - } - - if (tty_init_termios(tty) == 0) { - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - return 0; - } - return -ENOMEM; + return driver->ops->install ? driver->ops->install(driver, tty) : + tty_standard_install(driver, tty); } /** diff --git a/include/linux/tty.h b/include/linux/tty.h index d4077418820..a91ff403b3b 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -484,6 +484,8 @@ extern void deinitialize_tty_struct(struct tty_struct *tty); extern struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx); extern int tty_release(struct inode *inode, struct file *filp); extern int tty_init_termios(struct tty_struct *tty); +extern int tty_standard_install(struct tty_driver *driver, + struct tty_struct *tty); extern struct tty_struct *tty_pair_get_tty(struct tty_struct *tty); extern struct tty_struct *tty_pair_get_pty(struct tty_struct *tty); -- cgit v1.2.3-70-g09d2 From 76f82a7ab3a724791d184e74529e96ad6947a98f Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:29 +0100 Subject: USB: serial, use tty_standard_install But before that we need to reorder the calls so that we don't need to lower the reference counts if usb_autopm_get_interface fails. Signed-off-by: Jiri Slaby Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/usb-serial.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 611b206591c..1e30cc92719 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -214,15 +214,14 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) if (!try_module_get(serial->type->driver.owner)) goto error_module_get; - /* perform the standard setup */ - retval = tty_init_termios(tty); - if (retval) - goto error_init_termios; - retval = usb_autopm_get_interface(serial->interface); if (retval) goto error_get_interface; + retval = tty_standard_install(driver, tty); + if (retval) + goto error_init_termios; + mutex_unlock(&serial->disc_mutex); /* allow the driver to update the settings */ @@ -231,14 +230,11 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty) tty->driver_data = port; - /* Final install (we use the default method) */ - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; return retval; - error_get_interface: error_init_termios: + usb_autopm_put_interface(serial->interface); + error_get_interface: module_put(serial->type->driver.owner); error_module_get: error_no_port: -- cgit v1.2.3-70-g09d2 From 81f5835eae424be646753ec5a044ed4db1fcc09a Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:30 +0100 Subject: TTY: use tty_standard_install Use the helper in the rest of the tty drivers. This is a simple replacement. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/isdn/capi/capi.c | 9 +++------ drivers/misc/pti.c | 6 +----- drivers/mmc/card/sdio_uart.c | 9 +++------ drivers/tty/nozomi.c | 8 ++------ 4 files changed, 9 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c index e44933d5879..94948be5d36 100644 --- a/drivers/isdn/capi/capi.c +++ b/drivers/isdn/capi/capi.c @@ -1015,14 +1015,11 @@ capinc_tty_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct capiminor *mp = capiminor_get(idx); - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + if (ret == 0) tty->driver_data = mp; - driver->ttys[idx] = tty; - } else + else capiminor_put(mp); return ret; } diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c index 0b56e3f4357..471ff4c85cd 100644 --- a/drivers/misc/pti.c +++ b/drivers/misc/pti.c @@ -481,13 +481,9 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct pti_tty *pti_tty_data; - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; - driver->ttys[idx] = tty; - pti_tty_data = kmalloc(sizeof(struct pti_tty), GFP_KERNEL); if (pti_tty_data == NULL) return -ENOMEM; diff --git a/drivers/mmc/card/sdio_uart.c b/drivers/mmc/card/sdio_uart.c index 2c151e18c9e..bd4a67cdac3 100644 --- a/drivers/mmc/card/sdio_uart.c +++ b/drivers/mmc/card/sdio_uart.c @@ -750,15 +750,12 @@ static int sdio_uart_install(struct tty_driver *driver, struct tty_struct *tty) { int idx = tty->index; struct sdio_uart_port *port = sdio_uart_port_get(idx); - int ret = tty_init_termios(tty); + int ret = tty_standard_install(driver, tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + if (ret == 0) /* This is the ref sdio_uart_port get provided */ tty->driver_data = port; - driver->ttys[idx] = tty; - } else + else sdio_uart_port_put(port); return ret; } diff --git a/drivers/tty/nozomi.c b/drivers/tty/nozomi.c index fd347ff34d0..580da78b2d8 100644 --- a/drivers/tty/nozomi.c +++ b/drivers/tty/nozomi.c @@ -1602,13 +1602,9 @@ static int ntty_install(struct tty_driver *driver, struct tty_struct *tty) int ret; if (!port || !dc || dc->state != NOZOMI_STATE_READY) return -ENODEV; - ret = tty_init_termios(tty); - if (ret == 0) { - tty_driver_kref_get(driver); - tty->count++; + ret = tty_standard_install(driver, tty); + if (ret == 0) tty->driver_data = port; - driver->ttys[tty->index] = tty; - } return ret; } -- cgit v1.2.3-70-g09d2 From a50f724a432997321cabb6c9e665c28e34850f78 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:31 +0100 Subject: TTY: pty, remove superfluous ptm test The code looks like: if (tty->driver->subtype == PTY_TYPE_MASTER) { ... if (tty->driver == ptm_driver) But the second if is superfluous because only the ptm_driver is of PTY_TYPE_MASTER subtype. Also we can remove the #if now because devpts_pty_kill is defined as an empty function for non-CONFIG_UNIX98_PTYS configs. Signed-off-by: Jiri Slaby Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index d505837b347..ddec9f3c339 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -54,10 +54,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&tty->link->write_wait); if (tty->driver->subtype == PTY_TYPE_MASTER) { set_bit(TTY_OTHER_CLOSED, &tty->flags); -#ifdef CONFIG_UNIX98_PTYS - if (tty->driver == ptm_driver) - devpts_pty_kill(tty->link); -#endif + devpts_pty_kill(tty->link); tty_unlock(); tty_vhangup(tty->link); tty_lock(); -- cgit v1.2.3-70-g09d2 From d3bda5298aad98c7a27678bdd0dd9d008ab9e685 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 30 Jan 2012 21:14:32 +0100 Subject: TTY: get rid of BTM around devpts_* devpts operations are protected by inode mutexes and dentry refcounting. There is no need to hold BTM. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/pty.c | 6 ++---- drivers/tty/tty_io.c | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c index ddec9f3c339..39afd045f8e 100644 --- a/drivers/tty/pty.c +++ b/drivers/tty/pty.c @@ -54,8 +54,8 @@ static void pty_close(struct tty_struct *tty, struct file *filp) wake_up_interruptible(&tty->link->write_wait); if (tty->driver->subtype == PTY_TYPE_MASTER) { set_bit(TTY_OTHER_CLOSED, &tty->flags); - devpts_pty_kill(tty->link); tty_unlock(); + devpts_pty_kill(tty->link); tty_vhangup(tty->link); tty_lock(); } @@ -613,9 +613,7 @@ static int ptmx_open(struct inode *inode, struct file *filp) return retval; /* find a device that is not in use. */ - tty_lock(); index = devpts_new_index(inode); - tty_unlock(); if (index < 0) { retval = index; goto err_file; @@ -650,8 +648,8 @@ err_release: tty_release(inode, filp); return retval; out: - devpts_kill_index(inode, index); tty_unlock(); + devpts_kill_index(inode, index); err_file: tty_free_file(filp); return retval; diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 44736f9e61d..ea7ebe22a16 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1789,11 +1789,11 @@ int tty_release(struct inode *inode, struct file *filp) * the slots and preserving the termios structure. */ release_tty(tty, idx); + tty_unlock(); /* Make this pty number available for reallocation */ if (devpts) devpts_kill_index(inode, idx); - tty_unlock(); return 0; } -- cgit v1.2.3-70-g09d2 From 4f03a2c934894f30a64d397df8c7c4de129c5b30 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 27 Jan 2012 15:55:57 -0800 Subject: drivers: hv: kvp: Add/cleanup connector defines The current KVP code carries some private connector related defines. Update connector.h to have all the KVP defines. As part of this patch get rid of some unused defines. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.h | 3 --- include/linux/connector.h | 1 + tools/hv/hv_kvp_daemon.c | 4 ---- 3 files changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h index 9b765d7df83..c2c5bba25a5 100644 --- a/drivers/hv/hv_kvp.h +++ b/drivers/hv/hv_kvp.h @@ -107,9 +107,6 @@ * the KVP user-mode component. */ -#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ -#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ - enum hv_ku_op { KVP_REGISTER = 0, /* Register the user mode component */ KVP_KERNEL_GET, /* Kernel is requesting the value */ diff --git a/include/linux/connector.h b/include/linux/connector.h index 3c9c54fd569..76384074262 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -43,6 +43,7 @@ #define CN_IDX_DRBD 0x8 #define CN_VAL_DRBD 0x1 #define CN_KVP_IDX 0x9 /* HyperV KVP */ +#define CN_KVP_VAL 0x1 /* queries from the kernel */ #define CN_NETLINK_USERS 10 /* Highest index + 1 */ diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 11224eddcdc..2b6a2d950b8 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c @@ -40,15 +40,11 @@ #include /* - * KYS: TODO. Need to register these in the kernel. * * The following definitions are shared with the in-kernel component; do not * change any of this without making the corresponding changes in * the KVP kernel component. */ -#define CN_KVP_IDX 0x9 /* MSFT KVP functionality */ -#define CN_KVP_VAL 0x1 /* This supports queries from the kernel */ -#define CN_KVP_USER_VAL 0x2 /* This supports queries from the user */ /* * KVP protocol: The user mode component first registers with the -- cgit v1.2.3-70-g09d2 From 2939437ce8f2de07237eb2bcce29b6a699bfe799 Mon Sep 17 00:00:00 2001 From: "K. Y. Srinivasan" Date: Fri, 27 Jan 2012 15:55:58 -0800 Subject: drivers: hv: kvp: Move the contents of hv_kvp.h to hyperv.h In preparation for consolidating all KVP related defines into a single header file that both the kernel and user level components can use, move the contents of hv_kvp.h into hyperv.h. Signed-off-by: K. Y. Srinivasan Signed-off-by: Haiyang Zhang Signed-off-by: Greg Kroah-Hartman --- drivers/hv/hv_kvp.c | 2 - drivers/hv/hv_kvp.h | 181 ------------------------------------------------- drivers/hv/hv_util.c | 3 - include/linux/hyperv.h | 165 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 186 deletions(-) delete mode 100644 drivers/hv/hv_kvp.h (limited to 'drivers') diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 0e8343f585b..4a6971e1353 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c @@ -28,8 +28,6 @@ #include #include -#include "hv_kvp.h" - /* diff --git a/drivers/hv/hv_kvp.h b/drivers/hv/hv_kvp.h deleted file mode 100644 index c2c5bba25a5..00000000000 --- a/drivers/hv/hv_kvp.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * An implementation of HyperV key value pair (KVP) functionality for Linux. - * - * - * Copyright (C) 2010, Novell, Inc. - * Author : K. Y. Srinivasan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - */ -#ifndef _KVP_H -#define _KVP_H_ - -/* - * Maximum value size - used for both key names and value data, and includes - * any applicable NULL terminators. - * - * Note: This limit is somewhat arbitrary, but falls easily within what is - * supported for all native guests (back to Win 2000) and what is reasonable - * for the IC KVP exchange functionality. Note that Windows Me/98/95 are - * limited to 255 character key names. - * - * MSDN recommends not storing data values larger than 2048 bytes in the - * registry. - * - * Note: This value is used in defining the KVP exchange message - this value - * cannot be modified without affecting the message size and compatibility. - */ - -/* - * bytes, including any null terminators - */ -#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) - - -/* - * Maximum key size - the registry limit for the length of an entry name - * is 256 characters, including the null terminator - */ - -#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) - -/* - * In Linux, we implement the KVP functionality in two components: - * 1) The kernel component which is packaged as part of the hv_utils driver - * is responsible for communicating with the host and responsible for - * implementing the host/guest protocol. 2) A user level daemon that is - * responsible for data gathering. - * - * Host/Guest Protocol: The host iterates over an index and expects the guest - * to assign a key name to the index and also return the value corresponding to - * the key. The host will have atmost one KVP transaction outstanding at any - * given point in time. The host side iteration stops when the guest returns - * an error. Microsoft has specified the following mapping of key names to - * host specified index: - * - * Index Key Name - * 0 FullyQualifiedDomainName - * 1 IntegrationServicesVersion - * 2 NetworkAddressIPv4 - * 3 NetworkAddressIPv6 - * 4 OSBuildNumber - * 5 OSName - * 6 OSMajorVersion - * 7 OSMinorVersion - * 8 OSVersion - * 9 ProcessorArchitecture - * - * The Windows host expects the Key Name and Key Value to be encoded in utf16. - * - * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the - * data gathering functionality in a user mode daemon. The user level daemon - * is also responsible for binding the key name to the index as well. The - * kernel and user-level daemon communicate using a connector channel. - * - * The user mode component first registers with the - * the kernel component. Subsequently, the kernel component requests, data - * for the specified keys. In response to this message the user mode component - * fills in the value corresponding to the specified key. We overload the - * sequence field in the cn_msg header to define our KVP message types. - * - * - * The kernel component simply acts as a conduit for communication between the - * Windows host and the user-level daemon. The kernel component passes up the - * index received from the Host to the user-level daemon. If the index is - * valid (supported), the corresponding key as well as its - * value (both are strings) is returned. If the index is invalid - * (not supported), a NULL key string is returned. - */ - -/* - * - * The following definitions are shared with the user-mode component; do not - * change any of this without making the corresponding changes in - * the KVP user-mode component. - */ - -enum hv_ku_op { - KVP_REGISTER = 0, /* Register the user mode component */ - KVP_KERNEL_GET, /* Kernel is requesting the value */ - KVP_KERNEL_SET, /* Kernel is providing the value */ - KVP_USER_GET, /* User is requesting the value */ - KVP_USER_SET /* User is providing the value */ -}; - -struct hv_ku_msg { - __u32 kvp_index; /* Key index */ - __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ - __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ -}; - - - - -#ifdef __KERNEL__ - -/* - * Registry value types. - */ - -#define REG_SZ 1 - -enum hv_kvp_exchg_op { - KVP_OP_GET = 0, - KVP_OP_SET, - KVP_OP_DELETE, - KVP_OP_ENUMERATE, - KVP_OP_COUNT /* Number of operations, must be last. */ -}; - -enum hv_kvp_exchg_pool { - KVP_POOL_EXTERNAL = 0, - KVP_POOL_GUEST, - KVP_POOL_AUTO, - KVP_POOL_AUTO_EXTERNAL, - KVP_POOL_AUTO_INTERNAL, - KVP_POOL_COUNT /* Number of pools, must be last. */ -}; - -struct hv_kvp_hdr { - u8 operation; - u8 pool; -}; - -struct hv_kvp_exchg_msg_value { - u32 value_type; - u32 key_size; - u32 value_size; - u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; - u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; -}; - -struct hv_kvp_msg_enumerate { - u32 index; - struct hv_kvp_exchg_msg_value data; -}; - -struct hv_kvp_msg { - struct hv_kvp_hdr kvp_hdr; - struct hv_kvp_msg_enumerate kvp_data; -}; - -int hv_kvp_init(struct hv_util_service *); -void hv_kvp_deinit(void); -void hv_kvp_onchannelcallback(void *); - -#endif /* __KERNEL__ */ -#endif /* _KVP_H */ - diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c index 55d58f21e6d..dbb8b8eec21 100644 --- a/drivers/hv/hv_util.c +++ b/drivers/hv/hv_util.c @@ -28,9 +28,6 @@ #include #include -#include "hv_kvp.h" - - static void shutdown_onchannelcallback(void *context); static struct hv_util_service util_shutdown = { .util_cb = shutdown_onchannelcallback, diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 62b908e0e59..7332b3faecc 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -25,6 +25,166 @@ #ifndef _HYPERV_H #define _HYPERV_H +#include + +/* + * An implementation of HyperV key value pair (KVP) functionality for Linux. + * + * + * Copyright (C) 2010, Novell, Inc. + * Author : K. Y. Srinivasan + * + */ + +/* + * Maximum value size - used for both key names and value data, and includes + * any applicable NULL terminators. + * + * Note: This limit is somewhat arbitrary, but falls easily within what is + * supported for all native guests (back to Win 2000) and what is reasonable + * for the IC KVP exchange functionality. Note that Windows Me/98/95 are + * limited to 255 character key names. + * + * MSDN recommends not storing data values larger than 2048 bytes in the + * registry. + * + * Note: This value is used in defining the KVP exchange message - this value + * cannot be modified without affecting the message size and compatibility. + */ + +/* + * bytes, including any null terminators + */ +#define HV_KVP_EXCHANGE_MAX_VALUE_SIZE (2048) + + +/* + * Maximum key size - the registry limit for the length of an entry name + * is 256 characters, including the null terminator + */ + +#define HV_KVP_EXCHANGE_MAX_KEY_SIZE (512) + +/* + * In Linux, we implement the KVP functionality in two components: + * 1) The kernel component which is packaged as part of the hv_utils driver + * is responsible for communicating with the host and responsible for + * implementing the host/guest protocol. 2) A user level daemon that is + * responsible for data gathering. + * + * Host/Guest Protocol: The host iterates over an index and expects the guest + * to assign a key name to the index and also return the value corresponding to + * the key. The host will have atmost one KVP transaction outstanding at any + * given point in time. The host side iteration stops when the guest returns + * an error. Microsoft has specified the following mapping of key names to + * host specified index: + * + * Index Key Name + * 0 FullyQualifiedDomainName + * 1 IntegrationServicesVersion + * 2 NetworkAddressIPv4 + * 3 NetworkAddressIPv6 + * 4 OSBuildNumber + * 5 OSName + * 6 OSMajorVersion + * 7 OSMinorVersion + * 8 OSVersion + * 9 ProcessorArchitecture + * + * The Windows host expects the Key Name and Key Value to be encoded in utf16. + * + * Guest Kernel/KVP Daemon Protocol: As noted earlier, we implement all of the + * data gathering functionality in a user mode daemon. The user level daemon + * is also responsible for binding the key name to the index as well. The + * kernel and user-level daemon communicate using a connector channel. + * + * The user mode component first registers with the + * the kernel component. Subsequently, the kernel component requests, data + * for the specified keys. In response to this message the user mode component + * fills in the value corresponding to the specified key. We overload the + * sequence field in the cn_msg header to define our KVP message types. + * + * + * The kernel component simply acts as a conduit for communication between the + * Windows host and the user-level daemon. The kernel component passes up the + * index received from the Host to the user-level daemon. If the index is + * valid (supported), the corresponding key as well as its + * value (both are strings) is returned. If the index is invalid + * (not supported), a NULL key string is returned. + */ + +/* + * + * The following definitions are shared with the user-mode component; do not + * change any of this without making the corresponding changes in + * the KVP user-mode component. + */ + +enum hv_ku_op { + KVP_REGISTER = 0, /* Register the user mode component */ + KVP_KERNEL_GET, /* Kernel is requesting the value */ + KVP_KERNEL_SET, /* Kernel is providing the value */ + KVP_USER_GET, /* User is requesting the value */ + KVP_USER_SET /* User is providing the value */ +}; + +struct hv_ku_msg { + __u32 kvp_index; /* Key index */ + __u8 kvp_key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; /* Key name */ + __u8 kvp_value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; /* Key value */ +}; + + + + +#ifdef __KERNEL__ + +/* + * Registry value types. + */ + +#define REG_SZ 1 + +enum hv_kvp_exchg_op { + KVP_OP_GET = 0, + KVP_OP_SET, + KVP_OP_DELETE, + KVP_OP_ENUMERATE, + KVP_OP_COUNT /* Number of operations, must be last. */ +}; + +enum hv_kvp_exchg_pool { + KVP_POOL_EXTERNAL = 0, + KVP_POOL_GUEST, + KVP_POOL_AUTO, + KVP_POOL_AUTO_EXTERNAL, + KVP_POOL_AUTO_INTERNAL, + KVP_POOL_COUNT /* Number of pools, must be last. */ +}; + +struct hv_kvp_hdr { + u8 operation; + u8 pool; +}; + +struct hv_kvp_exchg_msg_value { + u32 value_type; + u32 key_size; + u32 value_size; + u8 key[HV_KVP_EXCHANGE_MAX_KEY_SIZE]; + u8 value[HV_KVP_EXCHANGE_MAX_VALUE_SIZE]; +}; + +struct hv_kvp_msg_enumerate { + u32 index; + struct hv_kvp_exchg_msg_value data; +}; + +struct hv_kvp_msg { + struct hv_kvp_hdr kvp_hdr; + struct hv_kvp_msg_enumerate kvp_data; +}; + #include #include #include @@ -870,4 +1030,9 @@ struct hyperv_service_callback { extern void vmbus_prep_negotiate_resp(struct icmsg_hdr *, struct icmsg_negotiate *, u8 *); +int hv_kvp_init(struct hv_util_service *); +void hv_kvp_deinit(void); +void hv_kvp_onchannelcallback(void *); + +#endif /* __KERNEL__ */ #endif /* _HYPERV_H */ -- cgit v1.2.3-70-g09d2 From b3012e12cdc5825f93367cc6294419e7ab1f00cc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 30 Jan 2012 14:47:28 +0000 Subject: cpufreq/gx: Fix the compile error Someone forgot to test this one it seems. Signed-off-by: Alan Cox Acked-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/cpufreq/gx-suspmod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/gx-suspmod.c b/drivers/cpufreq/gx-suspmod.c index 5a06c0ba245..456bee058fe 100644 --- a/drivers/cpufreq/gx-suspmod.c +++ b/drivers/cpufreq/gx-suspmod.c @@ -172,7 +172,7 @@ static struct pci_device_id gx_chipset_tbl[] __initdata = { { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), }, { 0, }, }; -MODULE_DEVICE_TABLE(gx_chipset_tbl); +MODULE_DEVICE_TABLE(pci, gx_chipset_tbl); static void gx_write_byte(int reg, int value) { -- cgit v1.2.3-70-g09d2 From 0cb54a3e47cb4baf0bc7463f0a64cfeae5e35697 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Feb 2012 15:38:14 -0500 Subject: USB: debugging code shouldn't alter control flow People have complained that debugging code shouldn't alter the flow of control; it should restrict itself to printing out warnings and error messages. Bowing to popular opinion, this patch (as1518) changes the debugging checks in usb_submit_urb() to follow this guideline. Signed-off-by: Alan Stern Reported-by: Keith Packard CC: Pavel Machek Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/urb.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 909625b91eb..f4f20c7b776 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c @@ -403,20 +403,17 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) * cause problems in HCDs if they get it wrong. */ { - unsigned int orig_flags = urb->transfer_flags; unsigned int allowed; static int pipetypes[4] = { PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT }; /* Check that the pipe's type matches the endpoint's type */ - if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) { - dev_err(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", + if (usb_pipetype(urb->pipe) != pipetypes[xfertype]) + dev_WARN(&dev->dev, "BOGUS urb xfer, pipe %x != type %x\n", usb_pipetype(urb->pipe), pipetypes[xfertype]); - return -EPIPE; /* The most suitable error code :-) */ - } - /* enforce simple/standard policy */ + /* Check against a simple/standard policy */ allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER); switch (xfertype) { @@ -435,14 +432,12 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) allowed |= URB_ISO_ASAP; break; } - urb->transfer_flags &= allowed; + allowed &= urb->transfer_flags; - /* fail if submitter gave bogus flags */ - if (urb->transfer_flags != orig_flags) { - dev_err(&dev->dev, "BOGUS urb flags, %x --> %x\n", - orig_flags, urb->transfer_flags); - return -EINVAL; - } + /* warn if submitter gave bogus flags */ + if (allowed != urb->transfer_flags) + dev_WARN(&dev->dev, "BOGUS urb flags, %x --> %x\n", + urb->transfer_flags, allowed); } #endif /* -- cgit v1.2.3-70-g09d2 From f84cbda06f79f05b748707b33b925b50c2fedc84 Mon Sep 17 00:00:00 2001 From: Sebastian Haas Date: Thu, 22 Dec 2011 23:57:49 +0100 Subject: can: ems_usb: Removed double netif_device_detach netif_device_attched is called twice when ems_usb_start fails with -ENODEV Signed-off-by: Sebastian Haas Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/ems_usb.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9697c14b8dc..7dae64d44e8 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -627,9 +627,6 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - usb_unanchor_urb(urb); usb_free_coherent(dev->udev, RX_BUFFER_SIZE, buf, urb->transfer_dma); @@ -659,9 +656,6 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { - if (err == -ENODEV) - netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", err); @@ -692,9 +686,6 @@ static int ems_usb_start(struct ems_usb *dev) return 0; failed: - if (err == -ENODEV) - netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); return err; -- cgit v1.2.3-70-g09d2 From cf5046b309b3a05c444a8edba6b44108510b7d7d Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Mon, 10 Oct 2011 23:43:53 +0200 Subject: can: dev: let can_get_echo_skb() return dlc of CAN frame can_get_echo_skb() is usually called in the TX complete handler. The stats->tx_packets and stats->tx_bytes should be updated there, too. This patch simplifies to figure out the size of the sent CAN frame. Signed-off-by: Marc Kleine-Budde --- drivers/net/can/dev.c | 10 +++++++++- include/linux/can/dev.h | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 120f1ab5a2c..9d9799cf68c 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -327,16 +327,24 @@ EXPORT_SYMBOL_GPL(can_put_echo_skb); * is handled in the device driver. The driver must protect * access to priv->echo_skb, if necessary. */ -void can_get_echo_skb(struct net_device *dev, unsigned int idx) +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx) { struct can_priv *priv = netdev_priv(dev); BUG_ON(idx >= priv->echo_skb_max); if (priv->echo_skb[idx]) { + struct sk_buff *skb = priv->echo_skb[idx]; + struct can_frame *cf = (struct can_frame *)skb->data; + u8 dlc = cf->can_dlc; + netif_rx(priv->echo_skb[idx]); priv->echo_skb[idx] = NULL; + + return dlc; } + + return 0; } EXPORT_SYMBOL_GPL(can_get_echo_skb); diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h index a0969fcb72b..5d2efe7e3f1 100644 --- a/include/linux/can/dev.h +++ b/include/linux/can/dev.h @@ -92,7 +92,7 @@ void can_bus_off(struct net_device *dev); void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, unsigned int idx); -void can_get_echo_skb(struct net_device *dev, unsigned int idx); +unsigned int can_get_echo_skb(struct net_device *dev, unsigned int idx); void can_free_echo_skb(struct net_device *dev, unsigned int idx); struct sk_buff *alloc_can_skb(struct net_device *dev, struct can_frame **cf); -- cgit v1.2.3-70-g09d2 From 9a12349663061d25b49e6542d005fa7193a2cb44 Mon Sep 17 00:00:00 2001 From: Reuben Dowle Date: Tue, 1 Nov 2011 11:18:03 +1300 Subject: can: flexcan: Fix CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK Currently the flexcan driver uses hardware local echo. This blindly echos all transmitted frames to all receiving sockets, regardless what CAN_RAW_RECV_OWN_MSGS and CAN_RAW_LOOPBACK are set to. This patch now submits transmitted frames to be echoed in the transmit complete interrupt, preserving the reference to the sending socket. This allows the can protocol to correctly handle the local echo. Further this patch moves tx_bytes statistic accounting into the tx_complete handler. Signed-off-by: Reuben Dowle [mkl: move tx_bytes accounting into tx_complete handler; cleanups] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/flexcan.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index 7fd8089946f..ab0136f49f4 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -269,7 +269,6 @@ static int flexcan_get_berr_counter(const struct net_device *dev, static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) { const struct flexcan_priv *priv = netdev_priv(dev); - struct net_device_stats *stats = &dev->stats; struct flexcan_regs __iomem *regs = priv->base; struct can_frame *cf = (struct can_frame *)skb->data; u32 can_id; @@ -299,14 +298,11 @@ static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) flexcan_write(data, ®s->cantxfg[FLEXCAN_TX_BUF_ID].data[1]); } + can_put_echo_skb(skb, dev, 0); + flexcan_write(can_id, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_id); flexcan_write(ctrl, ®s->cantxfg[FLEXCAN_TX_BUF_ID].can_ctrl); - kfree_skb(skb); - - /* tx_packets is incremented in flexcan_irq */ - stats->tx_bytes += cf->can_dlc; - return NETDEV_TX_OK; } @@ -609,7 +605,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) /* transmission complete interrupt */ if (reg_iflag1 & (1 << FLEXCAN_TX_BUF_ID)) { - /* tx_bytes is incremented in flexcan_start_xmit */ + stats->tx_bytes += can_get_echo_skb(dev, 0); stats->tx_packets++; flexcan_write((1 << FLEXCAN_TX_BUF_ID), ®s->iflag1); netif_wake_queue(dev); @@ -697,12 +693,13 @@ static int flexcan_chip_start(struct net_device *dev) * only supervisor access * enable warning int * choose format C + * disable local echo * */ reg_mcr = flexcan_read(®s->mcr); reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | - FLEXCAN_MCR_IDAM_C; + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); flexcan_write(reg_mcr, ®s->mcr); @@ -970,7 +967,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) goto failed_map; } - dev = alloc_candev(sizeof(struct flexcan_priv), 0); + dev = alloc_candev(sizeof(struct flexcan_priv), 1); if (!dev) { err = -ENOMEM; goto failed_alloc; @@ -978,7 +975,7 @@ static int __devinit flexcan_probe(struct platform_device *pdev) dev->netdev_ops = &flexcan_netdev_ops; dev->irq = irq; - dev->flags |= IFF_ECHO; /* we support local echo in hardware */ + dev->flags |= IFF_ECHO; priv = netdev_priv(dev); priv->can.clock.freq = clock_freq; -- cgit v1.2.3-70-g09d2 From 2ee6850ca0cac95101d2a36c8b186b40d4fc7311 Mon Sep 17 00:00:00 2001 From: Sebastian Haas Date: Thu, 22 Dec 2011 23:58:34 +0100 Subject: can: ems_usb: Improved memory handling on ems_usb_start Do not return from ems_usb_start if allocation fails. If not all URBs could be allocated use the one already submitted. Signed-off-by: Sebastian Haas Signed-off-by: Marc Kleine-Budde --- drivers/net/can/usb/ems_usb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 7dae64d44e8..9783e02fbc2 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -607,7 +607,8 @@ static int ems_usb_start(struct ems_usb *dev) if (!urb) { dev_err(netdev->dev.parent, "No memory left for URBs\n"); - return -ENOMEM; + err = -ENOMEM; + break; } buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, @@ -616,7 +617,8 @@ static int ems_usb_start(struct ems_usb *dev) dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); usb_free_urb(urb); - return -ENOMEM; + err = -ENOMEM; + break; } usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), -- cgit v1.2.3-70-g09d2 From e08534b57e79fa722e3136b79868a725a8eea0f0 Mon Sep 17 00:00:00 2001 From: James Kime Date: Mon, 12 Dec 2011 13:45:58 +0100 Subject: can: plx_pci: add support for IXXAT PCI cards This patch adds support for IXXAT passive CAN controllers Signed-off-by: James Kime Acked-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/sja1000/Kconfig | 1 + drivers/net/can/sja1000/plx_pci.c | 22 +++++++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/sja1000/Kconfig b/drivers/net/can/sja1000/Kconfig index 36e9d594069..b21523ddff3 100644 --- a/drivers/net/can/sja1000/Kconfig +++ b/drivers/net/can/sja1000/Kconfig @@ -71,6 +71,7 @@ config CAN_PLX_PCI - esd CAN-PCIe/2000 - Marathon CAN-bus-PCI card (http://www.marathon.ru/) - TEWS TECHNOLOGIES TPMC810 card (http://www.tews.com/) + - IXXAT Automation PC-I 04/PCI card (http://www.ixxat.com/) config CAN_TSCAN1 tristate "TS-CAN1 PC104 boards" diff --git a/drivers/net/can/sja1000/plx_pci.c b/drivers/net/can/sja1000/plx_pci.c index c7f3d4ea116..a227586ddd5 100644 --- a/drivers/net/can/sja1000/plx_pci.c +++ b/drivers/net/can/sja1000/plx_pci.c @@ -43,7 +43,8 @@ MODULE_SUPPORTED_DEVICE("Adlink PCI-7841/cPCI-7841, " "TEWS TECHNOLOGIES TPMC810, " "esd CAN-PCI/CPCI/PCI104/200, " "esd CAN-PCI/PMC/266, " - "esd CAN-PCIe/2000") + "esd CAN-PCIe/2000, " + "IXXAT PC-I 04/PCI") MODULE_LICENSE("GPL v2"); #define PLX_PCI_MAX_CHAN 2 @@ -121,6 +122,10 @@ struct plx_pci_card { #define ESD_PCI_SUB_SYS_ID_PCIE2000 0x0200 #define ESD_PCI_SUB_SYS_ID_PCI104200 0x0501 +#define IXXAT_PCI_VENDOR_ID 0x10b5 +#define IXXAT_PCI_DEVICE_ID 0x9050 +#define IXXAT_PCI_SUB_SYS_ID 0x2540 + #define MARATHON_PCI_DEVICE_ID 0x2715 #define TEWS_PCI_VENDOR_ID 0x1498 @@ -193,6 +198,14 @@ static struct plx_pci_card_info plx_pci_card_info_esd2000 __devinitdata = { /* based on PEX8311 */ }; +static struct plx_pci_card_info plx_pci_card_info_ixxat __devinitdata = { + "IXXAT PC-I 04/PCI", 2, + PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, + {0, 0x00, 0x00}, { {2, 0x00, 0x80}, {2, 0x200, 0x80} }, + &plx_pci_reset_common + /* based on PLX9050 */ +}; + static struct plx_pci_card_info plx_pci_card_info_marathon __devinitdata = { "Marathon CAN-bus-PCI", 2, PLX_PCI_CAN_CLOCK, PLX_PCI_OCR, PLX_PCI_CDR, @@ -266,6 +279,13 @@ static DEFINE_PCI_DEVICE_TABLE(plx_pci_tbl) = { 0, 0, (kernel_ulong_t)&plx_pci_card_info_esd2000 }, + { + /* IXXAT PC-I 04/PCI card */ + IXXAT_PCI_VENDOR_ID, IXXAT_PCI_DEVICE_ID, + PCI_ANY_ID, IXXAT_PCI_SUB_SYS_ID, + 0, 0, + (kernel_ulong_t)&plx_pci_card_info_ixxat + }, { /* Marathon CAN-bus-PCI card */ PCI_VENDOR_ID_PLX, MARATHON_PCI_DEVICE_ID, -- cgit v1.2.3-70-g09d2 From 74b5127884d76ccbf4f445f650f9e969ccb4a374 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 27 Jan 2012 20:05:21 +0900 Subject: can: pch_can: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor On October 1 in 2011, OKI SEMICONDUCTOR Co., Ltd. changed the company name in to LAPIS Semiconductor Signed-off-by: Tomoya MORINAGA Signed-off-by: Marc Kleine-Budde --- drivers/net/can/pch_can.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/pch_can.c b/drivers/net/can/pch_can.c index d11fbb2b95f..cc3ed57b6b1 100644 --- a/drivers/net/can/pch_can.c +++ b/drivers/net/can/pch_can.c @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 - 2010 Intel Corporation. - * Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD. + * Copyright (C) 2010 LAPIS SEMICONDUCTOR CO., LTD. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit v1.2.3-70-g09d2 From 03c49daa8168b58e6256f0cad88771b9440ca5f7 Mon Sep 17 00:00:00 2001 From: Tomoya MORINAGA Date: Fri, 27 Jan 2012 20:05:22 +0900 Subject: can: Kconfig: add more information about Intel EG20T PCH CAN controller Current menu description, not easy to understand what the description means. So, add information about the device. Signed-off-by: Tomoya MORINAGA [mkl: Added space before opening parentheses in Kconfig. Make commit message more descriptive.] Signed-off-by: Marc Kleine-Budde --- drivers/net/can/Kconfig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig index ab45758c49a..bb709fd6699 100644 --- a/drivers/net/can/Kconfig +++ b/drivers/net/can/Kconfig @@ -103,11 +103,11 @@ config CAN_FLEXCAN Say Y here if you want to support for Freescale FlexCAN. config PCH_CAN - tristate "PCH CAN" + tristate "Intel EG20T PCH CAN controller" depends on CAN_DEV && PCI ---help--- - This driver is for PCH CAN of Topcliff which is an IOH for x86 - embedded processor. + This driver is for PCH CAN of Topcliff (Intel EG20T PCH) which + is an IOH for x86 embedded processor (Intel Atom E6xx series). This driver can access CAN bus. source "drivers/net/can/mscan/Kconfig" -- cgit v1.2.3-70-g09d2 From 79d0d8a7d5edca459f544c2ad75088e99307795e Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 1 Feb 2012 11:14:13 +0100 Subject: can: bfin_can/ti_hecc/mscan: add missing do_get_berr_counter callback Cc: Anant Gole Signed-off-by: Wolfgang Grandegger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/bfin_can.c | 15 +++++++++++++++ drivers/net/can/mscan/mscan.c | 16 +++++++++++++++- drivers/net/can/ti_hecc.c | 12 ++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index 349e0fabb63..e1e7f9da3da 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -224,6 +224,20 @@ static int bfin_can_set_mode(struct net_device *dev, enum can_mode mode) return 0; } +static int bfin_can_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct bfin_can_priv *priv = netdev_priv(dev); + struct bfin_can_regs __iomem *reg = priv->membase; + + u16 cec = bfin_read(®->cec); + + bec->txerr = cec >> 8; + bec->rxerr = cec; + + return 0; +} + static int bfin_can_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct bfin_can_priv *priv = netdev_priv(dev); @@ -509,6 +523,7 @@ struct net_device *alloc_bfin_candev(void) priv->can.bittiming_const = &bfin_can_bittiming_const; priv->can.do_set_bittiming = bfin_can_set_bittiming; priv->can.do_set_mode = bfin_can_set_mode; + priv->can.do_get_berr_counter = bfin_can_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; return dev; diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index 1c82dd8b896..d11b0832ccd 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -560,6 +560,18 @@ static int mscan_do_set_bittiming(struct net_device *dev) return 0; } +static int mscan_get_berr_counter(const struct net_device *dev, + struct can_berr_counter *bec) +{ + struct mscan_priv *priv = netdev_priv(dev); + struct mscan_regs __iomem *regs = priv->reg_base; + + bec->txerr = in_8(®s->cantxerr); + bec->rxerr = in_8(®s->canrxerr); + + return 0; +} + static int mscan_open(struct net_device *dev) { int ret; @@ -639,8 +651,10 @@ int register_mscandev(struct net_device *dev, int mscan_clksrc) else ctl1 &= ~MSCAN_CLKSRC; - if (priv->type == MSCAN_TYPE_MPC5121) + if (priv->type == MSCAN_TYPE_MPC5121) { + priv->can.do_get_berr_counter = mscan_get_berr_counter; ctl1 |= MSCAN_BORM; /* bus-off recovery upon request */ + } ctl1 |= MSCAN_CANE; out_8(®s->canctl1, ctl1); diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index df809e3f130..aee925ab0de 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -458,6 +458,17 @@ static int ti_hecc_do_set_mode(struct net_device *ndev, enum can_mode mode) return ret; } +static int ti_hecc_get_berr_counter(const struct net_device *ndev, + struct can_berr_counter *bec) +{ + struct ti_hecc_priv *priv = netdev_priv(ndev); + + bec->txerr = hecc_read(priv, HECC_CANTEC); + bec->rxerr = hecc_read(priv, HECC_CANREC); + + return 0; +} + /* * ti_hecc_xmit: HECC Transmit * @@ -922,6 +933,7 @@ static int ti_hecc_probe(struct platform_device *pdev) priv->can.bittiming_const = &ti_hecc_bittiming_const; priv->can.do_set_mode = ti_hecc_do_set_mode; priv->can.do_get_state = ti_hecc_get_state; + priv->can.do_get_berr_counter = ti_hecc_get_berr_counter; priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES; spin_lock_init(&priv->mbx_lock); -- cgit v1.2.3-70-g09d2 From aabdfd6adb804d0aaba0188ade0f1afe42a52e31 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 1 Feb 2012 11:02:05 +0100 Subject: can: replace the dev_dbg/info/err/... with the new netdev_xxx macros Cc: uclinux-dist-devel@blackfin.uclinux.org Cc: Anant Gole Cc: Chris Elston Cc: Sebastian Haas Cc: Matthias Fuchs Signed-off-by: Wolfgang Grandegger Acked-by: Sebastian Haas Acked-by: Mike Frysinger Signed-off-by: Marc Kleine-Budde --- drivers/net/can/bfin_can.c | 21 ++++++--------- drivers/net/can/dev.c | 23 ++++++++-------- drivers/net/can/flexcan.c | 44 +++++++++++++++--------------- drivers/net/can/mcp251x.c | 3 +-- drivers/net/can/mscan/mscan.c | 17 ++++++------ drivers/net/can/sja1000/sja1000.c | 19 +++++++------ drivers/net/can/ti_hecc.c | 20 +++++++------- drivers/net/can/usb/ems_usb.c | 57 ++++++++++++++++----------------------- drivers/net/can/usb/esd_usb2.c | 27 +++++++++---------- 9 files changed, 103 insertions(+), 128 deletions(-) (limited to 'drivers') diff --git a/drivers/net/can/bfin_can.c b/drivers/net/can/bfin_can.c index e1e7f9da3da..3f88473423e 100644 --- a/drivers/net/can/bfin_can.c +++ b/drivers/net/can/bfin_can.c @@ -82,8 +82,7 @@ static int bfin_can_set_bittiming(struct net_device *dev) bfin_write(®->clock, clk); bfin_write(®->timing, timing); - dev_info(dev->dev.parent, "setting CLOCK=0x%04x TIMING=0x%04x\n", - clk, timing); + netdev_info(dev, "setting CLOCK=0x%04x TIMING=0x%04x\n", clk, timing); return 0; } @@ -108,8 +107,7 @@ static void bfin_can_set_reset_mode(struct net_device *dev) while (!(bfin_read(®->control) & CCA)) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to enter configuration mode\n"); + netdev_err(dev, "fail to enter configuration mode\n"); BUG(); } } @@ -165,8 +163,7 @@ static void bfin_can_set_normal_mode(struct net_device *dev) while (bfin_read(®->status) & CCA) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to leave configuration mode\n"); + netdev_err(dev, "fail to leave configuration mode\n"); BUG(); } } @@ -345,7 +342,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) if (isrc & RMLIS) { /* data overrun interrupt */ - dev_dbg(dev->dev.parent, "data overrun interrupt\n"); + netdev_dbg(dev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -353,7 +350,7 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) } if (isrc & BOIS) { - dev_dbg(dev->dev.parent, "bus-off mode interrupt\n"); + netdev_dbg(dev, "bus-off mode interrupt\n"); state = CAN_STATE_BUS_OFF; cf->can_id |= CAN_ERR_BUSOFF; can_bus_off(dev); @@ -361,13 +358,12 @@ static int bfin_can_err(struct net_device *dev, u16 isrc, u16 status) if (isrc & EPIS) { /* error passive interrupt */ - dev_dbg(dev->dev.parent, "error passive interrupt\n"); + netdev_dbg(dev, "error passive interrupt\n"); state = CAN_STATE_ERROR_PASSIVE; } if ((isrc & EWTIS) || (isrc & EWRIS)) { - dev_dbg(dev->dev.parent, - "Error Warning Transmit/Receive Interrupt\n"); + netdev_dbg(dev, "Error Warning Transmit/Receive Interrupt\n"); state = CAN_STATE_ERROR_WARNING; } @@ -651,8 +647,7 @@ static int bfin_can_suspend(struct platform_device *pdev, pm_message_t mesg) while (!(bfin_read(®->intr) & SMACK)) { udelay(10); if (--timeout == 0) { - dev_err(dev->dev.parent, - "fail to enter sleep mode\n"); + netdev_err(dev, "fail to enter sleep mode\n"); BUG(); } } diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index 9d9799cf68c..c5fe3a3db8c 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c @@ -130,13 +130,13 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) /* Error in one-tenth of a percent */ error = (best_error * 1000) / bt->bitrate; if (error > CAN_CALC_MAX_ERROR) { - dev_err(dev->dev.parent, - "bitrate error %ld.%ld%% too high\n", - error / 10, error % 10); + netdev_err(dev, + "bitrate error %ld.%ld%% too high\n", + error / 10, error % 10); return -EDOM; } else { - dev_warn(dev->dev.parent, "bitrate error %ld.%ld%%\n", - error / 10, error % 10); + netdev_warn(dev, "bitrate error %ld.%ld%%\n", + error / 10, error % 10); } } @@ -172,7 +172,7 @@ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) #else /* !CONFIG_CAN_CALC_BITTIMING */ static int can_calc_bittiming(struct net_device *dev, struct can_bittiming *bt) { - dev_err(dev->dev.parent, "bit-timing calculation not available\n"); + netdev_err(dev, "bit-timing calculation not available\n"); return -EINVAL; } #endif /* CONFIG_CAN_CALC_BITTIMING */ @@ -313,8 +313,7 @@ void can_put_echo_skb(struct sk_buff *skb, struct net_device *dev, priv->echo_skb[idx] = skb; } else { /* locking problem with netif_stop_queue() ?? */ - dev_err(dev->dev.parent, "%s: BUG! echo_skb is occupied!\n", - __func__); + netdev_err(dev, "%s: BUG! echo_skb is occupied!\n", __func__); kfree_skb(skb); } } @@ -400,7 +399,7 @@ void can_restart(unsigned long data) stats->rx_bytes += cf->can_dlc; restart: - dev_dbg(dev->dev.parent, "restarted\n"); + netdev_dbg(dev, "restarted\n"); priv->can_stats.restarts++; /* Now restart the device */ @@ -408,7 +407,7 @@ restart: netif_carrier_on(dev); if (err) - dev_err(dev->dev.parent, "Error %d during restart", err); + netdev_err(dev, "Error %d during restart", err); } int can_restart_now(struct net_device *dev) @@ -441,7 +440,7 @@ void can_bus_off(struct net_device *dev) { struct can_priv *priv = netdev_priv(dev); - dev_dbg(dev->dev.parent, "bus-off\n"); + netdev_dbg(dev, "bus-off\n"); netif_carrier_off(dev); priv->can_stats.bus_off++; @@ -553,7 +552,7 @@ int open_candev(struct net_device *dev) struct can_priv *priv = netdev_priv(dev); if (!priv->bittiming.tq && !priv->bittiming.bitrate) { - dev_err(dev->dev.parent, "bit-timing not yet defined\n"); + netdev_err(dev, "bit-timing not yet defined\n"); return -EINVAL; } diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index ab0136f49f4..e636287213f 100644 --- a/drivers/net/can/flexcan.c +++ b/drivers/net/can/flexcan.c @@ -315,34 +315,34 @@ static void do_bus_err(struct net_device *dev, cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; if (reg_esr & FLEXCAN_ESR_BIT1_ERR) { - dev_dbg(dev->dev.parent, "BIT1_ERR irq\n"); + netdev_dbg(dev, "BIT1_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT1; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_BIT0_ERR) { - dev_dbg(dev->dev.parent, "BIT0_ERR irq\n"); + netdev_dbg(dev, "BIT0_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT0; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_ACK_ERR) { - dev_dbg(dev->dev.parent, "ACK_ERR irq\n"); + netdev_dbg(dev, "ACK_ERR irq\n"); cf->can_id |= CAN_ERR_ACK; cf->data[3] |= CAN_ERR_PROT_LOC_ACK; tx_errors = 1; } if (reg_esr & FLEXCAN_ESR_CRC_ERR) { - dev_dbg(dev->dev.parent, "CRC_ERR irq\n"); + netdev_dbg(dev, "CRC_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_BIT; cf->data[3] |= CAN_ERR_PROT_LOC_CRC_SEQ; rx_errors = 1; } if (reg_esr & FLEXCAN_ESR_FRM_ERR) { - dev_dbg(dev->dev.parent, "FRM_ERR irq\n"); + netdev_dbg(dev, "FRM_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_FORM; rx_errors = 1; } if (reg_esr & FLEXCAN_ESR_STF_ERR) { - dev_dbg(dev->dev.parent, "STF_ERR irq\n"); + netdev_dbg(dev, "STF_ERR irq\n"); cf->data[2] |= CAN_ERR_PROT_STUFF; rx_errors = 1; } @@ -389,7 +389,7 @@ static void do_state(struct net_device *dev, */ if (new_state >= CAN_STATE_ERROR_WARNING && new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Warning IRQ\n"); + netdev_dbg(dev, "Error Warning IRQ\n"); priv->can.can_stats.error_warning++; cf->can_id |= CAN_ERR_CRTL; @@ -405,7 +405,7 @@ static void do_state(struct net_device *dev, */ if (new_state >= CAN_STATE_ERROR_PASSIVE && new_state <= CAN_STATE_BUS_OFF) { - dev_dbg(dev->dev.parent, "Error Passive IRQ\n"); + netdev_dbg(dev, "Error Passive IRQ\n"); priv->can.can_stats.error_passive++; cf->can_id |= CAN_ERR_CRTL; @@ -415,8 +415,8 @@ static void do_state(struct net_device *dev, } break; case CAN_STATE_BUS_OFF: - dev_err(dev->dev.parent, - "BUG! hardware recovered automatically from BUS_OFF\n"); + netdev_err(dev, "BUG! " + "hardware recovered automatically from BUS_OFF\n"); break; default: break; @@ -425,7 +425,7 @@ static void do_state(struct net_device *dev, /* process state changes depending on the new state */ switch (new_state) { case CAN_STATE_ERROR_ACTIVE: - dev_dbg(dev->dev.parent, "Error Active\n"); + netdev_dbg(dev, "Error Active\n"); cf->can_id |= CAN_ERR_PROT; cf->data[2] = CAN_ERR_PROT_ACTIVE; break; @@ -644,12 +644,12 @@ static void flexcan_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) reg |= FLEXCAN_CTRL_SMP; - dev_info(dev->dev.parent, "writing ctrl=0x%08x\n", reg); + netdev_info(dev, "writing ctrl=0x%08x\n", reg); flexcan_write(reg, ®s->ctrl); /* print chip status */ - dev_dbg(dev->dev.parent, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, - flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); + netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, + flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); } /* @@ -675,9 +675,8 @@ static int flexcan_chip_start(struct net_device *dev) reg_mcr = flexcan_read(®s->mcr); if (reg_mcr & FLEXCAN_MCR_SOFTRST) { - dev_err(dev->dev.parent, - "Failed to softreset can module (mcr=0x%08x)\n", - reg_mcr); + netdev_err(dev, "Failed to softreset can module (mcr=0x%08x)\n", + reg_mcr); err = -ENODEV; goto out; } @@ -700,7 +699,7 @@ static int flexcan_chip_start(struct net_device *dev) reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_FEN | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_SRX_DIS; - dev_dbg(dev->dev.parent, "%s: writing mcr=0x%08x", __func__, reg_mcr); + netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); flexcan_write(reg_mcr, ®s->mcr); /* @@ -726,7 +725,7 @@ static int flexcan_chip_start(struct net_device *dev) /* save for later use */ priv->reg_ctrl_default = reg_ctrl; - dev_dbg(dev->dev.parent, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); + netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); flexcan_write(reg_ctrl, ®s->ctrl); for (i = 0; i < ARRAY_SIZE(regs->cantxfg); i++) { @@ -758,8 +757,8 @@ static int flexcan_chip_start(struct net_device *dev) flexcan_write(FLEXCAN_IFLAG_DEFAULT, ®s->imask1); /* print chip status */ - dev_dbg(dev->dev.parent, "%s: reading mcr=0x%08x ctrl=0x%08x\n", - __func__, flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); + netdev_dbg(dev, "%s: reading mcr=0x%08x ctrl=0x%08x\n", __func__, + flexcan_read(®s->mcr), flexcan_read(®s->ctrl)); return 0; @@ -897,8 +896,7 @@ static int __devinit register_flexcandev(struct net_device *dev) */ reg = flexcan_read(®s->mcr); if (!(reg & FLEXCAN_MCR_FEN)) { - dev_err(dev->dev.parent, - "Could not enable RX FIFO, unsupported core\n"); + netdev_err(dev, "Could not enable RX FIFO, unsupported core\n"); err = -ENODEV; goto out; } diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/mcp251x.c index 330140ee266..346785c56a2 100644 --- a/drivers/net/can/mcp251x.c +++ b/drivers/net/can/mcp251x.c @@ -712,8 +712,7 @@ static void mcp251x_error_skb(struct net_device *net, int can_id, int data1) frame->data[1] = data1; netif_rx_ni(skb); } else { - dev_err(&net->dev, - "cannot allocate error skb\n"); + netdev_err(net, "cannot allocate error skb\n"); } } diff --git a/drivers/net/can/mscan/mscan.c b/drivers/net/can/mscan/mscan.c index d11b0832ccd..41a2a2dda7e 100644 --- a/drivers/net/can/mscan/mscan.c +++ b/drivers/net/can/mscan/mscan.c @@ -95,9 +95,9 @@ static int mscan_set_mode(struct net_device *dev, u8 mode) * any, at once. */ if (i >= MSCAN_SET_MODE_RETRIES) - dev_dbg(dev->dev.parent, - "device failed to enter sleep mode. " - "We proceed anyhow.\n"); + netdev_dbg(dev, + "device failed to enter sleep mode. " + "We proceed anyhow.\n"); else priv->can.state = CAN_STATE_SLEEPING; } @@ -213,7 +213,7 @@ static netdev_tx_t mscan_start_xmit(struct sk_buff *skb, struct net_device *dev) switch (hweight8(i)) { case 0: netif_stop_queue(dev); - dev_err(dev->dev.parent, "Tx Ring full when queue awake!\n"); + netdev_err(dev, "Tx Ring full when queue awake!\n"); return NETDEV_TX_BUSY; case 1: /* @@ -352,7 +352,7 @@ static void mscan_get_err_frame(struct net_device *dev, struct can_frame *frame, struct net_device_stats *stats = &dev->stats; enum can_state old_state; - dev_dbg(dev->dev.parent, "error interrupt (canrflg=%#x)\n", canrflg); + netdev_dbg(dev, "error interrupt (canrflg=%#x)\n", canrflg); frame->can_id = CAN_ERR_FLAG; if (canrflg & MSCAN_OVRIF) { @@ -427,7 +427,7 @@ static int mscan_rx_poll(struct napi_struct *napi, int quota) skb = alloc_can_skb(dev, &frame); if (!skb) { if (printk_ratelimit()) - dev_notice(dev->dev.parent, "packet dropped\n"); + netdev_notice(dev, "packet dropped\n"); stats->rx_dropped++; out_8(®s->canrflg, canrflg); continue; @@ -551,8 +551,7 @@ static int mscan_do_set_bittiming(struct net_device *dev) BTR1_SET_TSEG2(bt->phase_seg2) | BTR1_SET_SAM(priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)); - dev_info(dev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", - btr0, btr1); + netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); out_8(®s->canbtr0, btr0); out_8(®s->canbtr1, btr1); @@ -587,7 +586,7 @@ static int mscan_open(struct net_device *dev) ret = request_irq(dev->irq, mscan_isr, 0, dev->name, dev); if (ret < 0) { - dev_err(dev->dev.parent, "failed to attach interrupt\n"); + netdev_err(dev, "failed to attach interrupt\n"); goto exit_napi_disable; } diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c index 04a3f1b756a..ebbcfcafe29 100644 --- a/drivers/net/can/sja1000/sja1000.c +++ b/drivers/net/can/sja1000/sja1000.c @@ -128,7 +128,7 @@ static void set_reset_mode(struct net_device *dev) status = priv->read_reg(priv, REG_MOD); } - dev_err(dev->dev.parent, "setting SJA1000 into reset mode failed!\n"); + netdev_err(dev, "setting SJA1000 into reset mode failed!\n"); } static void set_normal_mode(struct net_device *dev) @@ -156,7 +156,7 @@ static void set_normal_mode(struct net_device *dev) status = priv->read_reg(priv, REG_MOD); } - dev_err(dev->dev.parent, "setting SJA1000 into normal mode failed!\n"); + netdev_err(dev, "setting SJA1000 into normal mode failed!\n"); } static void sja1000_start(struct net_device *dev) @@ -209,8 +209,7 @@ static int sja1000_set_bittiming(struct net_device *dev) if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) btr1 |= 0x80; - dev_info(dev->dev.parent, - "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); + netdev_info(dev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); priv->write_reg(priv, REG_BTR0, btr0); priv->write_reg(priv, REG_BTR1, btr1); @@ -378,7 +377,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_DOI) { /* data overrun interrupt */ - dev_dbg(dev->dev.parent, "data overrun interrupt\n"); + netdev_dbg(dev, "data overrun interrupt\n"); cf->can_id |= CAN_ERR_CRTL; cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; stats->rx_over_errors++; @@ -388,7 +387,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) if (isrc & IRQ_EI) { /* error warning interrupt */ - dev_dbg(dev->dev.parent, "error warning interrupt\n"); + netdev_dbg(dev, "error warning interrupt\n"); if (status & SR_BS) { state = CAN_STATE_BUS_OFF; @@ -429,7 +428,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) } if (isrc & IRQ_EPI) { /* error passive interrupt */ - dev_dbg(dev->dev.parent, "error passive interrupt\n"); + netdev_dbg(dev, "error passive interrupt\n"); if (status & SR_ES) state = CAN_STATE_ERROR_PASSIVE; else @@ -437,7 +436,7 @@ static int sja1000_err(struct net_device *dev, uint8_t isrc, uint8_t status) } if (isrc & IRQ_ALI) { /* arbitration lost interrupt */ - dev_dbg(dev->dev.parent, "arbitration lost interrupt\n"); + netdev_dbg(dev, "arbitration lost interrupt\n"); alc = priv->read_reg(priv, REG_ALC); priv->can.can_stats.arbitration_lost++; stats->tx_errors++; @@ -495,7 +494,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) status = priv->read_reg(priv, REG_SR); if (isrc & IRQ_WUI) - dev_warn(dev->dev.parent, "wakeup interrupt\n"); + netdev_warn(dev, "wakeup interrupt\n"); if (isrc & IRQ_TI) { /* transmission complete interrupt */ @@ -522,7 +521,7 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id) priv->post_irq(priv); if (n >= SJA1000_MAX_IRQ) - dev_dbg(dev->dev.parent, "%d messages handled in ISR", n); + netdev_dbg(dev, "%d messages handled in ISR", n); return (n) ? IRQ_HANDLED : IRQ_NONE; } diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index aee925ab0de..0d18a931972 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c @@ -306,7 +306,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) if (bit_timing->brp > 4) can_btc |= HECC_CANBTC_SAM; else - dev_warn(priv->ndev->dev.parent, "WARN: Triple" \ + netdev_warn(priv->ndev, "WARN: Triple" "sampling not set due to h/w limitations"); } can_btc |= ((bit_timing->sjw - 1) & 0x3) << 8; @@ -315,7 +315,7 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) /* ERM being set to 0 by default meaning resync at falling edge */ hecc_write(priv, HECC_CANBTC, can_btc); - dev_info(priv->ndev->dev.parent, "setting CANBTC=%#x\n", can_btc); + netdev_info(priv->ndev, "setting CANBTC=%#x\n", can_btc); return 0; } @@ -332,7 +332,7 @@ static void ti_hecc_reset(struct net_device *ndev) u32 cnt; struct ti_hecc_priv *priv = netdev_priv(ndev); - dev_dbg(ndev->dev.parent, "resetting hecc ...\n"); + netdev_dbg(ndev, "resetting hecc ...\n"); hecc_set_bit(priv, HECC_CANMC, HECC_CANMC_SRES); /* Set change control request and wait till enabled */ @@ -507,7 +507,7 @@ static netdev_tx_t ti_hecc_xmit(struct sk_buff *skb, struct net_device *ndev) if (unlikely(hecc_read(priv, HECC_CANME) & mbx_mask)) { spin_unlock_irqrestore(&priv->mbx_lock, flags); netif_stop_queue(ndev); - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "BUG: TX mbx not ready tx_head=%08X, tx_tail=%08X\n", priv->tx_head, priv->tx_tail); return NETDEV_TX_BUSY; @@ -561,7 +561,7 @@ static int ti_hecc_rx_pkt(struct ti_hecc_priv *priv, int mbxno) skb = alloc_can_skb(priv->ndev, &cf); if (!skb) { if (printk_ratelimit()) - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "ti_hecc_rx_pkt: alloc_can_skb() failed\n"); return -ENOMEM; } @@ -679,7 +679,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, skb = alloc_can_err_skb(ndev, &cf); if (!skb) { if (printk_ratelimit()) - dev_err(priv->ndev->dev.parent, + netdev_err(priv->ndev, "ti_hecc_error: alloc_can_err_skb() failed\n"); return -ENOMEM; } @@ -695,7 +695,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, cf->data[1] |= CAN_ERR_CRTL_RX_WARNING; } hecc_set_bit(priv, HECC_CANES, HECC_CANES_EW); - dev_dbg(priv->ndev->dev.parent, "Error Warning interrupt\n"); + netdev_dbg(priv->ndev, "Error Warning interrupt\n"); hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR); } @@ -710,7 +710,7 @@ static int ti_hecc_error(struct net_device *ndev, int int_status, cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; } hecc_set_bit(priv, HECC_CANES, HECC_CANES_EP); - dev_dbg(priv->ndev->dev.parent, "Error passive interrupt\n"); + netdev_dbg(priv->ndev, "Error passive interrupt\n"); hecc_clear_bit(priv, HECC_CANMC, HECC_CANMC_CCR); } @@ -835,7 +835,7 @@ static int ti_hecc_open(struct net_device *ndev) err = request_irq(ndev->irq, ti_hecc_interrupt, IRQF_SHARED, ndev->name, ndev); if (err) { - dev_err(ndev->dev.parent, "error requesting interrupt\n"); + netdev_err(ndev, "error requesting interrupt\n"); return err; } @@ -844,7 +844,7 @@ static int ti_hecc_open(struct net_device *ndev) /* Open common can device */ err = open_candev(ndev); if (err) { - dev_err(ndev->dev.parent, "open_candev() failed %d\n", err); + netdev_err(ndev, "open_candev() failed %d\n", err); ti_hecc_transceiver_switch(priv, 0); free_irq(ndev->irq, ndev); return err; diff --git a/drivers/net/can/usb/ems_usb.c b/drivers/net/can/usb/ems_usb.c index 9783e02fbc2..7ae65fc8003 100644 --- a/drivers/net/can/usb/ems_usb.c +++ b/drivers/net/can/usb/ems_usb.c @@ -288,8 +288,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n", - urb->status); + netdev_info(netdev, "Rx interrupt aborted %d\n", urb->status); break; } @@ -298,8 +297,7 @@ static void ems_usb_read_interrupt_callback(struct urb *urb) if (err == -ENODEV) netif_device_detach(netdev); else if (err) - dev_err(netdev->dev.parent, - "failed resubmitting intr urb: %d\n", err); + netdev_err(netdev, "failed resubmitting intr urb: %d\n", err); } static void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) @@ -431,8 +429,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) return; default: - dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Rx URB aborted (%d)\n", urb->status); goto resubmit_urb; } @@ -477,7 +474,7 @@ static void ems_usb_read_bulk_callback(struct urb *urb) msg_count--; if (start > urb->transfer_buffer_length) { - dev_err(netdev->dev.parent, "format error\n"); + netdev_err(netdev, "format error\n"); break; } } @@ -493,8 +490,8 @@ resubmit_urb: if (retval == -ENODEV) netif_device_detach(netdev); else if (retval) - dev_err(netdev->dev.parent, - "failed resubmitting read bulk urb: %d\n", retval); + netdev_err(netdev, + "failed resubmitting read bulk urb: %d\n", retval); } /* @@ -521,8 +518,7 @@ static void ems_usb_write_bulk_callback(struct urb *urb) return; if (urb->status) - dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->trans_start = jiffies; @@ -605,8 +601,7 @@ static int ems_usb_start(struct ems_usb *dev) /* create a URB, and a buffer for it */ urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - dev_err(netdev->dev.parent, - "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); err = -ENOMEM; break; } @@ -614,8 +609,7 @@ static int ems_usb_start(struct ems_usb *dev) buf = usb_alloc_coherent(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, - "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); err = -ENOMEM; break; @@ -641,13 +635,13 @@ static int ems_usb_start(struct ems_usb *dev) /* Did we submit any URBs */ if (i == 0) { - dev_warn(netdev->dev.parent, "couldn't setup read URBs\n"); + netdev_warn(netdev, "couldn't setup read URBs\n"); return err; } /* Warn if we've couldn't transmit all the URBs */ if (i < MAX_RX_URBS) - dev_warn(netdev->dev.parent, "rx performance may be slow\n"); + netdev_warn(netdev, "rx performance may be slow\n"); /* Setup and start interrupt URB */ usb_fill_int_urb(dev->intr_urb, dev->udev, @@ -658,8 +652,7 @@ static int ems_usb_start(struct ems_usb *dev) err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); if (err) { - dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", - err); + netdev_warn(netdev, "intr URB submit failed: %d\n", err); return err; } @@ -688,7 +681,7 @@ static int ems_usb_start(struct ems_usb *dev) return 0; failed: - dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); + netdev_warn(netdev, "couldn't submit control: %d\n", err); return err; } @@ -728,8 +721,7 @@ static int ems_usb_open(struct net_device *netdev) if (err == -ENODEV) netif_device_detach(dev->netdev); - dev_warn(netdev->dev.parent, "couldn't start device: %d\n", - err); + netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); @@ -762,13 +754,13 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_err(netdev->dev.parent, "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); goto nomem; } buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); usb_free_urb(urb); goto nomem; } @@ -811,7 +803,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne usb_unanchor_urb(urb); usb_free_coherent(dev->udev, size, buf, urb->transfer_dma); - dev_warn(netdev->dev.parent, "couldn't find free context\n"); + netdev_warn(netdev, "couldn't find free context\n"); return NETDEV_TX_BUSY; } @@ -842,7 +834,7 @@ static netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *ne if (err == -ENODEV) { netif_device_detach(netdev); } else { - dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); + netdev_warn(netdev, "failed tx_urb %d\n", err); stats->tx_dropped++; } @@ -882,7 +874,7 @@ static int ems_usb_close(struct net_device *netdev) /* Set CAN controller to reset mode */ if (ems_usb_write_mode(dev, SJA1000_MOD_RM)) - dev_warn(netdev->dev.parent, "couldn't stop device"); + netdev_warn(netdev, "couldn't stop device"); close_candev(netdev); @@ -919,7 +911,7 @@ static int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) switch (mode) { case CAN_MODE_START: if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) - dev_warn(netdev->dev.parent, "couldn't start device"); + netdev_warn(netdev, "couldn't start device"); if (netif_queue_stopped(netdev)) netif_wake_queue(netdev); @@ -944,8 +936,7 @@ static int ems_usb_set_bittiming(struct net_device *netdev) if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) btr1 |= 0x80; - dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", - btr0, btr1); + netdev_info(netdev, "setting BTR0=0x%02x BTR1=0x%02x\n", btr0, btr1); dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0; dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1; @@ -1050,15 +1041,13 @@ static int ems_usb_probe(struct usb_interface *intf, err = ems_usb_command_msg(dev, &dev->active_params); if (err) { - dev_err(netdev->dev.parent, - "couldn't initialize controller: %d\n", err); + netdev_err(netdev, "couldn't initialize controller: %d\n", err); goto cleanup_tx_msg_buffer; } err = register_candev(netdev); if (err) { - dev_err(netdev->dev.parent, - "couldn't register CAN device: %d\n", err); + netdev_err(netdev, "couldn't register CAN device: %d\n", err); goto cleanup_tx_msg_buffer; } diff --git a/drivers/net/can/usb/esd_usb2.c b/drivers/net/can/usb/esd_usb2.c index 92774637aad..09b1da5bc51 100644 --- a/drivers/net/can/usb/esd_usb2.c +++ b/drivers/net/can/usb/esd_usb2.c @@ -470,8 +470,7 @@ static void esd_usb2_write_bulk_callback(struct urb *urb) return; if (urb->status) - dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", - urb->status); + netdev_info(netdev, "Tx URB aborted (%d)\n", urb->status); netdev->trans_start = jiffies; } @@ -651,7 +650,7 @@ failed: if (err == -ENODEV) netif_device_detach(netdev); - dev_err(netdev->dev.parent, "couldn't start device: %d\n", err); + netdev_err(netdev, "couldn't start device: %d\n", err); return err; } @@ -687,8 +686,7 @@ static int esd_usb2_open(struct net_device *netdev) /* finally start device */ err = esd_usb2_start(priv); if (err) { - dev_warn(netdev->dev.parent, - "couldn't start device: %d\n", err); + netdev_warn(netdev, "couldn't start device: %d\n", err); close_candev(netdev); return err; } @@ -721,7 +719,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, /* create a URB, and a buffer for it, and copy the data to the URB */ urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { - dev_err(netdev->dev.parent, "No memory left for URBs\n"); + netdev_err(netdev, "No memory left for URBs\n"); stats->tx_dropped++; dev_kfree_skb(skb); goto nourbmem; @@ -730,7 +728,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, buf = usb_alloc_coherent(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); if (!buf) { - dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); + netdev_err(netdev, "No memory left for USB buffer\n"); stats->tx_dropped++; dev_kfree_skb(skb); goto nobufmem; @@ -766,7 +764,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, * This may never happen. */ if (!context) { - dev_warn(netdev->dev.parent, "couldn't find free context\n"); + netdev_warn(netdev, "couldn't find free context\n"); ret = NETDEV_TX_BUSY; goto releasebuf; } @@ -806,7 +804,7 @@ static netdev_tx_t esd_usb2_start_xmit(struct sk_buff *skb, if (err == -ENODEV) netif_device_detach(netdev); else - dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); + netdev_warn(netdev, "failed tx_urb %d\n", err); goto releasebuf; } @@ -845,7 +843,7 @@ static int esd_usb2_close(struct net_device *netdev) for (i = 0; i <= ESD_MAX_ID_SEGMENT; i++) msg.msg.filter.mask[i] = 0; if (esd_usb2_send_msg(priv->usb2, &msg) < 0) - dev_err(netdev->dev.parent, "sending idadd message failed\n"); + netdev_err(netdev, "sending idadd message failed\n"); /* set CAN controller to reset mode */ msg.msg.hdr.len = 2; @@ -854,7 +852,7 @@ static int esd_usb2_close(struct net_device *netdev) msg.msg.setbaud.rsvd = 0; msg.msg.setbaud.baud = cpu_to_le32(ESD_USB2_NO_BAUDRATE); if (esd_usb2_send_msg(priv->usb2, &msg) < 0) - dev_err(netdev->dev.parent, "sending setbaud message failed\n"); + netdev_err(netdev, "sending setbaud message failed\n"); priv->can.state = CAN_STATE_STOPPED; @@ -910,7 +908,7 @@ static int esd_usb2_set_bittiming(struct net_device *netdev) msg.msg.setbaud.rsvd = 0; msg.msg.setbaud.baud = cpu_to_le32(canbtr); - dev_info(netdev->dev.parent, "setting BTR=%#x\n", canbtr); + netdev_info(netdev, "setting BTR=%#x\n", canbtr); return esd_usb2_send_msg(priv->usb2, &msg); } @@ -988,15 +986,14 @@ static int esd_usb2_probe_one_net(struct usb_interface *intf, int index) err = register_candev(netdev); if (err) { - dev_err(&intf->dev, - "couldn't register CAN device: %d\n", err); + dev_err(&intf->dev, "couldn't register CAN device: %d\n", err); free_candev(netdev); err = -ENOMEM; goto done; } dev->nets[index] = priv; - dev_info(netdev->dev.parent, "device %s registered\n", netdev->name); + netdev_info(netdev, "device %s registered\n", netdev->name); done: return err; -- cgit v1.2.3-70-g09d2 From a80b83b7b8456e9b475346c2e01d7e210883208c Mon Sep 17 00:00:00 2001 From: John Stultz Date: Fri, 3 Feb 2012 00:19:07 -0800 Subject: Input: add infrastructure for selecting clockid for event time stamps As noted by Arve and others, since wall time can jump backwards, it is difficult to use for input because one cannot determine if one event occurred before another or for how long a key was pressed. However, the timestamp field is part of the kernel ABI, and cannot be changed without possibly breaking existing users. This patch adds a new IOCTL that allows a clockid to be set in the evdev_client struct that will specify which time base to use for event timestamps (ie: CLOCK_MONOTONIC instead of CLOCK_REALTIME). For now we only support CLOCK_MONOTONIC and CLOCK_REALTIME, but in the future we could support other clockids if appropriate. The default remains CLOCK_REALTIME, so we don't change the ABI. Signed-off-by: John Stultz Reviewed-by: Daniel Kurtz Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 25 +++++++++++++++++++++---- include/linux/input.h | 2 ++ kernel/time/timekeeping.c | 2 ++ 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 76457d50bc3..c1740974299 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -46,6 +46,7 @@ struct evdev_client { struct fasync_struct *fasync; struct evdev *evdev; struct list_head node; + int clkid; unsigned int bufsize; struct input_event buffer[]; }; @@ -54,8 +55,12 @@ static struct evdev *evdev_table[EVDEV_MINORS]; static DEFINE_MUTEX(evdev_table_mutex); static void evdev_pass_event(struct evdev_client *client, - struct input_event *event) + struct input_event *event, + ktime_t mono, ktime_t real) { + event->time = ktime_to_timeval(client->clkid == CLOCK_MONOTONIC ? + mono : real); + /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); @@ -94,8 +99,11 @@ static void evdev_event(struct input_handle *handle, struct evdev *evdev = handle->private; struct evdev_client *client; struct input_event event; + ktime_t time_mono, time_real; + + time_mono = ktime_get(); + time_real = ktime_sub(time_mono, ktime_get_monotonic_offset()); - do_gettimeofday(&event.time); event.type = type; event.code = code; event.value = value; @@ -103,11 +111,12 @@ static void evdev_event(struct input_handle *handle, rcu_read_lock(); client = rcu_dereference(evdev->grab); + if (client) - evdev_pass_event(client, &event); + evdev_pass_event(client, &event, time_mono, time_real); else list_for_each_entry_rcu(client, &evdev->client_list, node) - evdev_pass_event(client, &event); + evdev_pass_event(client, &event, time_mono, time_real); rcu_read_unlock(); @@ -685,6 +694,14 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, else return evdev_ungrab(evdev, client); + case EVIOCSCLOCKID: + if (copy_from_user(&i, p, sizeof(unsigned int))) + return -EFAULT; + if (i != CLOCK_MONOTONIC && i != CLOCK_REALTIME) + return -EINVAL; + client->clkid = i; + return 0; + case EVIOCGKEYCODE: return evdev_handle_get_keycode(dev, p); diff --git a/include/linux/input.h b/include/linux/input.h index 3862e32c4ee..177261ea6f5 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -129,6 +129,8 @@ struct input_keymap_entry { #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ +#define EVIOCSCLOCKID _IOW('E', 0xa0, int) /* Set clockid to be used for timestamps */ + /* * Device properties and quirks */ diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 2b021b0e850..16947999475 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c @@ -1140,6 +1140,8 @@ ktime_t ktime_get_monotonic_offset(void) } while (read_seqretry(&xtime_lock, seq)); return timespec_to_ktime(wtom); } +EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); + /** * xtime_update() - advances the timekeeping infrastructure -- cgit v1.2.3-70-g09d2 From 8491ee1093c476ea3a9a19ab8593d8531cab40f7 Mon Sep 17 00:00:00 2001 From: Jan Steinhoff Date: Fri, 3 Feb 2012 00:21:31 -0800 Subject: Input: add Synaptics USB device driver This patch adds a driver for Synaptics USB touchpad or pointing stick devices. These USB devices emulate an USB mouse by default, so one can also use the usbhid driver. However, in combination with special user space drivers this kernel driver allows one to customize the behaviour of the device. An extended version of this driver with support for the cPad background display can be found at . Signed-off-by: Jan Steinhoff Acked-by: Jiri Kosina Signed-off-by: Dmitry Torokhov --- drivers/hid/hid-core.c | 10 + drivers/hid/hid-ids.h | 11 + drivers/input/mouse/Kconfig | 17 ++ drivers/input/mouse/Makefile | 1 + drivers/input/mouse/synaptics_usb.c | 568 ++++++++++++++++++++++++++++++++++++ 5 files changed, 607 insertions(+) create mode 100644 drivers/input/mouse/synaptics_usb.c (limited to 'drivers') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 848a56c0279..b639855acd2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1892,6 +1892,16 @@ static const struct hid_device_id hid_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_PANJIT, 0x0004) }, { HID_USB_DEVICE(USB_VENDOR_ID_PHILIPS, USB_DEVICE_ID_PHILIPS_IEEE802154_DONGLE) }, { HID_USB_DEVICE(USB_VENDOR_ID_POWERCOM, USB_DEVICE_ID_POWERCOM_UPS) }, +#if defined(CONFIG_MOUSE_SYNAPTICS_USB) || defined(CONFIG_MOUSE_SYNAPTICS_USB_MODULE) + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_INT_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_CPAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_STICK) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_COMP_TP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_WTP) }, + { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_DPAD) }, +#endif { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, { HID_USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 06ce996b8b6..3b683439c6c 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -633,6 +633,17 @@ #define USB_DEVICE_ID_SYMBOL_SCANNER_1 0x0800 #define USB_DEVICE_ID_SYMBOL_SCANNER_2 0x1300 +#define USB_VENDOR_ID_SYNAPTICS 0x06cb +#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 +#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 +#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 +#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 +#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 +#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 +#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 +#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 +#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 + #define USB_VENDOR_ID_THRUSTMASTER 0x044f #define USB_VENDOR_ID_TOPSEED 0x0766 diff --git a/drivers/input/mouse/Kconfig b/drivers/input/mouse/Kconfig index 9c1e6ee8353..9b8db821d5f 100644 --- a/drivers/input/mouse/Kconfig +++ b/drivers/input/mouse/Kconfig @@ -322,4 +322,21 @@ config MOUSE_SYNAPTICS_I2C To compile this driver as a module, choose M here: the module will be called synaptics_i2c. +config MOUSE_SYNAPTICS_USB + tristate "Synaptics USB device support" + depends on USB_ARCH_HAS_HCD + select USB + help + Say Y here if you want to use a Synaptics USB touchpad or pointing + stick. + + While these devices emulate an USB mouse by default and can be used + with standard usbhid driver, this driver, together with its X.Org + counterpart, allows you to fully utilize capabilities of the device. + More information can be found at: + + + To compile this driver as a module, choose M here: the + module will be called synaptics_usb. + endif diff --git a/drivers/input/mouse/Makefile b/drivers/input/mouse/Makefile index 570c84a4a65..4718effeb8d 100644 --- a/drivers/input/mouse/Makefile +++ b/drivers/input/mouse/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_MOUSE_PXA930_TRKBALL) += pxa930_trkball.o obj-$(CONFIG_MOUSE_RISCPC) += rpcmouse.o obj-$(CONFIG_MOUSE_SERIAL) += sermouse.o obj-$(CONFIG_MOUSE_SYNAPTICS_I2C) += synaptics_i2c.o +obj-$(CONFIG_MOUSE_SYNAPTICS_USB) += synaptics_usb.o obj-$(CONFIG_MOUSE_VSXXXAA) += vsxxxaa.o psmouse-objs := psmouse-base.o synaptics.o diff --git a/drivers/input/mouse/synaptics_usb.c b/drivers/input/mouse/synaptics_usb.c new file mode 100644 index 00000000000..e559a947bb5 --- /dev/null +++ b/drivers/input/mouse/synaptics_usb.c @@ -0,0 +1,568 @@ +/* + * USB Synaptics device driver + * + * Copyright (c) 2002 Rob Miller (rob@inpharmatica . co . uk) + * Copyright (c) 2003 Ron Lee (ron@debian.org) + * cPad driver for kernel 2.4 + * + * Copyright (c) 2004 Jan Steinhoff (cpad@jan-steinhoff . de) + * Copyright (c) 2004 Ron Lee (ron@debian.org) + * rewritten for kernel 2.6 + * + * cPad display character device part is not included. It can be found at + * http://jan-steinhoff.de/linux/synaptics-usb.html + * + * Bases on: usb_skeleton.c v2.2 by Greg Kroah-Hartman + * drivers/hid/usbhid/usbmouse.c by Vojtech Pavlik + * drivers/input/mouse/synaptics.c by Peter Osterlund + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * Trademarks are the property of their respective owners. + */ + +/* + * There are three different types of Synaptics USB devices: Touchpads, + * touchsticks (or trackpoints), and touchscreens. Touchpads are well supported + * by this driver, touchstick support has not been tested much yet, and + * touchscreens have not been tested at all. + * + * Up to three alternate settings are possible: + * setting 0: one int endpoint for relative movement (used by usbhid.ko) + * setting 1: one int endpoint for absolute finger position + * setting 2 (cPad only): one int endpoint for absolute finger position and + * two bulk endpoints for the display (in/out) + * This driver uses setting 1. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define USB_VENDOR_ID_SYNAPTICS 0x06cb +#define USB_DEVICE_ID_SYNAPTICS_TP 0x0001 /* Synaptics USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_INT_TP 0x0002 /* Integrated USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_CPAD 0x0003 /* Synaptics cPad */ +#define USB_DEVICE_ID_SYNAPTICS_TS 0x0006 /* Synaptics TouchScreen */ +#define USB_DEVICE_ID_SYNAPTICS_STICK 0x0007 /* Synaptics USB Styk */ +#define USB_DEVICE_ID_SYNAPTICS_WP 0x0008 /* Synaptics USB WheelPad */ +#define USB_DEVICE_ID_SYNAPTICS_COMP_TP 0x0009 /* Composite USB TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_WTP 0x0010 /* Wireless TouchPad */ +#define USB_DEVICE_ID_SYNAPTICS_DPAD 0x0013 /* DisplayPad */ + +#define SYNUSB_TOUCHPAD (1 << 0) +#define SYNUSB_STICK (1 << 1) +#define SYNUSB_TOUCHSCREEN (1 << 2) +#define SYNUSB_AUXDISPLAY (1 << 3) /* For cPad */ +#define SYNUSB_COMBO (1 << 4) /* Composite device (TP + stick) */ +#define SYNUSB_IO_ALWAYS (1 << 5) + +#define USB_DEVICE_SYNAPTICS(prod, kind) \ + USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, \ + USB_DEVICE_ID_SYNAPTICS_##prod), \ + .driver_info = (kind), + +#define SYNUSB_RECV_SIZE 8 + +#define XMIN_NOMINAL 1472 +#define XMAX_NOMINAL 5472 +#define YMIN_NOMINAL 1408 +#define YMAX_NOMINAL 4448 + +struct synusb { + struct usb_device *udev; + struct usb_interface *intf; + struct urb *urb; + unsigned char *data; + + /* input device related data structures */ + struct input_dev *input; + char name[128]; + char phys[64]; + + /* characteristics of the device */ + unsigned long flags; +}; + +static void synusb_report_buttons(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + + input_report_key(input_dev, BTN_LEFT, synusb->data[1] & 0x04); + input_report_key(input_dev, BTN_RIGHT, synusb->data[1] & 0x01); + input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x02); +} + +static void synusb_report_stick(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + int x, y; + unsigned int pressure; + + pressure = synusb->data[6]; + x = (s16)(be16_to_cpup((__be16 *)&synusb->data[2]) << 3) >> 7; + y = (s16)(be16_to_cpup((__be16 *)&synusb->data[4]) << 3) >> 7; + + if (pressure > 0) { + input_report_rel(input_dev, REL_X, x); + input_report_rel(input_dev, REL_Y, -y); + } + + input_report_abs(input_dev, ABS_PRESSURE, pressure); + + synusb_report_buttons(synusb); + + input_sync(input_dev); +} + +static void synusb_report_touchpad(struct synusb *synusb) +{ + struct input_dev *input_dev = synusb->input; + unsigned int num_fingers, tool_width; + unsigned int x, y; + unsigned int pressure, w; + + pressure = synusb->data[6]; + x = be16_to_cpup((__be16 *)&synusb->data[2]); + y = be16_to_cpup((__be16 *)&synusb->data[4]); + w = synusb->data[0] & 0x0f; + + if (pressure > 0) { + num_fingers = 1; + tool_width = 5; + switch (w) { + case 0 ... 1: + num_fingers = 2 + w; + break; + + case 2: /* pen, pretend its a finger */ + break; + + case 4 ... 15: + tool_width = w; + break; + } + } else { + num_fingers = 0; + tool_width = 0; + } + + /* + * Post events + * BTN_TOUCH has to be first as mousedev relies on it when doing + * absolute -> relative conversion + */ + + if (pressure > 30) + input_report_key(input_dev, BTN_TOUCH, 1); + if (pressure < 25) + input_report_key(input_dev, BTN_TOUCH, 0); + + if (num_fingers > 0) { + input_report_abs(input_dev, ABS_X, x); + input_report_abs(input_dev, ABS_Y, + YMAX_NOMINAL + YMIN_NOMINAL - y); + } + + input_report_abs(input_dev, ABS_PRESSURE, pressure); + input_report_abs(input_dev, ABS_TOOL_WIDTH, tool_width); + + input_report_key(input_dev, BTN_TOOL_FINGER, num_fingers == 1); + input_report_key(input_dev, BTN_TOOL_DOUBLETAP, num_fingers == 2); + input_report_key(input_dev, BTN_TOOL_TRIPLETAP, num_fingers == 3); + + synusb_report_buttons(synusb); + if (synusb->flags & SYNUSB_AUXDISPLAY) + input_report_key(input_dev, BTN_MIDDLE, synusb->data[1] & 0x08); + + input_sync(input_dev); +} + +static void synusb_irq(struct urb *urb) +{ + struct synusb *synusb = urb->context; + int error; + + /* Check our status in case we need to bail out early. */ + switch (urb->status) { + case 0: + usb_mark_last_busy(synusb->udev); + break; + + /* Device went away so don't keep trying to read from it. */ + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + return; + + default: + goto resubmit; + break; + } + + if (synusb->flags & SYNUSB_STICK) + synusb_report_stick(synusb); + else + synusb_report_touchpad(synusb); + +resubmit: + error = usb_submit_urb(urb, GFP_ATOMIC); + if (error && error != -EPERM) + dev_err(&synusb->intf->dev, + "%s - usb_submit_urb failed with result: %d", + __func__, error); +} + +static struct usb_endpoint_descriptor * +synusb_get_in_endpoint(struct usb_host_interface *iface) +{ + + struct usb_endpoint_descriptor *endpoint; + int i; + + for (i = 0; i < iface->desc.bNumEndpoints; ++i) { + endpoint = &iface->endpoint[i].desc; + + if (usb_endpoint_is_int_in(endpoint)) { + /* we found our interrupt in endpoint */ + return endpoint; + } + } + + return NULL; +} + +static int synusb_open(struct input_dev *dev) +{ + struct synusb *synusb = input_get_drvdata(dev); + int retval; + + retval = usb_autopm_get_interface(synusb->intf); + if (retval) { + dev_err(&synusb->intf->dev, + "%s - usb_autopm_get_interface failed, error: %d\n", + __func__, retval); + return retval; + } + + retval = usb_submit_urb(synusb->urb, GFP_KERNEL); + if (retval) { + dev_err(&synusb->intf->dev, + "%s - usb_submit_urb failed, error: %d\n", + __func__, retval); + retval = -EIO; + goto out; + } + + synusb->intf->needs_remote_wakeup = 1; + +out: + usb_autopm_put_interface(synusb->intf); + return retval; +} + +static void synusb_close(struct input_dev *dev) +{ + struct synusb *synusb = input_get_drvdata(dev); + int autopm_error; + + autopm_error = usb_autopm_get_interface(synusb->intf); + + usb_kill_urb(synusb->urb); + synusb->intf->needs_remote_wakeup = 0; + + if (!autopm_error) + usb_autopm_put_interface(synusb->intf); +} + +static int synusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *ep; + struct synusb *synusb; + struct input_dev *input_dev; + unsigned int intf_num = intf->cur_altsetting->desc.bInterfaceNumber; + unsigned int altsetting = min(intf->num_altsetting, 1U); + int error; + + error = usb_set_interface(udev, intf_num, altsetting); + if (error) { + dev_err(&udev->dev, + "Can not set alternate setting to %i, error: %i", + altsetting, error); + return error; + } + + ep = synusb_get_in_endpoint(intf->cur_altsetting); + if (!ep) + return -ENODEV; + + synusb = kzalloc(sizeof(*synusb), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!synusb || !input_dev) { + error = -ENOMEM; + goto err_free_mem; + } + + synusb->udev = udev; + synusb->intf = intf; + synusb->input = input_dev; + + synusb->flags = id->driver_info; + if (synusb->flags & SYNUSB_COMBO) { + /* + * This is a combo device, we need to set proper + * capability, depending on the interface. + */ + synusb->flags |= intf_num == 1 ? + SYNUSB_STICK : SYNUSB_TOUCHPAD; + } + + synusb->urb = usb_alloc_urb(0, GFP_KERNEL); + if (!synusb->urb) { + error = -ENOMEM; + goto err_free_mem; + } + + synusb->data = usb_alloc_coherent(udev, SYNUSB_RECV_SIZE, GFP_KERNEL, + &synusb->urb->transfer_dma); + if (!synusb->data) { + error = -ENOMEM; + goto err_free_urb; + } + + usb_fill_int_urb(synusb->urb, udev, + usb_rcvintpipe(udev, ep->bEndpointAddress), + synusb->data, SYNUSB_RECV_SIZE, + synusb_irq, synusb, + ep->bInterval); + synusb->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + if (udev->manufacturer) + strlcpy(synusb->name, udev->manufacturer, + sizeof(synusb->name)); + + if (udev->product) { + if (udev->manufacturer) + strlcat(synusb->name, " ", sizeof(synusb->name)); + strlcat(synusb->name, udev->product, sizeof(synusb->name)); + } + + if (!strlen(synusb->name)) + snprintf(synusb->name, sizeof(synusb->name), + "USB Synaptics Device %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); + + if (synusb->flags & SYNUSB_STICK) + strlcat(synusb->name, " (Stick) ", sizeof(synusb->name)); + + usb_make_path(udev, synusb->phys, sizeof(synusb->phys)); + strlcat(synusb->phys, "/input0", sizeof(synusb->phys)); + + input_dev->name = synusb->name; + input_dev->phys = synusb->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->dev.parent = &synusb->intf->dev; + + if (!(synusb->flags & SYNUSB_IO_ALWAYS)) { + input_dev->open = synusb_open; + input_dev->close = synusb_close; + } + + input_set_drvdata(input_dev, synusb); + + __set_bit(EV_ABS, input_dev->evbit); + __set_bit(EV_KEY, input_dev->evbit); + + if (synusb->flags & SYNUSB_STICK) { + __set_bit(EV_REL, input_dev->evbit); + __set_bit(REL_X, input_dev->relbit); + __set_bit(REL_Y, input_dev->relbit); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0); + } else { + input_set_abs_params(input_dev, ABS_X, + XMIN_NOMINAL, XMAX_NOMINAL, 0, 0); + input_set_abs_params(input_dev, ABS_Y, + YMIN_NOMINAL, YMAX_NOMINAL, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, 255, 0, 0); + input_set_abs_params(input_dev, ABS_TOOL_WIDTH, 0, 15, 0, 0); + __set_bit(BTN_TOUCH, input_dev->keybit); + __set_bit(BTN_TOOL_FINGER, input_dev->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); + } + + __set_bit(BTN_LEFT, input_dev->keybit); + __set_bit(BTN_RIGHT, input_dev->keybit); + __set_bit(BTN_MIDDLE, input_dev->keybit); + + usb_set_intfdata(intf, synusb); + + if (synusb->flags & SYNUSB_IO_ALWAYS) { + error = synusb_open(input_dev); + if (error) + goto err_free_dma; + } + + error = input_register_device(input_dev); + if (error) { + dev_err(&udev->dev, + "Failed to register input device, error %d\n", + error); + goto err_stop_io; + } + + return 0; + +err_stop_io: + if (synusb->flags & SYNUSB_IO_ALWAYS) + synusb_close(synusb->input); +err_free_dma: + usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, + synusb->urb->transfer_dma); +err_free_urb: + usb_free_urb(synusb->urb); +err_free_mem: + input_free_device(input_dev); + kfree(synusb); + usb_set_intfdata(intf, NULL); + + return error; +} + +static void synusb_disconnect(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct usb_device *udev = interface_to_usbdev(intf); + + if (synusb->flags & SYNUSB_IO_ALWAYS) + synusb_close(synusb->input); + + input_unregister_device(synusb->input); + + usb_free_coherent(udev, SYNUSB_RECV_SIZE, synusb->data, + synusb->urb->transfer_dma); + usb_free_urb(synusb->urb); + kfree(synusb); + + usb_set_intfdata(intf, NULL); +} + +static int synusb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + + mutex_lock(&input_dev->mutex); + usb_kill_urb(synusb->urb); + mutex_unlock(&input_dev->mutex); + + return 0; +} + +static int synusb_resume(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + int retval = 0; + + mutex_lock(&input_dev->mutex); + + if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { + retval = -EIO; + } + + mutex_unlock(&input_dev->mutex); + + return retval; +} + +static int synusb_pre_reset(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + + mutex_lock(&input_dev->mutex); + usb_kill_urb(synusb->urb); + + return 0; +} + +static int synusb_post_reset(struct usb_interface *intf) +{ + struct synusb *synusb = usb_get_intfdata(intf); + struct input_dev *input_dev = synusb->input; + int retval = 0; + + if ((input_dev->users || (synusb->flags & SYNUSB_IO_ALWAYS)) && + usb_submit_urb(synusb->urb, GFP_NOIO) < 0) { + retval = -EIO; + } + + mutex_unlock(&input_dev->mutex); + + return retval; +} + +static int synusb_reset_resume(struct usb_interface *intf) +{ + return synusb_resume(intf); +} + +static struct usb_device_id synusb_idtable[] = { + { USB_DEVICE_SYNAPTICS(TP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(INT_TP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(CPAD, + SYNUSB_TOUCHPAD | SYNUSB_AUXDISPLAY | SYNUSB_IO_ALWAYS) }, + { USB_DEVICE_SYNAPTICS(TS, SYNUSB_TOUCHSCREEN) }, + { USB_DEVICE_SYNAPTICS(STICK, SYNUSB_STICK) }, + { USB_DEVICE_SYNAPTICS(WP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(COMP_TP, SYNUSB_COMBO) }, + { USB_DEVICE_SYNAPTICS(WTP, SYNUSB_TOUCHPAD) }, + { USB_DEVICE_SYNAPTICS(DPAD, SYNUSB_TOUCHPAD) }, + { } +}; +MODULE_DEVICE_TABLE(usb, synusb_idtable); + +static struct usb_driver synusb_driver = { + .name = "synaptics_usb", + .probe = synusb_probe, + .disconnect = synusb_disconnect, + .id_table = synusb_idtable, + .suspend = synusb_suspend, + .resume = synusb_resume, + .pre_reset = synusb_pre_reset, + .post_reset = synusb_post_reset, + .reset_resume = synusb_reset_resume, + .supports_autosuspend = 1, +}; + +static int __init synusb_init(void) +{ + return usb_register(&synusb_driver); +} + +static void __exit synusb_exit(void) +{ + usb_deregister(&synusb_driver); +} + +module_init(synusb_init); +module_exit(synusb_exit); + +MODULE_AUTHOR("Rob Miller , " + "Ron Lee , " + "Jan Steinhoff "); +MODULE_DESCRIPTION("Synaptics USB device driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3-70-g09d2 From 023cea0ecfa2df034096c3f4afa796a0b2d1188a Mon Sep 17 00:00:00 2001 From: Shridhar Rasal Date: Fri, 3 Feb 2012 00:27:30 -0800 Subject: Input: tegra-kbc - allow skipping setting up some of GPIO pins Allow marking some of GPIO pins as ignored to to avoid continuously generating KBC input events. Signed-off-by: Shridhar Rasal Signed-off-by: Dmitry Torokhov --- arch/arm/mach-tegra/include/mach/kbc.h | 8 +++++++- drivers/input/keyboard/tegra-kbc.c | 34 +++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-tegra/include/mach/kbc.h b/arch/arm/mach-tegra/include/mach/kbc.h index d34ecd1bea6..a1302561293 100644 --- a/arch/arm/mach-tegra/include/mach/kbc.h +++ b/arch/arm/mach-tegra/include/mach/kbc.h @@ -31,8 +31,14 @@ #define KBC_MAX_COL 8 #define KBC_MAX_KEY (KBC_MAX_ROW * KBC_MAX_COL) +enum tegra_pin_type { + PIN_CFG_IGNORE, + PIN_CFG_COL, + PIN_CFG_ROW, +}; + struct tegra_kbc_pin_cfg { - bool is_row; + enum tegra_pin_type type; unsigned char num; }; diff --git a/drivers/input/keyboard/tegra-kbc.c b/drivers/input/keyboard/tegra-kbc.c index b307a46ecef..dc19432c665 100644 --- a/drivers/input/keyboard/tegra-kbc.c +++ b/drivers/input/keyboard/tegra-kbc.c @@ -468,10 +468,18 @@ static void tegra_kbc_config_pins(struct tegra_kbc *kbc) row_cfg &= ~r_mask; col_cfg &= ~c_mask; - if (pdata->pin_cfg[i].is_row) + switch (pdata->pin_cfg[i].type) { + case PIN_CFG_ROW: row_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << r_shft; - else + break; + + case PIN_CFG_COL: col_cfg |= ((pdata->pin_cfg[i].num << 1) | 1) << c_shft; + break; + + case PIN_CFG_IGNORE: + break; + } writel(row_cfg, kbc->mmio + r_offs); writel(col_cfg, kbc->mmio + c_offs); @@ -576,7 +584,8 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, for (i = 0; i < KBC_MAX_GPIO; i++) { const struct tegra_kbc_pin_cfg *pin_cfg = &pdata->pin_cfg[i]; - if (pin_cfg->is_row) { + switch (pin_cfg->type) { + case PIN_CFG_ROW: if (pin_cfg->num >= KBC_MAX_ROW) { dev_err(dev, "pin_cfg[%d]: invalid row number %d\n", @@ -584,13 +593,25 @@ tegra_kbc_check_pin_cfg(const struct tegra_kbc_platform_data *pdata, return false; } (*num_rows)++; - } else { + break; + + case PIN_CFG_COL: if (pin_cfg->num >= KBC_MAX_COL) { dev_err(dev, "pin_cfg[%d]: invalid column number %d\n", i, pin_cfg->num); return false; } + break; + + case PIN_CFG_IGNORE: + break; + + default: + dev_err(dev, + "pin_cfg[%d]: invalid entry type %d\n", + pin_cfg->type, pin_cfg->num); + return false; } } @@ -607,7 +628,6 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) if (!np) return NULL; - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; @@ -629,12 +649,12 @@ tegra_kbc_dt_parse_pdata(struct platform_device *pdev) */ for (i = 0; i < KBC_MAX_ROW; i++) { pdata->pin_cfg[i].num = i; - pdata->pin_cfg[i].is_row = true; + pdata->pin_cfg[i].type = PIN_CFG_ROW; } for (i = 0; i < KBC_MAX_COL; i++) { pdata->pin_cfg[KBC_MAX_ROW + i].num = i; - pdata->pin_cfg[KBC_MAX_ROW + i].is_row = false; + pdata->pin_cfg[KBC_MAX_ROW + i].type = PIN_CFG_COL; } return pdata; -- cgit v1.2.3-70-g09d2 From a14b1b42477c5ef089fcda88cbaae50d979eb8f9 Mon Sep 17 00:00:00 2001 From: Mandeep Singh Baines Date: Fri, 20 Jan 2012 12:11:16 -0800 Subject: drm: remove master fd restriction on mode setting getters Its useful to be able to call the mode setting getter ioctls. Not requiring master fd, enables writing a simple program which can query the state of the video system. Since these ioctls are only "getters" there is no security or synchronization issues which would require master fd. Opening an new fd is already protected by the file permissions on the device file. Signed-off-by: Mandeep Singh Baines Cc: Dave Airlie Cc: Daniel Vetter Cc: Ilija Hadzic Cc: Jesse Barnes Cc: Stephane Marchesin Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_drv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f68fc..d166bd08040 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c @@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = { DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), - DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), + DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), -- cgit v1.2.3-70-g09d2 From 86a4d69c0ad62ced87a74bbd43f2acefc66a97b0 Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Wed, 1 Feb 2012 11:42:38 -0500 Subject: drm/radeon/kms: common definitions for blit copy code R600/700 and Evergreen/NI blit code have a few redundant definitions in respective .c file. Move common definitions into a separate (new) .h file. Signed-off-by: Ilija Hadzic Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 12 +------- drivers/gpu/drm/radeon/r600_blit_kms.c | 15 +--------- drivers/gpu/drm/radeon/radeon_blit_common.h | 44 +++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/radeon/radeon_blit_common.h (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2379849515c..4e83fdcf4bc 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -32,17 +32,7 @@ #include "evergreend.h" #include "evergreen_blit_shaders.h" #include "cayman_blit_shaders.h" - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a +#include "radeon_blit_common.h" /* emits 17 */ static void diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index accc032c103..db38f587f27 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c @@ -30,20 +30,7 @@ #include "r600d.h" #include "r600_blit_shaders.h" - -#define DI_PT_RECTLIST 0x11 -#define DI_INDEX_SIZE_16_BIT 0x0 -#define DI_SRC_SEL_AUTO_INDEX 0x2 - -#define FMT_8 0x1 -#define FMT_5_6_5 0x8 -#define FMT_8_8_8_8 0x1a -#define COLOR_8 0x1 -#define COLOR_5_6_5 0x8 -#define COLOR_8_8_8_8 0x1a - -#define RECT_UNIT_H 32 -#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) +#include "radeon_blit_common.h" /* emits 21 on rv770+, 23 on r600 */ static void diff --git a/drivers/gpu/drm/radeon/radeon_blit_common.h b/drivers/gpu/drm/radeon/radeon_blit_common.h new file mode 100644 index 00000000000..4ecbe72c9d2 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_blit_common.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009 Advanced Micro Devices, Inc. + * Copyright 2009 Red Hat Inc. + * Copyright 2012 Alcatel-Lucent, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __RADEON_BLIT_COMMON_H__ + +#define DI_PT_RECTLIST 0x11 +#define DI_INDEX_SIZE_16_BIT 0x0 +#define DI_SRC_SEL_AUTO_INDEX 0x2 + +#define FMT_8 0x1 +#define FMT_5_6_5 0x8 +#define FMT_8_8_8_8 0x1a +#define COLOR_8 0x1 +#define COLOR_5_6_5 0x8 +#define COLOR_8_8_8_8 0x1a + +#define RECT_UNIT_H 32 +#define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) + +#define __RADEON_BLIT_COMMON_H__ +#endif -- cgit v1.2.3-70-g09d2 From 6d75e83ee31c146c8a3d56c762d3e15c483dc40e Mon Sep 17 00:00:00 2001 From: Ilija Hadzic Date: Tue, 31 Jan 2012 09:35:25 -0500 Subject: drm/radeon/kms: remove benchmarks shorter than one page copy_blit operation works only on integral number of pages so benchmarks shorter than one page size (4K) do not make sense v2: use RADEON_GPU_PAGE_SIZE instead of "magic" 1024 number and sweep sizes between 1 * to 16K * doubling the size in each iteration; we get the same coverage, as in the original benchmark, but guarantee integer multiples of page size v3: add whitespace between '*' operator per review received from zajec5@gmail.com Signed-off-by: Ilija Hadzic Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_benchmark.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 815f2341ab9..58cee89215c 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -208,22 +208,22 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number) break; case 3: /* GTT to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, RADEON_GEM_DOMAIN_VRAM); break; case 4: /* VRAM to GTT, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_GTT); break; case 5: /* VRAM to VRAM, buffer size sweep, powers of 2 */ - for (i = 1; i <= 65536; i <<= 1) - radeon_benchmark_move(rdev, i*1024, + for (i = 1; i <= 16384; i <<= 1) + radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, RADEON_GEM_DOMAIN_VRAM, RADEON_GEM_DOMAIN_VRAM); break; -- cgit v1.2.3-70-g09d2 From 1849ecb22fb3b5d57b65e7369a3957adf9f26f39 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Jan 2012 11:07:09 +0100 Subject: drm/kms: Make i2c buses faster A udelay value of 20 leads to an I2C bus running at only 25 kbps. I2C devices can typically operate faster than this, 50 kbps should be fine for all devices (and compliant devices can always stretch the clock if needed.) FWIW, the vast majority of framebuffer drivers set udelay to 10 already. So set it to 10 in DRM drivers too, this will make EDID block reads faster. We might even lower the udelay value later if no problem is reported. Signed-off-by: Jean Delvare Acked-by: Eugeni Dodonov Cc: Keith Packard Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/i915/intel_i2c.c | 2 +- drivers/gpu/drm/radeon/radeon_i2c.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index d30ccccb9d7..7fa4f640e6f 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -37,7 +37,7 @@ /* Intel GPIO access functions */ -#define I2C_RISEFALL_TIME 20 +#define I2C_RISEFALL_TIME 10 static inline struct intel_gmbus * to_intel_gmbus(struct i2c_adapter *i2c) diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 98a8ad68010..b7ec89bf393 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -925,7 +925,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->algo.bit.setscl = set_clock; i2c->algo.bit.getsda = get_data; i2c->algo.bit.getscl = get_clock; - i2c->algo.bit.udelay = 20; + i2c->algo.bit.udelay = 10; /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always * make this, 2 jiffies is a lot more reliable */ i2c->algo.bit.timeout = 2; -- cgit v1.2.3-70-g09d2 From 9048955748aa14b1dbf068ef3a9288ec15cabc66 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 28 Jan 2012 11:08:58 +0100 Subject: drm/radeon/kms: Use the standard VESA timeout for DDC channels The VESA specification suggests a 2.2 ms timeout on DDC channels. Use exactly that (as the i915 driver does) instead of hard-coding a jiffy count. Signed-off-by: Jean Delvare Reviewed-by: Keith Packard Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_i2c.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index b7ec89bf393..c47f222f744 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -926,9 +926,7 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, i2c->algo.bit.getsda = get_data; i2c->algo.bit.getscl = get_clock; i2c->algo.bit.udelay = 10; - /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always - * make this, 2 jiffies is a lot more reliable */ - i2c->algo.bit.timeout = 2; + i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ i2c->algo.bit.data = i2c; ret = i2c_bit_add_bus(&i2c->adapter); if (ret) { -- cgit v1.2.3-70-g09d2 From 30388c6e48e62b2806b14552275f091e2f5adbf4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 20 Jan 2012 14:50:18 -0500 Subject: drm/radeon/kms/dce3+: add support for hw i2c using atom Starting with DCE3 hardware, atom contains a general purpose ProcessI2cChannelTransaction similar to ProcessAuxChannelTransaction. Add an implementation using the atom tables for DCE3+ hardware. This should be a little less CPU intensive than bit banging and may work better in certain cases. Enable it by setting the radeon hw_i2c module parameter to 1. E.g., radeon.hw_i2c=1 on the kernel command line in grub. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/Makefile | 2 +- drivers/gpu/drm/radeon/atombios_i2c.c | 139 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_i2c.c | 21 +++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/radeon/atombios_i2c.c (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 2139fe893ec..84104153a68 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ - radeon_semaphore.o radeon_sa.o + radeon_semaphore.o radeon_sa.o atombios_i2c.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c new file mode 100644 index 00000000000..44d87b6b422 --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_i2c.c @@ -0,0 +1,139 @@ +/* + * Copyright 2011 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Alex Deucher + * + */ +#include "drmP.h" +#include "radeon_drm.h" +#include "radeon.h" +#include "atom.h" + +#define TARGET_HW_I2C_CLOCK 50 + +/* these are a limitation of ProcessI2cChannelTransaction not the hw */ +#define ATOM_MAX_HW_I2C_WRITE 2 +#define ATOM_MAX_HW_I2C_READ 255 + +static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, + u8 slave_addr, u8 flags, + u8 *buf, u8 num) +{ + struct drm_device *dev = chan->dev; + struct radeon_device *rdev = dev->dev_private; + PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; + int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); + unsigned char *base; + u16 out; + + memset(&args, 0, sizeof(args)); + + base = (unsigned char *)rdev->mode_info.atom_context->scratch; + + if (flags & HW_I2C_WRITE) { + if (num > ATOM_MAX_HW_I2C_WRITE) { + DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num); + return -EINVAL; + } + memcpy(&out, buf, num); + args.lpI2CDataOut = cpu_to_le16(out); + } else { + if (num > ATOM_MAX_HW_I2C_READ) { + DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); + return -EINVAL; + } + } + + args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; + args.ucRegIndex = 0; + args.ucTransBytes = num; + args.ucSlaveAddr = slave_addr << 1; + args.ucLineNumber = chan->rec.i2c_id; + + atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); + + /* error */ + if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { + DRM_DEBUG_KMS("hw_i2c error\n"); + return -EIO; + } + + if (!(flags & HW_I2C_WRITE)) + memcpy(buf, base, num); + + return 0; +} + +int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num) +{ + struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); + struct i2c_msg *p; + int i, remaining, current_count, buffer_offset, max_bytes, ret; + u8 buf = 0, flags; + + /* check for bus probe */ + p = &msgs[0]; + if ((num == 1) && (p->len == 0)) { + ret = radeon_process_i2c_ch(i2c, + p->addr, HW_I2C_WRITE, + &buf, 1); + if (ret) + return ret; + else + return num; + } + + for (i = 0; i < num; i++) { + p = &msgs[i]; + remaining = p->len; + buffer_offset = 0; + /* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */ + if (p->flags & I2C_M_RD) { + max_bytes = ATOM_MAX_HW_I2C_READ; + flags = HW_I2C_READ; + } else { + max_bytes = ATOM_MAX_HW_I2C_WRITE; + flags = HW_I2C_WRITE; + } + while (remaining) { + if (remaining > max_bytes) + current_count = max_bytes; + else + current_count = remaining; + ret = radeon_process_i2c_ch(i2c, + p->addr, flags, + &p->buf[buffer_offset], current_count); + if (ret) + return ret; + remaining -= current_count; + buffer_offset += current_count; + } + } + + return num; +} + +u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; +} + diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index c47f222f744..3265a7a5797 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c @@ -30,6 +30,10 @@ #include "radeon.h" #include "atom.h" +extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg *msgs, int num); +extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); + /** * radeon_ddc_probe * @@ -882,6 +886,11 @@ static const struct i2c_algorithm radeon_i2c_algo = { .functionality = radeon_hw_i2c_func, }; +static const struct i2c_algorithm radeon_atom_i2c_algo = { + .master_xfer = radeon_atom_hw_i2c_xfer, + .functionality = radeon_atom_hw_i2c_func, +}; + struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, struct radeon_i2c_bus_rec *rec, const char *name) @@ -914,6 +923,18 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, DRM_ERROR("Failed to register hw i2c %s\n", name); goto out_free; } + } else if (rec->hw_capable && + radeon_hw_i2c && + ASIC_IS_DCE3(rdev)) { + /* hw i2c using atom */ + snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), + "Radeon i2c hw bus %s", name); + i2c->adapter.algo = &radeon_atom_i2c_algo; + ret = i2c_add_adapter(&i2c->adapter); + if (ret) { + DRM_ERROR("Failed to register hw i2c %s\n", name); + goto out_free; + } } else { /* set the radeon bit adapter */ snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), -- cgit v1.2.3-70-g09d2 From 9292f37e1f5c79400254dca46f83313488093825 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Thu, 5 Jan 2012 09:34:28 -0200 Subject: drm: give up on edid retries when i2c bus is not responding This allows to avoid talking to a non-responding bus repeatedly until we finally timeout after 15 attempts. We can do this by catching the -ENXIO error, provided by i2c_algo_bit:bit_doAddress call. Within the bit_doAddress we already try 3 times to get the edid data, so if the routine tells us that bus is not responding, it is mostly pointless to keep re-trying those attempts over and over again until we reach final number of retries. This change should fix https://bugs.freedesktop.org/show_bug.cgi?id=41059 and improve overall edid detection timing by 10-30% in most cases, and by a much larger margin in case of phantom outputs (up to 30x in one worst case). Timing results for i915-powered machines for 'time xrandr' command: Machine 1: from 0.840s to 0.290s Machine 2: from 0.315s to 0.280s Machine 3: from +/- 4s to 0.184s Timing results for HD5770 with 'time xrandr' command: Machine 4: from 3.210s to 1.060s Reviewed-by: Chris Wilson Reviewed-by: Keith Packard Tested-by: Sean Finney Tested-by: Soren Hansen Tested-by: Hernando Torque Tested-by: Mike Lothian Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=41059 Signed-off-by: Eugeni Dodonov Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ece03fc2d38..54a4efa0eef 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, } }; ret = i2c_transfer(adapter, msgs, 2); + if (ret == -ENXIO) { + DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", + adapter->name); + break; + } } while (ret != 2 && --retries); return ret == 2 ? 0 : -1; -- cgit v1.2.3-70-g09d2 From c9068eb296fc682513f8612168f605c169b773e4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 2 Feb 2012 10:11:11 -0500 Subject: drm/radeon/kms: add r1xx/r2xx support for CS_KEEP_TILING_FLAGS Previous patch only updates r3xx+. It's not likely anyone will use this on r1xx/r2xx, but add it for consistency. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 46 ++++++++++++++++++++++++------------------- drivers/gpu/drm/radeon/r200.c | 17 +++++++++------- 2 files changed, 36 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a..7dd6a1c4734 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -87,23 +87,27 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } + value = radeon_get_ib_value(p, idx); tmp = value & 0x003fffff; tmp += (((u32)reloc->lobj.gpu_offset) >> 10); - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_DST_TILE_MACRO; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { - if (reg == RADEON_SRC_PITCH_OFFSET) { - DRM_ERROR("Cannot src blit from microtiled surface\n"); - r100_cs_dump_packet(p, pkt); - return -EINVAL; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_DST_TILE_MACRO; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { + if (reg == RADEON_SRC_PITCH_OFFSET) { + DRM_ERROR("Cannot src blit from microtiled surface\n"); + r100_cs_dump_packet(p, pkt); + return -EINVAL; + } + tile_flags |= RADEON_DST_TILE_MICRO; } - tile_flags |= RADEON_DST_TILE_MICRO; - } - tmp |= tile_flags; - p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; + tmp |= tile_flags; + p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; + } else + p->ib->ptr[idx] = (value & 0xffc00000) | tmp; return 0; } @@ -1625,15 +1629,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_COLOR_TILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; + + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; + } else + ib[idx] = idx_value; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; track->cb_dirty = true; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index eba4cbfa78f..2f44397f6df 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -277,14 +277,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, return r; } - if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) - tile_flags |= RADEON_COLOR_TILE_ENABLE; - if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) - tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_COLOR_TILE_ENABLE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; - tmp = idx_value & ~(0x7 << 16); - tmp |= tile_flags; - ib[idx] = tmp; + tmp = idx_value & ~(0x7 << 16); + tmp |= tile_flags; + ib[idx] = tmp; + } else + ib[idx] = idx_value; track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; track->cb_dirty = true; -- cgit v1.2.3-70-g09d2 From f2746f83d50287fdb6768e0f20168c64b6a7c9cb Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 2 Feb 2012 10:11:12 -0500 Subject: drm/radeon/kms: add r1xx/r2xx CS support for tiled textures Not likely this will be implemented anytime soon, but for completeness... Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 12 +++++++++++- drivers/gpu/drm/radeon/r200.c | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 7dd6a1c4734..99bb0064935 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -1558,7 +1558,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= RADEON_TXO_MACRO_TILE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= RADEON_TXO_MICRO_TILE_X2; + + tmp = idx_value & ~(0x7 << 2); + tmp |= tile_flags; + ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); + } else + ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; track->tex_dirty = true; break; diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index 2f44397f6df..a59cc474d53 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c @@ -215,7 +215,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, r100_cs_dump_packet(p, pkt); return r; } - ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); + if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { + if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) + tile_flags |= R200_TXO_MACRO_TILE; + if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) + tile_flags |= R200_TXO_MICRO_TILE; + + tmp = idx_value & ~(0x7 << 2); + tmp |= tile_flags; + ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); + } else + ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); track->textures[i].robj = reloc->robj; track->tex_dirty = true; break; -- cgit v1.2.3-70-g09d2 From 59ce062ead2a7d114a1e7f505f250eabab9e9d85 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:20 +0100 Subject: drm crtc: add forgotten idr cleanup functions drm_mode_config_init initializes the idr with idr_init, so add the missing counterparts in drm_mode_config_cleanup. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5e818a808ac..c1a0d346b0c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -1048,6 +1048,9 @@ void drm_mode_config_cleanup(struct drm_device *dev) head) { plane->funcs->destroy(plane); } + + idr_remove_all(&dev->mode_config.crtc_idr); + idr_destroy(&dev->mode_config.crtc_idr); } EXPORT_SYMBOL(drm_mode_config_cleanup); -- cgit v1.2.3-70-g09d2 From aefd330e694d5b7b9657cc53821c7879b14c8128 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:21 +0100 Subject: drm/edid: drm modes have to be free with drm_mode_destroy to add the missing drm_mode_object_put for that mode. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_edid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 54a4efa0eef..7ee7be1e5ce 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -750,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, */ mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { - kfree(mode); + drm_mode_destroy(dev, mode); mode = drm_gtf_mode_complex(dev, hsize, vsize, vrefresh_rate, 0, 0, drm_gtf2_m(edid), -- cgit v1.2.3-70-g09d2 From 554f1d7888d4a1055965198d0ac46ba50e8b684e Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:19 +0100 Subject: drm crtc: use drm_mode_destroy instead of kfree in drm_mode_remove Modes are created using drm_mode_create which does a drm_mode_object_get, so use drm_mode_destroy in drm_mode_remove which does a drm_mode_object_put. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index c1a0d346b0c..33ebe291d18 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -442,7 +442,7 @@ void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode) { list_del(&mode->head); - kfree(mode); + drm_mode_destroy(connector->dev, mode); } EXPORT_SYMBOL(drm_mode_remove); -- cgit v1.2.3-70-g09d2 From a1b7736dac5f2d5876e68c47a0fce3f423840070 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:22 +0100 Subject: drm drm_fb_helper: destroy modes drm_setup_crtcs allocated modes using drm_mode_duplicate. Free them in drm_fb_helper_crtc_free. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index aada26f63de..77fec5a9383 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -430,8 +430,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) for (i = 0; i < helper->connector_count; i++) kfree(helper->connector_info[i]); kfree(helper->connector_info); - for (i = 0; i < helper->crtc_count; i++) + for (i = 0; i < helper->crtc_count; i++) { kfree(helper->crtc_info[i].mode_set.connectors); + if (helper->crtc_info[i].mode_set.mode) + drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode); + } kfree(helper->crtc_info); } -- cgit v1.2.3-70-g09d2 From 4cae5b84628d5df76247d494e51b89d07e28e6aa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:23 +0100 Subject: drm: add proper return value for drm_mode_crtc_set_gamma_size drm_mode_crtc_set_gamma_size returns boolean true for success and false for failure. This is not very kernel conform, so change it to return 0 for success and a propert error code otherwise. Noone checks the return value, so no users have to be fixed. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 6 +++--- include/drm/drm_crtc.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 33ebe291d18..df6e4135680 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -3024,7 +3024,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector, } EXPORT_SYMBOL(drm_mode_connector_detach_encoder); -bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, +int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size) { crtc->gamma_size = gamma_size; @@ -3032,10 +3032,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); if (!crtc->gamma_store) { crtc->gamma_size = 0; - return false; + return -ENOMEM; } - return true; + return 0; } EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 4cd4be26722..8d593ad95f1 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -919,7 +919,7 @@ extern int drm_mode_connector_attach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); extern void drm_mode_connector_detach_encoder(struct drm_connector *connector, struct drm_encoder *encoder); -extern bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, +extern int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, int gamma_size); extern struct drm_mode_object *drm_mode_object_find(struct drm_device *dev, uint32_t id, uint32_t type); -- cgit v1.2.3-70-g09d2 From 3a8148c514b45672f876c4d7c23ed1f54e7c48e7 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:24 +0100 Subject: drm fb helper: use drm_helper_connector_dpms to do dpms drm_fb_helper_on|off currently manually searches for encoders to turn on/off. Make this simpler by using the helper function. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 80 ++++++----------------------------------- 1 file changed, 10 insertions(+), 70 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 77fec5a9383..4fc38a7fc0b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; #endif -static void drm_fb_helper_on(struct fb_info *info) +static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) { struct drm_fb_helper *fb_helper = info->par; struct drm_device *dev = fb_helper->dev; struct drm_crtc *crtc; - struct drm_crtc_helper_funcs *crtc_funcs; struct drm_connector *connector; - struct drm_encoder *encoder; int i, j; /* - * For each CRTC in this fb, turn the crtc on then, - * find all associated encoders and turn them on. + * For each CRTC in this fb, turn the connectors on/off. */ mutex_lock(&dev->mode_config.mutex); for (i = 0; i < fb_helper->crtc_count; i++) { crtc = fb_helper->crtc_info[i].mode_set.crtc; - crtc_funcs = crtc->helper_private; if (!crtc->enabled) continue; - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); - - /* Walk the connectors & encoders on this fb turning them on */ + /* Walk the connectors & encoders on this fb turning them on/off */ for (j = 0; j < fb_helper->connector_count; j++) { connector = fb_helper->connector_info[j]->connector; - connector->dpms = DRM_MODE_DPMS_ON; + drm_helper_connector_dpms(connector, dpms_mode); drm_connector_property_set_value(connector, - dev->mode_config.dpms_property, - DRM_MODE_DPMS_ON); - } - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); - } - } - } - mutex_unlock(&dev->mode_config.mutex); -} - -static void drm_fb_helper_off(struct fb_info *info, int dpms_mode) -{ - struct drm_fb_helper *fb_helper = info->par; - struct drm_device *dev = fb_helper->dev; - struct drm_crtc *crtc; - struct drm_crtc_helper_funcs *crtc_funcs; - struct drm_connector *connector; - struct drm_encoder *encoder; - int i, j; - - /* - * For each CRTC in this fb, find all associated encoders - * and turn them off, then turn off the CRTC. - */ - mutex_lock(&dev->mode_config.mutex); - for (i = 0; i < fb_helper->crtc_count; i++) { - crtc = fb_helper->crtc_info[i].mode_set.crtc; - crtc_funcs = crtc->helper_private; - - if (!crtc->enabled) - continue; - - /* Walk the connectors on this fb and mark them off */ - for (j = 0; j < fb_helper->connector_count; j++) { - connector = fb_helper->connector_info[j]->connector; - connector->dpms = dpms_mode; - drm_connector_property_set_value(connector, - dev->mode_config.dpms_property, - dpms_mode); - } - /* Found a CRTC on this fb, now find encoders */ - list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc == crtc) { - struct drm_encoder_helper_funcs *encoder_funcs; - - encoder_funcs = encoder->helper_private; - encoder_funcs->dpms(encoder, dpms_mode); - } + dev->mode_config.dpms_property, dpms_mode); } - crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); } mutex_unlock(&dev->mode_config.mutex); } @@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info) switch (blank) { /* Display: On; HSync: On, VSync: On */ case FB_BLANK_UNBLANK: - drm_fb_helper_on(info); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON); break; /* Display: Off; HSync: On, VSync: On */ case FB_BLANK_NORMAL: - drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); break; /* Display: Off; HSync: Off, VSync: On */ case FB_BLANK_HSYNC_SUSPEND: - drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); break; /* Display: Off; HSync: On, VSync: Off */ case FB_BLANK_VSYNC_SUSPEND: - drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND); break; /* Display: Off; HSync: Off, VSync: Off */ case FB_BLANK_POWERDOWN: - drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); + drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF); break; } return 0; -- cgit v1.2.3-70-g09d2 From e9ad318128aa858f713d6f2c4623f7583ca53a71 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:25 +0100 Subject: drm fb helper: remove unused variable conn_limit conn_limit is set but never used. Remove it from struct drm_fb_helper. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 2 +- include/drm/drm_fb_helper.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 4fc38a7fc0b..7b37874741f 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -421,7 +421,7 @@ int drm_fb_helper_init(struct drm_device *dev, fb_helper->crtc_info[i].mode_set.crtc = crtc; i++; } - fb_helper->conn_limit = max_conn_count; + return 0; out_free: drm_fb_helper_crtc_free(fb_helper); diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 6e3076ad646..55e10d62eab 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -74,7 +74,6 @@ struct drm_fb_helper { int connector_count; struct drm_fb_helper_connector **connector_info; struct drm_fb_helper_funcs *funcs; - int conn_limit; struct fb_info *fbdev; u32 pseudo_palette[17]; struct list_head kernel_fb_list; -- cgit v1.2.3-70-g09d2 From 4f988d132d2668b4f3b42bfc70daa531115ccca1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:26 +0100 Subject: drm fb helper: remove unused variable crtc_id crtc_id is set but never used, so remove it from struct drm_fb_helper_crtc. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 1 - include/drm/drm_fb_helper.h | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 7b37874741f..7740dd26f00 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -417,7 +417,6 @@ int drm_fb_helper_init(struct drm_device *dev, i = 0; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { - fb_helper->crtc_info[i].crtc_id = crtc->base.id; fb_helper->crtc_info[i].mode_set.crtc = crtc; i++; } diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 55e10d62eab..5120b01c2ee 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h @@ -35,7 +35,6 @@ struct drm_fb_helper; #include struct drm_fb_helper_crtc { - uint32_t crtc_id; struct drm_mode_set mode_set; struct drm_display_mode *desired_mode; }; -- cgit v1.2.3-70-g09d2 From b20f38679fee704d5ebfe2815fb5af492a0dde9f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:31 +0100 Subject: drm crtc: Fix locking comments Several comments above functions say that the caller must hold the mode_config lock, but the functions take the lock themselves. Fix the comments. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index df6e4135680..322bc7b1300 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -454,7 +454,7 @@ EXPORT_SYMBOL(drm_mode_remove); * @name: user visible name of the connector * * LOCKING: - * Caller must hold @dev's mode_config lock. + * Takes mode config lock. * * Initialises a preallocated connector. Connectors should be * subclassed as part of driver connector objects. @@ -497,7 +497,7 @@ EXPORT_SYMBOL(drm_connector_init); * @connector: connector to cleanup * * LOCKING: - * Caller must hold @dev's mode_config lock. + * Takes mode config lock. * * Cleans up the connector but doesn't free the object. */ @@ -1314,7 +1314,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Construct a CRTC configuration structure to return to the user. * @@ -1374,7 +1374,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Construct a connector configuration structure to return to the user. * @@ -1556,6 +1556,9 @@ out: * @data: ioctl data * @file_priv: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Return an plane count and set of IDs. */ int drm_mode_getplane_res(struct drm_device *dev, void *data, @@ -1602,6 +1605,9 @@ out: * @data: ioctl data * @file_priv: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Return plane info, including formats supported, gamma size, any * current fb, etc. */ @@ -1667,6 +1673,9 @@ out: * @data: ioctl data* * @file_prive: DRM file info * + * LOCKING: + * Takes mode config lock. + * * Set plane info, including placement, fb, scaling, and other factors. * Or pass a NULL fb to disable. */ @@ -1797,7 +1806,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Build a new CRTC configuration based on user request. * @@ -2278,7 +2287,7 @@ out: * @arg: arg from ioctl * * LOCKING: - * Caller? (FIXME) + * Takes mode config lock. * * Lookup the FB given its ID and return info about it. * -- cgit v1.2.3-70-g09d2 From a1178ca06213ba937b20d3d32102f64c15dd9a9d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:30 +0100 Subject: drm crtc_helper: use list_for_each_entry list_for_each_entry_safe is for walking a list safe against removal of entries. Here, no entries are removed, so use list_for_each_entry. Signed-off-by: Sascha Hauer Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 84a4a809793..d761d124115 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600); static void drm_mode_validate_flag(struct drm_connector *connector, int flags) { - struct drm_display_mode *mode, *t; + struct drm_display_mode *mode; if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) return; - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && !(flags & DRM_MODE_FLAG_INTERLACE)) mode->status = MODE_NO_INTERLACE; @@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY) { struct drm_device *dev = connector->dev; - struct drm_display_mode *mode, *t; + struct drm_display_mode *mode; struct drm_connector_helper_funcs *connector_funcs = connector->helper_private; int count = 0; @@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, drm_get_connector_name(connector)); /* set all modes to the unverified state */ - list_for_each_entry_safe(mode, t, &connector->modes, head) + list_for_each_entry(mode, &connector->modes, head) mode->status = MODE_UNVERIFIED; if (connector->force) { @@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, mode_flags |= DRM_MODE_FLAG_DBLSCAN; drm_mode_validate_flag(connector, mode_flags); - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { if (mode->status == MODE_OK) mode->status = connector_funcs->mode_valid(connector, mode); @@ -152,7 +152,7 @@ prune: DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, drm_get_connector_name(connector)); - list_for_each_entry_safe(mode, t, &connector->modes, head) { + list_for_each_entry(mode, &connector->modes, head) { mode->vrefresh = drm_mode_vrefresh(mode); drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); -- cgit v1.2.3-70-g09d2 From 83b316fdafcc37e3e65b4a650afb7aab5cc2d271 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 1 Feb 2012 11:38:37 +0100 Subject: drm exynos: use drm_fb_helper_set_par directly info->fix.visual already is correctly set from drm_fb_helper_fill_fix. info->fix.line_length is also set from drm_fb_helper_fill_fix, so drm_fb_helper_set_par directly instead of a custom exynos_drm_fbdev_set_par. Signed-off-by: Sascha Hauer Tested-by: Inki Dae Signed-off-by: Dave Airlie --- drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d7ae29d2f3d..5737bc5e6ed 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -46,39 +46,13 @@ struct exynos_drm_fbdev { struct exynos_drm_gem_obj *exynos_gem_obj; }; -static int exynos_drm_fbdev_set_par(struct fb_info *info) -{ - struct fb_var_screeninfo *var = &info->var; - - switch (var->bits_per_pixel) { - case 32: - case 24: - case 18: - case 16: - case 12: - info->fix.visual = FB_VISUAL_TRUECOLOR; - break; - case 1: - info->fix.visual = FB_VISUAL_MONO01; - break; - default: - info->fix.visual = FB_VISUAL_PSEUDOCOLOR; - break; - } - - info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; - - return drm_fb_helper_set_par(info); -} - - static struct fb_ops exynos_drm_fb_ops = { .owner = THIS_MODULE, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = exynos_drm_fbdev_set_par, + .fb_set_par = drm_fb_helper_set_par, .fb_blank = drm_fb_helper_blank, .fb_pan_display = drm_fb_helper_pan_display, .fb_setcmap = drm_fb_helper_setcmap, -- cgit v1.2.3-70-g09d2 From 1b65fa8496059d919a16b8431672d11e199ae515 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Feb 2012 11:02:58 +0000 Subject: mfd: twl-core: Don't specify regulator consumers by struct device This has been deprecated for considerable time now and support has been removed from the regulator API. dev_name should be used instead. Signed-off-by: Mark Brown --- drivers/mfd/twl-core.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index e04e04ddc15..8dcf70f8d65 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -751,9 +751,9 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) /* we need to connect regulators to this transceiver */ if (twl_has_regulator() && child) { - usb1v5.dev = child; - usb1v8.dev = child; - usb3v1.dev = child; + usb1v5.dev_name = dev_name(child); + usb1v8.dev_name = dev_name(child); + usb3v1.dev_name = dev_name(child); } } if (twl_has_usb() && pdata->usb && twl_class_is_6030()) { @@ -799,7 +799,7 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); /* we need to connect regulators to this transceiver */ if (twl_has_regulator() && child) - usb3v3.dev = child; + usb3v3.dev_name = dev_name(child); } else if (twl_has_regulator() && twl_class_is_6030()) { if (features & TWL6025_SUBCLASS) child = add_regulator(TWL6025_REG_LDOUSB, -- cgit v1.2.3-70-g09d2 From 9918ceafd4a9e013572e03983f528017c29bb1cb Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 26 Jan 2012 14:07:09 +0100 Subject: ARM: at91: code removal of CAP9 SoC Following removal announce and addition to feature-removal-schedule.txt, here is the actual source code deletion for Atmel CAP9 family. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- Documentation/feature-removal-schedule.txt | 14 - arch/arm/Kconfig | 2 +- arch/arm/Kconfig.debug | 2 +- arch/arm/configs/at91cap9_defconfig | 108 -- arch/arm/mach-at91/Kconfig | 26 +- arch/arm/mach-at91/Makefile | 4 - arch/arm/mach-at91/Makefile.boot | 6 +- arch/arm/mach-at91/at91cap9.c | 404 ------- arch/arm/mach-at91/at91cap9_devices.c | 1273 --------------------- arch/arm/mach-at91/board-cap9adk.c | 396 ------- arch/arm/mach-at91/clock.c | 5 +- arch/arm/mach-at91/generic.h | 1 - arch/arm/mach-at91/include/mach/at91_pmc.h | 14 +- arch/arm/mach-at91/include/mach/at91cap9.h | 122 -- arch/arm/mach-at91/include/mach/at91cap9_matrix.h | 137 --- arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h | 10 - arch/arm/mach-at91/include/mach/cpu.h | 21 - arch/arm/mach-at91/include/mach/hardware.h | 4 +- arch/arm/mach-at91/pm.c | 5 - arch/arm/mach-at91/pm.h | 18 - arch/arm/mach-at91/pm_slowclock.S | 12 +- arch/arm/mach-at91/setup.c | 17 - arch/arm/mach-at91/soc.h | 5 - arch/avr32/mach-at32ap/include/mach/cpu.h | 3 - drivers/mmc/host/at91_mci.c | 1 - drivers/usb/gadget/Kconfig | 4 +- 26 files changed, 17 insertions(+), 2597 deletions(-) delete mode 100644 arch/arm/configs/at91cap9_defconfig delete mode 100644 arch/arm/mach-at91/at91cap9.c delete mode 100644 arch/arm/mach-at91/at91cap9_devices.c delete mode 100644 arch/arm/mach-at91/board-cap9adk.c delete mode 100644 arch/arm/mach-at91/include/mach/at91cap9.h delete mode 100644 arch/arm/mach-at91/include/mach/at91cap9_matrix.h (limited to 'drivers') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a0ffac029a0..1bea46a54b1 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -510,17 +510,3 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The convert to using pci_scan_root_bus() so they can supply a list of bus resources when the bus is created. Who: Bjorn Helgaas - ----------------------------- - -What: The CAP9 SoC family will be removed -When: 3.4 -Files: arch/arm/mach-at91/at91cap9.c - arch/arm/mach-at91/at91cap9_devices.c - arch/arm/mach-at91/include/mach/at91cap9.h - arch/arm/mach-at91/include/mach/at91cap9_matrix.h - arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h - arch/arm/mach-at91/board-cap9adk.c -Why: The code is not actively maintained and platforms are now hard to find. -Who: Nicolas Ferre - Jean-Christophe PLAGNIOL-VILLARD diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a48aecc17ea..92c9c79c140 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -324,7 +324,7 @@ config ARCH_AT91 select CLKDEV_LOOKUP help This enables support for systems based on the Atmel AT91RM9200, - AT91SAM9 and AT91CAP9 processors. + AT91SAM9 processors. config ARCH_BCMRING bool "Broadcom BCMRING" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 03646c4c13d..b895a2a92da 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -86,7 +86,7 @@ choice depends on HAVE_AT91_DBGU0 config AT91_DEBUG_LL_DBGU1 - bool "Kernel low-level debugging on 9263, 9g45 and cap9" + bool "Kernel low-level debugging on 9263 and 9g45" depends on HAVE_AT91_DBGU1 config DEBUG_CLPS711X_UART1 diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig deleted file mode 100644 index 8826eb218e7..00000000000 --- a/arch/arm/configs/at91cap9_defconfig +++ /dev/null @@ -1,108 +0,0 @@ -CONFIG_EXPERIMENTAL=y -# CONFIG_LOCALVERSION_AUTO is not set -# CONFIG_SWAP is not set -CONFIG_SYSVIPC=y -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_BLK_DEV_INITRD=y -CONFIG_SLAB=y -CONFIG_MODULES=y -CONFIG_MODULE_UNLOAD=y -# CONFIG_BLK_DEV_BSG is not set -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set -CONFIG_ARCH_AT91=y -CONFIG_ARCH_AT91CAP9=y -CONFIG_MACH_AT91CAP9ADK=y -CONFIG_MTD_AT91_DATAFLASH_CARD=y -CONFIG_AT91_PROGRAMMABLE_CLOCKS=y -# CONFIG_ARM_THUMB is not set -CONFIG_AEABI=y -CONFIG_LEDS=y -CONFIG_LEDS_CPU=y -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw" -CONFIG_FPE_NWFPE=y -CONFIG_NET=y -CONFIG_PACKET=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -# CONFIG_INET_XFRM_MODE_TUNNEL is not set -# CONFIG_INET_XFRM_MODE_BEET is not set -# CONFIG_INET_LRO is not set -# CONFIG_INET_DIAG is not set -# CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" -CONFIG_MTD=y -CONFIG_MTD_CMDLINE_PARTS=y -CONFIG_MTD_CHAR=y -CONFIG_MTD_BLOCK=y -CONFIG_MTD_CFI=y -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_PHYSMAP=y -CONFIG_MTD_DATAFLASH=y -CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ATMEL=y -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_SCSI_MULTI_LUN=y -CONFIG_NETDEVICES=y -CONFIG_MII=y -CONFIG_MACB=y -# CONFIG_INPUT_MOUSEDEV_PSAUX is not set -CONFIG_INPUT_EVDEV=y -# CONFIG_INPUT_KEYBOARD is not set -# CONFIG_INPUT_MOUSE is not set -CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_ADS7846=y -# CONFIG_SERIO is not set -CONFIG_SERIAL_ATMEL=y -CONFIG_SERIAL_ATMEL_CONSOLE=y -CONFIG_HW_RANDOM=y -CONFIG_I2C=y -CONFIG_I2C_CHARDEV=y -CONFIG_SPI=y -CONFIG_SPI_ATMEL=y -# CONFIG_HWMON is not set -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_FB=y -CONFIG_FB_ATMEL=y -CONFIG_LOGO=y -# CONFIG_LOGO_LINUX_MONO is not set -# CONFIG_LOGO_LINUX_CLUT224 is not set -# CONFIG_USB_HID is not set -CONFIG_USB=y -CONFIG_USB_DEVICEFS=y -CONFIG_USB_MON=y -CONFIG_USB_OHCI_HCD=y -CONFIG_USB_STORAGE=y -CONFIG_USB_GADGET=y -CONFIG_USB_ETH=m -CONFIG_USB_FILE_STORAGE=m -CONFIG_MMC=y -CONFIG_MMC_AT91=m -CONFIG_RTC_CLASS=y -CONFIG_RTC_DRV_AT91SAM9=y -CONFIG_EXT2_FS=y -CONFIG_VFAT_FS=y -CONFIG_TMPFS=y -CONFIG_JFFS2_FS=y -CONFIG_CRAMFS=y -CONFIG_NFS_FS=y -CONFIG_ROOT_NFS=y -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_850=y -CONFIG_NLS_ISO8859_1=y -CONFIG_DEBUG_FS=y -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_INFO=y -CONFIG_DEBUG_USER=y diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 71feb00a1e9..0284e66c47f 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -102,15 +102,6 @@ config ARCH_AT91SAM9G45 select HAVE_AT91_DBGU1 select AT91_SAM9G45_RESET -config ARCH_AT91CAP9 - bool "AT91CAP9" - select CPU_ARM926T - select GENERIC_CLOCKEVENTS - select HAVE_FB_ATMEL - select HAVE_NET_MACB - select HAVE_AT91_DBGU1 - select AT91_SAM9G45_RESET - config ARCH_AT91X40 bool "AT91x40" select ARCH_USES_GETTIMEOFFSET @@ -447,21 +438,6 @@ endif # ---------------------------------------------------------- -if ARCH_AT91CAP9 - -comment "AT91CAP9 Board Type" - -config MACH_AT91CAP9ADK - bool "Atmel AT91CAP9A-DK Evaluation Kit" - select HAVE_AT91_DATAFLASH_CARD - help - Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit. - - -endif - -# ---------------------------------------------------------- - if ARCH_AT91X40 comment "AT91X40 Board Type" @@ -544,7 +520,7 @@ config AT91_EARLY_DBGU0 depends on HAVE_AT91_DBGU0 config AT91_EARLY_DBGU1 - bool "DBGU on 9263, 9g45 and cap9" + bool "DBGU on 9263 and 9g45" depends on HAVE_AT91_DBGU1 config AT91_EARLY_USART0 diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 705e1fbded3..aeb76f1690d 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -20,7 +20,6 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o -obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o # AT91RM9200 board-specific support @@ -81,9 +80,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o # AT91SAM board with device-tree obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o -# AT91CAP9 board-specific support -obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o - # AT91X40 board-specific support obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot index 8ddafadfdc7..2fd051eb244 100644 --- a/arch/arm/mach-at91/Makefile.boot +++ b/arch/arm/mach-at91/Makefile.boot @@ -3,11 +3,7 @@ # PARAMS_PHYS must be within 4MB of ZRELADDR # INITRD_PHYS must be in RAM -ifeq ($(CONFIG_ARCH_AT91CAP9),y) - zreladdr-y += 0x70008000 -params_phys-y := 0x70000100 -initrd_phys-y := 0x70410000 -else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) +ifeq ($(CONFIG_ARCH_AT91SAM9G45),y) zreladdr-y += 0x70008000 params_phys-y := 0x70000100 initrd_phys-y := 0x70410000 diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c deleted file mode 100644 index 8967d75c2ea..00000000000 --- a/arch/arm/mach-at91/at91cap9.c +++ /dev/null @@ -1,404 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9.c - * - * Copyright (C) 2007 Stelian Pop - * Copyright (C) 2007 Lead Tech Design - * Copyright (C) 2007 Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ - -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "soc.h" -#include "generic.h" -#include "clock.h" -#include "sam9_smc.h" - -/* -------------------------------------------------------------------- - * Clocks - * -------------------------------------------------------------------- */ - -/* - * The peripheral clocks. - */ -static struct clk pioABCD_clk = { - .name = "pioABCD_clk", - .pmc_mask = 1 << AT91CAP9_ID_PIOABCD, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb0_clk = { - .name = "mpb0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb1_clk = { - .name = "mpb1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb2_clk = { - .name = "mpb2_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb3_clk = { - .name = "mpb3_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB3, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mpb4_clk = { - .name = "mpb4_clk", - .pmc_mask = 1 << AT91CAP9_ID_MPB4, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart0_clk = { - .name = "usart0_clk", - .pmc_mask = 1 << AT91CAP9_ID_US0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart1_clk = { - .name = "usart1_clk", - .pmc_mask = 1 << AT91CAP9_ID_US1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk usart2_clk = { - .name = "usart2_clk", - .pmc_mask = 1 << AT91CAP9_ID_US2, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc0_clk = { - .name = "mci0_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk mmc1_clk = { - .name = "mci1_clk", - .pmc_mask = 1 << AT91CAP9_ID_MCI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk can_clk = { - .name = "can_clk", - .pmc_mask = 1 << AT91CAP9_ID_CAN, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk twi_clk = { - .name = "twi_clk", - .pmc_mask = 1 << AT91CAP9_ID_TWI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi0_clk = { - .name = "spi0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk spi1_clk = { - .name = "spi1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SPI1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc0_clk = { - .name = "ssc0_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC0, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ssc1_clk = { - .name = "ssc1_clk", - .pmc_mask = 1 << AT91CAP9_ID_SSC1, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ac97_clk = { - .name = "ac97_clk", - .pmc_mask = 1 << AT91CAP9_ID_AC97C, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk tcb_clk = { - .name = "tcb_clk", - .pmc_mask = 1 << AT91CAP9_ID_TCB, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk pwm_clk = { - .name = "pwm_clk", - .pmc_mask = 1 << AT91CAP9_ID_PWMC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk macb_clk = { - .name = "pclk", - .pmc_mask = 1 << AT91CAP9_ID_EMAC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk aestdes_clk = { - .name = "aestdes_clk", - .pmc_mask = 1 << AT91CAP9_ID_AESTDES, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk adc_clk = { - .name = "adc_clk", - .pmc_mask = 1 << AT91CAP9_ID_ADC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk isi_clk = { - .name = "isi_clk", - .pmc_mask = 1 << AT91CAP9_ID_ISI, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk lcdc_clk = { - .name = "lcdc_clk", - .pmc_mask = 1 << AT91CAP9_ID_LCDC, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk dma_clk = { - .name = "dma_clk", - .pmc_mask = 1 << AT91CAP9_ID_DMA, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk udphs_clk = { - .name = "udphs_clk", - .pmc_mask = 1 << AT91CAP9_ID_UDPHS, - .type = CLK_TYPE_PERIPHERAL, -}; -static struct clk ohci_clk = { - .name = "ohci_clk", - .pmc_mask = 1 << AT91CAP9_ID_UHP, - .type = CLK_TYPE_PERIPHERAL, -}; - -static struct clk *periph_clocks[] __initdata = { - &pioABCD_clk, - &mpb0_clk, - &mpb1_clk, - &mpb2_clk, - &mpb3_clk, - &mpb4_clk, - &usart0_clk, - &usart1_clk, - &usart2_clk, - &mmc0_clk, - &mmc1_clk, - &can_clk, - &twi_clk, - &spi0_clk, - &spi1_clk, - &ssc0_clk, - &ssc1_clk, - &ac97_clk, - &tcb_clk, - &pwm_clk, - &macb_clk, - &aestdes_clk, - &adc_clk, - &isi_clk, - &lcdc_clk, - &dma_clk, - &udphs_clk, - &ohci_clk, - // irq0 .. irq1 -}; - -static struct clk_lookup periph_clocks_lookups[] = { - /* One additional fake clock for macb_hclk */ - CLKDEV_CON_ID("hclk", &macb_clk), - CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk), - CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk), - CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk), - CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk), - CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk), - CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk), - /* fake hclk clock */ - CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk), - CLKDEV_CON_ID("pioA", &pioABCD_clk), - CLKDEV_CON_ID("pioB", &pioABCD_clk), - CLKDEV_CON_ID("pioC", &pioABCD_clk), - CLKDEV_CON_ID("pioD", &pioABCD_clk), -}; - -static struct clk_lookup usart_clocks_lookups[] = { - CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk), - CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk), -}; - -/* - * The four programmable clocks. - * You must configure pin multiplexing to bring these signals out. - */ -static struct clk pck0 = { - .name = "pck0", - .pmc_mask = AT91_PMC_PCK0, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 0, -}; -static struct clk pck1 = { - .name = "pck1", - .pmc_mask = AT91_PMC_PCK1, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 1, -}; -static struct clk pck2 = { - .name = "pck2", - .pmc_mask = AT91_PMC_PCK2, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 2, -}; -static struct clk pck3 = { - .name = "pck3", - .pmc_mask = AT91_PMC_PCK3, - .type = CLK_TYPE_PROGRAMMABLE, - .id = 3, -}; - -static void __init at91cap9_register_clocks(void) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(periph_clocks); i++) - clk_register(periph_clocks[i]); - - clkdev_add_table(periph_clocks_lookups, - ARRAY_SIZE(periph_clocks_lookups)); - clkdev_add_table(usart_clocks_lookups, - ARRAY_SIZE(usart_clocks_lookups)); - - clk_register(&pck0); - clk_register(&pck1); - clk_register(&pck2); - clk_register(&pck3); -} - -static struct clk_lookup console_clock_lookup; - -void __init at91cap9_set_console_clock(int id) -{ - if (id >= ARRAY_SIZE(usart_clocks_lookups)) - return; - - console_clock_lookup.con_id = "usart"; - console_clock_lookup.clk = usart_clocks_lookups[id].clk; - clkdev_add(&console_clock_lookup); -} - -/* -------------------------------------------------------------------- - * GPIO - * -------------------------------------------------------------------- */ - -static struct at91_gpio_bank at91cap9_gpio[] __initdata = { - { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOA, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOB, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOC, - }, { - .id = AT91CAP9_ID_PIOABCD, - .regbase = AT91CAP9_BASE_PIOD, - } -}; - -static void at91cap9_idle(void) -{ - at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK); - cpu_do_idle(); -} - -/* -------------------------------------------------------------------- - * AT91CAP9 processor initialization - * -------------------------------------------------------------------- */ - -static void __init at91cap9_map_io(void) -{ - at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE); -} - -static void __init at91cap9_ioremap_registers(void) -{ - at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC); - at91_ioremap_rstc(AT91CAP9_BASE_RSTC); - at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT); - at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC); -} - -static void __init at91cap9_initialize(void) -{ - arm_pm_idle = at91cap9_idle; - arm_pm_restart = at91sam9g45_restart; - at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1); - - /* Register GPIO subsystem */ - at91_gpio_init(at91cap9_gpio, 4); - - /* Remember the silicon revision */ - if (cpu_is_at91cap9_revB()) - system_rev = 0xB; - else if (cpu_is_at91cap9_revC()) - system_rev = 0xC; -} - -/* -------------------------------------------------------------------- - * Interrupt initialization - * -------------------------------------------------------------------- */ - -/* - * The default interrupt priority levels (0 = lowest, 7 = highest). - */ -static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = { - 7, /* Advanced Interrupt Controller (FIQ) */ - 7, /* System Peripherals */ - 1, /* Parallel IO Controller A, B, C and D */ - 0, /* MP Block Peripheral 0 */ - 0, /* MP Block Peripheral 1 */ - 0, /* MP Block Peripheral 2 */ - 0, /* MP Block Peripheral 3 */ - 0, /* MP Block Peripheral 4 */ - 5, /* USART 0 */ - 5, /* USART 1 */ - 5, /* USART 2 */ - 0, /* Multimedia Card Interface 0 */ - 0, /* Multimedia Card Interface 1 */ - 3, /* CAN */ - 6, /* Two-Wire Interface */ - 5, /* Serial Peripheral Interface 0 */ - 5, /* Serial Peripheral Interface 1 */ - 4, /* Serial Synchronous Controller 0 */ - 4, /* Serial Synchronous Controller 1 */ - 5, /* AC97 Controller */ - 0, /* Timer Counter 0, 1 and 2 */ - 0, /* Pulse Width Modulation Controller */ - 3, /* Ethernet */ - 0, /* Advanced Encryption Standard, Triple DES*/ - 0, /* Analog-to-Digital Converter */ - 0, /* Image Sensor Interface */ - 3, /* LCD Controller */ - 0, /* DMA Controller */ - 2, /* USB Device Port */ - 2, /* USB Host port */ - 0, /* Advanced Interrupt Controller (IRQ0) */ - 0, /* Advanced Interrupt Controller (IRQ1) */ -}; - -struct at91_init_soc __initdata at91cap9_soc = { - .map_io = at91cap9_map_io, - .default_irq_priority = at91cap9_default_irq_priority, - .ioremap_registers = at91cap9_ioremap_registers, - .register_clocks = at91cap9_register_clocks, - .init = at91cap9_initialize, -}; diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c deleted file mode 100644 index d298fb7cb21..00000000000 --- a/arch/arm/mach-at91/at91cap9_devices.c +++ /dev/null @@ -1,1273 +0,0 @@ -/* - * arch/arm/mach-at91/at91cap9_devices.c - * - * Copyright (C) 2007 Stelian Pop - * Copyright (C) 2007 Lead Tech Design - * Copyright (C) 2007 Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -#include -#include -#include - -#include -#include -#include -#include - -#include