aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2006-01-13 04:59:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-01-31 20:23:40 -0500
commit80aae7a17afd21f7ba900dd566fb23a2444021f8 (patch)
tree2193fe416373daddbc2b1da8bca61664081b927b /drivers
parent6f7494759870ec6fbb066f7202c5585fe36fbe82 (diff)
[PATCH] USBATM: allow isochronous transfer
While the usbatm core has had some support for using isoc urbs for some time, there was no way for users to turn it on. While use of isoc transfer should still be considered experimental, it now works well enough to let users turn it on. Minidrivers signal to the core that they want to use isoc transfer by setting the new UDSL_USE_ISOC flag. The speedtch minidriver gets a new module parameter enable_isoc (defaults to false), plus some logic that checks for the existence of an isoc receive endpoint (not all speedtouch modems have one). Signed-off-by: Duncan Sands <baldrick@free.fr> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/atm/cxacru.c4
-rw-r--r--drivers/usb/atm/speedtch.c82
-rw-r--r--drivers/usb/atm/ueagle-atm.c4
-rw-r--r--drivers/usb/atm/usbatm.c30
-rw-r--r--drivers/usb/atm/usbatm.h7
-rw-r--r--drivers/usb/atm/xusbatm.c4
6 files changed, 92 insertions, 39 deletions
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c
index 675fdbd5967e..70a96e98152c 100644
--- a/drivers/usb/atm/cxacru.c
+++ b/drivers/usb/atm/cxacru.c
@@ -836,8 +836,8 @@ static struct usbatm_driver cxacru_driver = {
836 .heavy_init = cxacru_heavy_init, 836 .heavy_init = cxacru_heavy_init,
837 .unbind = cxacru_unbind, 837 .unbind = cxacru_unbind,
838 .atm_start = cxacru_atm_start, 838 .atm_start = cxacru_atm_start,
839 .in = CXACRU_EP_DATA, 839 .bulk_in = CXACRU_EP_DATA,
840 .out = CXACRU_EP_DATA, 840 .bulk_out = CXACRU_EP_DATA,
841 .rx_padding = 3, 841 .rx_padding = 3,
842 .tx_padding = 11, 842 .tx_padding = 11,
843}; 843};
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index 0e981672f149..8c1c560cf051 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -35,6 +35,8 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/stat.h> 36#include <linux/stat.h>
37#include <linux/timer.h> 37#include <linux/timer.h>
38#include <linux/types.h>
39#include <linux/usb_ch9.h>
38#include <linux/workqueue.h> 40#include <linux/workqueue.h>
39 41
40#include "usbatm.h" 42#include "usbatm.h"
@@ -66,24 +68,33 @@ static const char speedtch_driver_name[] = "speedtch";
66 68
67#define RESUBMIT_DELAY 1000 /* milliseconds */ 69#define RESUBMIT_DELAY 1000 /* milliseconds */
68 70
69#define DEFAULT_ALTSETTING 1 71#define DEFAULT_BULK_ALTSETTING 1
72#define DEFAULT_ISOC_ALTSETTING 2
70#define DEFAULT_DL_512_FIRST 0 73#define DEFAULT_DL_512_FIRST 0
74#define DEFAULT_ENABLE_ISOC 0
71#define DEFAULT_SW_BUFFERING 0 75#define DEFAULT_SW_BUFFERING 0
72 76
73static int altsetting = DEFAULT_ALTSETTING; 77static unsigned int altsetting = 0; /* zero means: use the default */
74static int dl_512_first = DEFAULT_DL_512_FIRST; 78static int dl_512_first = DEFAULT_DL_512_FIRST;
79static int enable_isoc = DEFAULT_ENABLE_ISOC;
75static int sw_buffering = DEFAULT_SW_BUFFERING; 80static int sw_buffering = DEFAULT_SW_BUFFERING;
76 81
77module_param(altsetting, int, S_IRUGO | S_IWUSR); 82module_param(altsetting, uint, S_IRUGO | S_IWUSR);
78MODULE_PARM_DESC(altsetting, 83MODULE_PARM_DESC(altsetting,
79 "Alternative setting for data interface (default: " 84 "Alternative setting for data interface (bulk_default: "
80 __MODULE_STRING(DEFAULT_ALTSETTING) ")"); 85 __MODULE_STRING(DEFAULT_BULK_ALTSETTING) "; isoc_default: "
86 __MODULE_STRING(DEFAULT_ISOC_ALTSETTING) ")");
81 87
82module_param(dl_512_first, bool, S_IRUGO | S_IWUSR); 88module_param(dl_512_first, bool, S_IRUGO | S_IWUSR);
83MODULE_PARM_DESC(dl_512_first, 89MODULE_PARM_DESC(dl_512_first,
84 "Read 512 bytes before sending firmware (default: " 90 "Read 512 bytes before sending firmware (default: "
85 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")"); 91 __MODULE_STRING(DEFAULT_DL_512_FIRST) ")");
86 92
93module_param(enable_isoc, bool, S_IRUGO | S_IWUSR);
94MODULE_PARM_DESC(enable_isoc,
95 "Use isochronous transfers if available (default: "
96 __MODULE_STRING(DEFAULT_ENABLE_ISOC) ")");
97
87module_param(sw_buffering, bool, S_IRUGO | S_IWUSR); 98module_param(sw_buffering, bool, S_IRUGO | S_IWUSR);
88MODULE_PARM_DESC(sw_buffering, 99MODULE_PARM_DESC(sw_buffering,
89 "Enable software buffering (default: " 100 "Enable software buffering (default: "
@@ -91,7 +102,8 @@ MODULE_PARM_DESC(sw_buffering,
91 102
92#define INTERFACE_DATA 1 103#define INTERFACE_DATA 1
93#define ENDPOINT_INT 0x81 104#define ENDPOINT_INT 0x81
94#define ENDPOINT_DATA 0x07 105#define ENDPOINT_BULK_DATA 0x07
106#define ENDPOINT_ISOC_DATA 0x07
95#define ENDPOINT_FIRMWARE 0x05 107#define ENDPOINT_FIRMWARE 0x05
96 108
97#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) ) 109#define hex2int(c) ( (c >= '0') && (c <= '9') ? (c - '0') : ((c & 0xf) + 9) )
@@ -687,11 +699,12 @@ static int speedtch_bind(struct usbatm_data *usbatm,
687 const struct usb_device_id *id) 699 const struct usb_device_id *id)
688{ 700{
689 struct usb_device *usb_dev = interface_to_usbdev(intf); 701 struct usb_device *usb_dev = interface_to_usbdev(intf);
690 struct usb_interface *cur_intf; 702 struct usb_interface *cur_intf, *data_intf;
691 struct speedtch_instance_data *instance; 703 struct speedtch_instance_data *instance;
692 int ifnum = intf->altsetting->desc.bInterfaceNumber; 704 int ifnum = intf->altsetting->desc.bInterfaceNumber;
693 int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces; 705 int num_interfaces = usb_dev->actconfig->desc.bNumInterfaces;
694 int i, ret; 706 int i, ret;
707 int use_isoc;
695 708
696 usb_dbg(usbatm, "%s entered\n", __func__); 709 usb_dbg(usbatm, "%s entered\n", __func__);
697 710
@@ -702,6 +715,11 @@ static int speedtch_bind(struct usbatm_data *usbatm,
702 return -ENODEV; 715 return -ENODEV;
703 } 716 }
704 717
718 if (!(data_intf = usb_ifnum_to_if(usb_dev, INTERFACE_DATA))) {
719 usb_err(usbatm, "%s: data interface not found!\n", __func__);
720 return -ENODEV;
721 }
722
705 /* claim all interfaces */ 723 /* claim all interfaces */
706 724
707 for (i=0; i < num_interfaces; i++) { 725 for (i=0; i < num_interfaces; i++) {
@@ -728,8 +746,9 @@ static int speedtch_bind(struct usbatm_data *usbatm,
728 746
729 instance->usbatm = usbatm; 747 instance->usbatm = usbatm;
730 748
731 /* altsetting may change at any moment, so take a snapshot */ 749 /* altsetting and enable_isoc may change at any moment, so take a snapshot */
732 instance->altsetting = altsetting; 750 instance->altsetting = altsetting;
751 use_isoc = enable_isoc;
733 752
734 if (instance->altsetting) 753 if (instance->altsetting)
735 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) { 754 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, instance->altsetting)) < 0) {
@@ -737,14 +756,44 @@ static int speedtch_bind(struct usbatm_data *usbatm,
737 instance->altsetting = 0; /* fall back to default */ 756 instance->altsetting = 0; /* fall back to default */
738 } 757 }
739 758
740 if (!instance->altsetting) { 759 if (!instance->altsetting && use_isoc)
741 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ALTSETTING)) < 0) { 760 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_ISOC_ALTSETTING)) < 0) {
742 usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ALTSETTING, ret); 761 usb_dbg(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_ISOC_ALTSETTING, ret);
743 goto fail_free; 762 use_isoc = 0; /* fall back to bulk */
744 } 763 }
745 instance->altsetting = DEFAULT_ALTSETTING; 764
765 if (use_isoc) {
766 const struct usb_host_interface *desc = data_intf->cur_altsetting;
767 const __u8 target_address = USB_DIR_IN | usbatm->driver->isoc_in;
768 int i;
769
770 use_isoc = 0; /* fall back to bulk if endpoint not found */
771
772 for (i=0; i<desc->desc.bNumEndpoints; i++) {
773 const struct usb_endpoint_descriptor *endpoint_desc = &desc->endpoint[i].desc;
774
775 if ((endpoint_desc->bEndpointAddress == target_address)) {
776 use_isoc = (endpoint_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) ==
777 USB_ENDPOINT_XFER_ISOC;
778 break;
779 }
780 }
781
782 if (!use_isoc)
783 usb_info(usbatm, "isochronous transfer not supported - using bulk\n");
746 } 784 }
747 785
786 if (!use_isoc && !instance->altsetting)
787 if ((ret = usb_set_interface(usb_dev, INTERFACE_DATA, DEFAULT_BULK_ALTSETTING)) < 0) {
788 usb_err(usbatm, "%s: setting interface to %2d failed (%d)!\n", __func__, DEFAULT_BULK_ALTSETTING, ret);
789 goto fail_free;
790 }
791
792 if (!instance->altsetting)
793 instance->altsetting = use_isoc ? DEFAULT_ISOC_ALTSETTING : DEFAULT_BULK_ALTSETTING;
794
795 usbatm->flags |= (use_isoc ? UDSL_USE_ISOC : 0);
796
748 INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance); 797 INIT_WORK(&instance->status_checker, (void *)speedtch_check_status, instance);
749 798
750 instance->status_checker.timer.function = speedtch_status_poll; 799 instance->status_checker.timer.function = speedtch_status_poll;
@@ -771,7 +820,7 @@ static int speedtch_bind(struct usbatm_data *usbatm,
771 0x12, 0xc0, 0x07, 0x00, 820 0x12, 0xc0, 0x07, 0x00,
772 instance->scratch_buffer + OFFSET_7, SIZE_7, 500); 821 instance->scratch_buffer + OFFSET_7, SIZE_7, 500);
773 822
774 usbatm->flags = (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0); 823 usbatm->flags |= (ret == SIZE_7 ? UDSL_SKIP_HEAVY_INIT : 0);
775 824
776 usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not"); 825 usb_dbg(usbatm, "%s: firmware %s loaded\n", __func__, usbatm->flags & UDSL_SKIP_HEAVY_INIT ? "already" : "not");
777 826
@@ -817,8 +866,9 @@ static struct usbatm_driver speedtch_usbatm_driver = {
817 .unbind = speedtch_unbind, 866 .unbind = speedtch_unbind,
818 .atm_start = speedtch_atm_start, 867 .atm_start = speedtch_atm_start,
819 .atm_stop = speedtch_atm_stop, 868 .atm_stop = speedtch_atm_stop,
820 .in = ENDPOINT_DATA, 869 .bulk_in = ENDPOINT_BULK_DATA,
821 .out = ENDPOINT_DATA 870 .bulk_out = ENDPOINT_BULK_DATA,
871 .isoc_in = ENDPOINT_ISOC_DATA
822}; 872};
823 873
824static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) 874static int speedtch_usb_probe(struct usb_interface *intf, const struct usb_device_id *id)
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index aa072ad953a6..956cd9e82dee 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -1705,8 +1705,8 @@ static struct usbatm_driver uea_usbatm_driver = {
1705 .atm_start = uea_atm_open, 1705 .atm_start = uea_atm_open,
1706 .unbind = uea_unbind, 1706 .unbind = uea_unbind,
1707 .heavy_init = uea_heavy, 1707 .heavy_init = uea_heavy,
1708 .in = UEA_BULK_DATA_PIPE, 1708 .bulk_in = UEA_BULK_DATA_PIPE,
1709 .out = UEA_BULK_DATA_PIPE, 1709 .bulk_out = UEA_BULK_DATA_PIPE,
1710}; 1710};
1711 1711
1712static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) 1712static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c
index 1d829c29c86d..923f2d9269bc 100644
--- a/drivers/usb/atm/usbatm.c
+++ b/drivers/usb/atm/usbatm.c
@@ -1049,17 +1049,23 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1049 init_completion(&instance->thread_exited); 1049 init_completion(&instance->thread_exited);
1050 1050
1051 INIT_LIST_HEAD(&instance->vcc_list); 1051 INIT_LIST_HEAD(&instance->vcc_list);
1052 skb_queue_head_init(&instance->sndqueue);
1052 1053
1053 usbatm_init_channel(&instance->rx_channel); 1054 usbatm_init_channel(&instance->rx_channel);
1054 usbatm_init_channel(&instance->tx_channel); 1055 usbatm_init_channel(&instance->tx_channel);
1055 tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance); 1056 tasklet_init(&instance->rx_channel.tasklet, usbatm_rx_process, (unsigned long)instance);
1056 tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance); 1057 tasklet_init(&instance->tx_channel.tasklet, usbatm_tx_process, (unsigned long)instance);
1057 instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->in);
1058 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->out);
1059 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding; 1058 instance->rx_channel.stride = ATM_CELL_SIZE + driver->rx_padding;
1060 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding; 1059 instance->tx_channel.stride = ATM_CELL_SIZE + driver->tx_padding;
1061 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance; 1060 instance->rx_channel.usbatm = instance->tx_channel.usbatm = instance;
1062 1061
1062 if ((instance->flags & UDSL_USE_ISOC) && driver->isoc_in)
1063 instance->rx_channel.endpoint = usb_rcvisocpipe(usb_dev, driver->isoc_in);
1064 else
1065 instance->rx_channel.endpoint = usb_rcvbulkpipe(usb_dev, driver->bulk_in);
1066
1067 instance->tx_channel.endpoint = usb_sndbulkpipe(usb_dev, driver->bulk_out);
1068
1063 /* tx buffer size must be a positive multiple of the stride */ 1069 /* tx buffer size must be a positive multiple of the stride */
1064 instance->tx_channel.buf_size = max (instance->tx_channel.stride, 1070 instance->tx_channel.buf_size = max (instance->tx_channel.stride,
1065 snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride)); 1071 snd_buf_bytes - (snd_buf_bytes % instance->tx_channel.stride));
@@ -1080,6 +1086,7 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1080 num_packets--; 1086 num_packets--;
1081 1087
1082 instance->rx_channel.buf_size = num_packets * maxpacket; 1088 instance->rx_channel.buf_size = num_packets * maxpacket;
1089 instance->rx_channel.packet_size = maxpacket;
1083 1090
1084#ifdef DEBUG 1091#ifdef DEBUG
1085 for (i = 0; i < 2; i++) { 1092 for (i = 0; i < 2; i++) {
@@ -1090,22 +1097,16 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1090 } 1097 }
1091#endif 1098#endif
1092 1099
1093 skb_queue_head_init(&instance->sndqueue); 1100 /* initialize urbs */
1094 1101
1095 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) { 1102 for (i = 0; i < num_rcv_urbs + num_snd_urbs; i++) {
1096 struct urb *urb;
1097 u8 *buffer; 1103 u8 *buffer;
1098 unsigned int iso_packets = 0, iso_size = 0;
1099 struct usbatm_channel *channel = i < num_rcv_urbs ? 1104 struct usbatm_channel *channel = i < num_rcv_urbs ?
1100 &instance->rx_channel : &instance->tx_channel; 1105 &instance->rx_channel : &instance->tx_channel;
1106 struct urb *urb;
1107 unsigned int iso_packets = usb_pipeisoc(channel->endpoint) ? channel->buf_size / channel->packet_size : 0;
1101 1108
1102 if (usb_pipeisoc(channel->endpoint)) { 1109 UDSL_ASSERT(!usb_pipeisoc(channel->endpoint) || usb_pipein(channel->endpoint));
1103 /* don't expect iso out endpoints */
1104 iso_size = usb_maxpacket(instance->usb_dev, channel->endpoint, 0);
1105 iso_size -= iso_size % channel->stride; /* alignment */
1106 BUG_ON(!iso_size);
1107 iso_packets = (channel->buf_size - 1) / iso_size + 1;
1108 }
1109 1110
1110 urb = usb_alloc_urb(iso_packets, GFP_KERNEL); 1111 urb = usb_alloc_urb(iso_packets, GFP_KERNEL);
1111 if (!urb) { 1112 if (!urb) {
@@ -1132,9 +1133,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
1132 urb->transfer_flags = URB_ISO_ASAP; 1133 urb->transfer_flags = URB_ISO_ASAP;
1133 urb->number_of_packets = iso_packets; 1134 urb->number_of_packets = iso_packets;
1134 for (j = 0; j < iso_packets; j++) { 1135 for (j = 0; j < iso_packets; j++) {
1135 urb->iso_frame_desc[j].offset = iso_size * j; 1136 urb->iso_frame_desc[j].offset = channel->packet_size * j;
1136 urb->iso_frame_desc[j].length = min_t(int, iso_size, 1137 urb->iso_frame_desc[j].length = channel->packet_size;
1137 channel->buf_size - urb->iso_frame_desc[j].offset);
1138 } 1138 }
1139 } 1139 }
1140 1140
diff --git a/drivers/usb/atm/usbatm.h b/drivers/usb/atm/usbatm.h
index 1a31cf87bb1f..0e2caa0967c1 100644
--- a/drivers/usb/atm/usbatm.h
+++ b/drivers/usb/atm/usbatm.h
@@ -87,6 +87,7 @@
87/* flags, set by mini-driver in bind() */ 87/* flags, set by mini-driver in bind() */
88 88
89#define UDSL_SKIP_HEAVY_INIT (1<<0) 89#define UDSL_SKIP_HEAVY_INIT (1<<0)
90#define UDSL_USE_ISOC (1<<1)
90 91
91 92
92/* mini driver */ 93/* mini driver */
@@ -118,8 +119,9 @@ struct usbatm_driver {
118 /* cleanup ATM device ... can sleep, but can't fail */ 119 /* cleanup ATM device ... can sleep, but can't fail */
119 void (*atm_stop) (struct usbatm_data *, struct atm_dev *); 120 void (*atm_stop) (struct usbatm_data *, struct atm_dev *);
120 121
121 int in; /* rx endpoint */ 122 int bulk_in; /* bulk rx endpoint */
122 int out; /* tx endpoint */ 123 int isoc_in; /* isochronous rx endpoint */
124 int bulk_out; /* bulk tx endpoint */
123 125
124 unsigned rx_padding; 126 unsigned rx_padding;
125 unsigned tx_padding; 127 unsigned tx_padding;
@@ -134,6 +136,7 @@ struct usbatm_channel {
134 int endpoint; /* usb pipe */ 136 int endpoint; /* usb pipe */
135 unsigned int stride; /* ATM cell size + padding */ 137 unsigned int stride; /* ATM cell size + padding */
136 unsigned int buf_size; /* urb buffer size */ 138 unsigned int buf_size; /* urb buffer size */
139 unsigned int packet_size; /* endpoint maxpacket */
137 spinlock_t lock; 140 spinlock_t lock;
138 struct list_head list; 141 struct list_head list;
139 struct tasklet_struct tasklet; 142 struct tasklet_struct tasklet;
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 83848ee2c6fe..42d6823b82b3 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -210,8 +210,8 @@ static int __init xusbatm_init(void)
210 xusbatm_drivers[i].bind = xusbatm_bind; 210 xusbatm_drivers[i].bind = xusbatm_bind;
211 xusbatm_drivers[i].unbind = xusbatm_unbind; 211 xusbatm_drivers[i].unbind = xusbatm_unbind;
212 xusbatm_drivers[i].atm_start = xusbatm_atm_start; 212 xusbatm_drivers[i].atm_start = xusbatm_atm_start;
213 xusbatm_drivers[i].in = rx_endpoint[i]; 213 xusbatm_drivers[i].bulk_in = rx_endpoint[i];
214 xusbatm_drivers[i].out = tx_endpoint[i]; 214 xusbatm_drivers[i].bulk_out = tx_endpoint[i];
215 xusbatm_drivers[i].rx_padding = rx_padding[i]; 215 xusbatm_drivers[i].rx_padding = rx_padding[i];
216 xusbatm_drivers[i].tx_padding = tx_padding[i]; 216 xusbatm_drivers[i].tx_padding = tx_padding[i];
217 } 217 }