···123123124124/* The transmit wake timer for a given cpu and echannel. */125125struct tile_net_tx_wake {126126+ int tx_queue_idx;126127 struct hrtimer timer;127128 struct net_device *dev;128129};···574573 comps->comp_next++;575574}576575577577-static void tile_net_schedule_tx_wake_timer(struct net_device *dev)576576+static void tile_net_schedule_tx_wake_timer(struct net_device *dev,577577+ int tx_queue_idx)578578{579579- struct tile_net_info *info = &__get_cpu_var(per_cpu_info);579579+ struct tile_net_info *info = &per_cpu(per_cpu_info, tx_queue_idx);580580 struct tile_net_priv *priv = netdev_priv(dev);581581+ struct tile_net_tx_wake *tx_wake = &info->tx_wake[priv->echannel];581582582582- hrtimer_start(&info->tx_wake[priv->echannel].timer,583583+ hrtimer_start(&tx_wake->timer,583584 ktime_set(0, TX_TIMER_DELAY_USEC * 1000UL),584585 HRTIMER_MODE_REL_PINNED);585586}···590587{591588 struct tile_net_tx_wake *tx_wake =592589 container_of(t, struct tile_net_tx_wake, timer);593593- netif_wake_subqueue(tx_wake->dev, smp_processor_id());590590+ netif_wake_subqueue(tx_wake->dev, tx_wake->tx_queue_idx);594591 return HRTIMER_NORESTART;595592}596593···1221121812221219 hrtimer_init(&tx_wake->timer, CLOCK_MONOTONIC,12231220 HRTIMER_MODE_REL);12211221+ tx_wake->tx_queue_idx = cpu;12241222 tx_wake->timer.function = tile_net_handle_tx_wake_timer;12251223 tx_wake->dev = dev;12261224 }···12951291 * stop the queue and schedule the tx_wake timer.12961292 */12971293static s64 tile_net_equeue_try_reserve(struct net_device *dev,12941294+ int tx_queue_idx,12981295 struct tile_net_comps *comps,12991296 gxio_mpipe_equeue_t *equeue,13001297 int num_edescs)···13181313 }1319131413201315 /* Still nothing; give up and stop the queue for a short while. */13211321- netif_stop_subqueue(dev, smp_processor_id());13221322- tile_net_schedule_tx_wake_timer(dev);13161316+ netif_stop_subqueue(dev, tx_queue_idx);13171317+ tile_net_schedule_tx_wake_timer(dev, tx_queue_idx);13231318 return -1;13241319}13251320···13331328static int tso_count_edescs(struct sk_buff *skb)13341329{13351330 struct skb_shared_info *sh = skb_shinfo(skb);13361336- unsigned int data_len = skb->data_len;13311331+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);13321332+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;13371333 unsigned int p_len = sh->gso_size;13381334 long f_id = -1; /* id of the current fragment */13391339- long f_size = -1; /* size of the current fragment */13401340- long f_used = -1; /* bytes used from the current fragment */13351335+ long f_size = skb->hdr_len; /* size of the current fragment */13361336+ long f_used = sh_len; /* bytes used from the current fragment */13411337 long n; /* size of the current piece of payload */13421338 int num_edescs = 0;13431339 int segment;···13831377 struct skb_shared_info *sh = skb_shinfo(skb);13841378 struct iphdr *ih;13851379 struct tcphdr *th;13861386- unsigned int data_len = skb->data_len;13801380+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);13811381+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;13871382 unsigned char *data = skb->data;13881388- unsigned int ih_off, th_off, sh_len, p_len;13831383+ unsigned int ih_off, th_off, p_len;13891384 unsigned int isum_seed, tsum_seed, id, seq;13901385 long f_id = -1; /* id of the current fragment */13911391- long f_size = -1; /* size of the current fragment */13921392- long f_used = -1; /* bytes used from the current fragment */13861386+ long f_size = skb->hdr_len; /* size of the current fragment */13871387+ long f_used = sh_len; /* bytes used from the current fragment */13931388 long n; /* size of the current piece of payload */13941389 int segment;13951390···13991392 th = tcp_hdr(skb);14001393 ih_off = skb_network_offset(skb);14011394 th_off = skb_transport_offset(skb);14021402- sh_len = th_off + tcp_hdrlen(skb);14031395 p_len = sh->gso_size;1404139614051397 /* Set up seed values for IP and TCP csum and initialize id and seq. */14061398 isum_seed = ((0xFFFF - ih->check) +14071399 (0xFFFF - ih->tot_len) +14081400 (0xFFFF - ih->id));14091409- tsum_seed = th->check + (0xFFFF ^ htons(skb->len));14011401+ tsum_seed = th->check + (0xFFFF ^ htons(sh_len + data_len));14101402 id = ntohs(ih->id);14111403 seq = ntohl(th->seq);14121404···14771471{14781472 struct tile_net_priv *priv = netdev_priv(dev);14791473 struct skb_shared_info *sh = skb_shinfo(skb);14801480- unsigned int data_len = skb->data_len;14741474+ unsigned int sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);14751475+ unsigned int data_len = skb->data_len + skb->hdr_len - sh_len;14811476 unsigned int p_len = sh->gso_size;14821477 gxio_mpipe_edesc_t edesc_head = { { 0 } };14831478 gxio_mpipe_edesc_t edesc_body = { { 0 } };14841479 long f_id = -1; /* id of the current fragment */14851485- long f_size = -1; /* size of the current fragment */14861486- long f_used = -1; /* bytes used from the current fragment */14801480+ long f_size = skb->hdr_len; /* size of the current fragment */14811481+ long f_used = sh_len; /* bytes used from the current fragment */14821482+ void *f_data = skb->data;14871483 long n; /* size of the current piece of payload */14881484 unsigned long tx_packets = 0, tx_bytes = 0;14891489- unsigned int csum_start, sh_len;14851485+ unsigned int csum_start;14901486 int segment;1491148714921488 /* Prepare to egress the headers: set up header edesc. */14931489 csum_start = skb_checksum_start_offset(skb);14941494- sh_len = skb_transport_offset(skb) + tcp_hdrlen(skb);14951490 edesc_head.csum = 1;14961491 edesc_head.csum_start = csum_start;14971492 edesc_head.csum_dest = csum_start + skb->csum_offset;···1504149715051498 /* Egress all the edescs. */15061499 for (segment = 0; segment < sh->gso_segs; segment++) {15071507- void *va;15081500 unsigned char *buf;15091501 unsigned int p_used = 0;15101502···15221516 f_id++;15231517 f_size = sh->frags[f_id].size;15241518 f_used = 0;15191519+ f_data = tile_net_frag_buf(&sh->frags[f_id]);15251520 }15261526-15271527- va = tile_net_frag_buf(&sh->frags[f_id]) + f_used;1528152115291522 /* Use bytes from the current fragment. */15301523 n = p_len - p_used;···15331528 p_used += n;1534152915351530 /* Egress a piece of the payload. */15361536- edesc_body.va = va_to_tile_io_addr(va);15311531+ edesc_body.va = va_to_tile_io_addr(f_data) + f_used;15371532 edesc_body.xfer_size = n;15381533 edesc_body.bound = !(p_used < p_len);15391534 gxio_mpipe_equeue_put_at(equeue, edesc_body, slot);···15851580 local_irq_save(irqflags);1586158115871582 /* Try to acquire a completion entry and an egress slot. */15881588- slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs);15831583+ slot = tile_net_equeue_try_reserve(dev, skb->queue_mapping, comps,15841584+ equeue, num_edescs);15891585 if (slot < 0) {15901586 local_irq_restore(irqflags);15911587 return NETDEV_TX_BUSY;···16801674 local_irq_save(irqflags);1681167516821676 /* Try to acquire a completion entry and an egress slot. */16831683- slot = tile_net_equeue_try_reserve(dev, comps, equeue, num_edescs);16771677+ slot = tile_net_equeue_try_reserve(dev, skb->queue_mapping, comps,16781678+ equeue, num_edescs);16841679 if (slot < 0) {16851680 local_irq_restore(irqflags);16861681 return NETDEV_TX_BUSY;···18511844 memcpy(dev->dev_addr, mac, 6);18521845 dev->addr_len = 6;18531846 } else {18541854- eth_random_addr(dev->dev_addr);18471847+ eth_hw_addr_random(dev);18551848 }1856184918571850 /* Register the network device. */