From b11f8d8cc3bb2fa6fa55286babc1a5ebb2e932c4 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Tue, 15 Jul 2008 02:18:41 -0700 Subject: ethtool: Expand ethtool_cmd.speed to 32 bits Introduce the speed_hi field to ethtool_cmd, using the reserved space, to expand the speed field to 2^32 Megabits/second. Making this field expansion now gives us plenty of time to fix up the user-space pieces that use SIOCETHTOOL before hardware faster than 64 Gb/s is available. Signed-off-by: Brandon Philips Signed-off-by: Jeff Garzik --- include/linux/ethtool.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index 8bb5e87df36..b4b038b89ee 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -27,9 +27,24 @@ struct ethtool_cmd { __u8 autoneg; /* Enable or disable autonegotiation */ __u32 maxtxpkt; /* Tx pkts before generating tx int */ __u32 maxrxpkt; /* Rx pkts before generating rx int */ - __u32 reserved[4]; + __u16 speed_hi; + __u16 reserved2; + __u32 reserved[3]; }; +static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep, + __u32 speed) +{ + + ep->speed = (__u16)speed; + ep->speed_hi = (__u16)(speed >> 16); +} + +static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep) +{ + return (ep->speed_hi << 16) | ep->speed; +} + #define ETHTOOL_BUSINFO_LEN 32 /* these strings are set to whatever the driver author decides... */ struct ethtool_drvinfo { -- cgit v1.2.3-70-g09d2 From fe414248551e2880fe8913577699003ff145ab9d Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 23 Jul 2008 17:41:52 +0200 Subject: dm9000: Support MAC address setting through platform data. The dm9000 driver reads the chip's MAC address from the attached EEPROM. When no EEPROM is present, or when the MAC address is invalid, it falls back to reading the address from the chip. This patch lets platform code set the desired MAC address through platform data. Signed-off-by: Laurent Pinchart Signed-off-by: Jeff Garzik --- drivers/net/dm9000.c | 5 +++++ include/linux/dm9000.h | 1 + 2 files changed, 6 insertions(+) (limited to 'include/linux') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 0b0f1c407a7..f42c23f4265 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -1374,6 +1374,11 @@ dm9000_probe(struct platform_device *pdev) for (i = 0; i < 6; i += 2) dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i); + if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) { + mac_src = "platform data"; + memcpy(ndev->dev_addr, pdata->dev_addr, 6); + } + if (!is_valid_ether_addr(ndev->dev_addr)) { /* try reading from mac */ diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h index fc82446b642..c30879cf93b 100644 --- a/include/linux/dm9000.h +++ b/include/linux/dm9000.h @@ -27,6 +27,7 @@ struct dm9000_plat_data { unsigned int flags; + unsigned char dev_addr[6]; /* allow replacement IO routines */ -- cgit v1.2.3-70-g09d2 From 7d283aee50351ec19eaf654a8690d77c4e1dff50 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 6 Aug 2008 15:21:26 -0700 Subject: list.h: Add list_splice_tail() and list_splice_tail_init() If you are using linked lists for queues list_splice() will not do what you would expect even if you use the elements passed reversed. We need to handle these differently. We add list_splice_tail() and list_splice_tail_init(). Signed-off-by: Peter Zijlstra Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/dma/ioat_dma.c | 2 +- drivers/usb/host/ehci-q.c | 2 +- include/linux/list.h | 47 ++++++++++++++++++++++++++++++++++++++--------- 3 files changed, 40 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index a52156e5688..bc8c6e3470c 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c @@ -551,7 +551,7 @@ static dma_cookie_t ioat1_tx_submit(struct dma_async_tx_descriptor *tx) /* write address into NextDescriptor field of last desc in chain */ to_ioat_desc(ioat_chan->used_desc.prev)->hw->next = first->async_tx.phys; - __list_splice(&new_chain, ioat_chan->used_desc.prev); + list_splice_tail(&new_chain, &ioat_chan->used_desc); ioat_chan->dmacount += desc_count; ioat_chan->pending += desc_count; diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2622b6596d7..3712b925b31 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -932,7 +932,7 @@ static struct ehci_qh *qh_append_tds ( list_del (&qtd->qtd_list); list_add (&dummy->qtd_list, qtd_list); - __list_splice (qtd_list, qh->qtd_list.prev); + list_splice_tail(qtd_list, &qh->qtd_list); ehci_qtd_init(ehci, qtd, qtd->qtd_dma); qh->dummy = qtd; diff --git a/include/linux/list.h b/include/linux/list.h index 453916bc041..a886f27a118 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -215,21 +215,21 @@ static inline int list_is_singular(const struct list_head *head) } static inline void __list_splice(const struct list_head *list, - struct list_head *head) + struct list_head *prev, + struct list_head *next) { struct list_head *first = list->next; struct list_head *last = list->prev; - struct list_head *at = head->next; - first->prev = head; - head->next = first; + first->prev = prev; + prev->next = first; - last->next = at; - at->prev = last; + last->next = next; + next->prev = last; } /** - * list_splice - join two lists + * list_splice - join two lists, this is designed for stacks * @list: the new list to add. * @head: the place to add it in the first list. */ @@ -237,7 +237,19 @@ static inline void list_splice(const struct list_head *list, struct list_head *head) { if (!list_empty(list)) - __list_splice(list, head); + __list_splice(list, head, head->next); +} + +/** + * list_splice_tail - join two lists, each list being a queue + * @list: the new list to add. + * @head: the place to add it in the first list. + */ +static inline void list_splice_tail(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) + __list_splice(list, head->prev, head); } /** @@ -251,7 +263,24 @@ static inline void list_splice_init(struct list_head *list, struct list_head *head) { if (!list_empty(list)) { - __list_splice(list, head); + __list_splice(list, head, head->next); + INIT_LIST_HEAD(list); + } +} + +/** + * list_splice_tail_init - join two lists, each list being a queue, and + * reinitialise the emptied list. + * @list: the new list to add. + * @head: the place to add it in the first list. + * + * The list at @list is reinitialised + */ +static inline void list_splice_tail_init(struct list_head *list, + struct list_head *head) +{ + if (!list_empty(list)) { + __list_splice(list, head->prev, head); INIT_LIST_HEAD(list); } } -- cgit v1.2.3-70-g09d2 From 00e8a4da8cf0d7dba8cc4b0da28ea0f12dcf6b36 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 6 Aug 2008 13:28:54 -0700 Subject: list.h: add list_cut_position() This adds list_cut_position() which lets you cut a list into two lists given a pivot in the list. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- include/linux/list.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index a886f27a118..1d109e2ef0a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -214,6 +214,46 @@ static inline int list_is_singular(const struct list_head *head) return !list_empty(head) && (head->next == head->prev); } +static inline void __list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + struct list_head *new_first = entry->next; + list->next = head->next; + list->next->prev = list; + list->prev = entry; + entry->next = list; + head->next = new_first; + new_first->prev = head; +} + +/** + * list_cut_position - cut a list into two + * @list: a new list to add all removed entries + * @head: a list with entries + * @entry: an entry within head, could be the head itself + * and if so we won't cut the list + * + * This helper moves the initial part of @head, up to and + * including @entry, from @head to @list. You should + * pass on @entry an element you know is on @head. @list + * should be an empty list or a list you do not care about + * losing its data. + * + */ +static inline void list_cut_position(struct list_head *list, + struct list_head *head, struct list_head *entry) +{ + if (list_empty(head)) + return; + if (list_is_singular(head) && + (head->next != entry && head != entry)) + return; + if (entry == head) + INIT_LIST_HEAD(list); + else + __list_cut_position(list, head, entry); +} + static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next) -- cgit v1.2.3-70-g09d2