diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-03 00:01:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-03 00:01:38 -0400 |
commit | b59449bea276793b8f228ea07bcb861670d79d75 (patch) | |
tree | c5e405e27e07a5800ca21312ad45c2a3af892449 /drivers | |
parent | fffe566b8f735fa71b38c7cc487b471b85894401 (diff) | |
parent | 63ac9b915924d1237d2135fcb4de724e6127ca5e (diff) |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6:
3c589_cs: fix local_bh_enable warning
RESEND [PATCH 3/3] NetXen: Graceful teardown of interface and hardware upon module unload
drivers/net/ns83820.c: fix a check-after-use
net/usb/cdc_ether minor sparse cleanup
RESEND [PATCH 2/3] NetXen: Support per PCI-function interrupt mask registers
RESEND [PATCH 1/3] NetXen: Fix issue of MSI not working correctly
dm9601: Return 0 from bind() on success
Update MAINTAINERS for USB network devices
usbnet: Zero padding byte if there is tail room in skb
dm9601: HW header size shouldn't be included in packet length
starfire list alpha as 64 bit arch
myri10ge: SET_NETDEV_DEV()
gianfar: Fix typo bug introduced by move to udp_hdr()
[PATCH] libertas: remove private ioctls
[PATCH] libertas: fix WPA associations by handling ENABLE_RSN correctly
[PATCH] libertas: kill wlan_scan_process_results
[PATCH] libertas: style fixes
Diffstat (limited to 'drivers')
25 files changed, 443 insertions, 1731 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6822bf14267b..1b854bf07b09 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -944,7 +944,7 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb) | |||
944 | flags |= TXFCB_UDP; | 944 | flags |= TXFCB_UDP; |
945 | fcb->phcs = udp_hdr(skb)->check; | 945 | fcb->phcs = udp_hdr(skb)->check; |
946 | } else | 946 | } else |
947 | fcb->phcs = udp_hdr(skb)->check; | 947 | fcb->phcs = tcp_hdr(skb)->check; |
948 | 948 | ||
949 | /* l3os is the distance between the start of the | 949 | /* l3os is the distance between the start of the |
950 | * frame (skb->data) and the start of the IP hdr. | 950 | * frame (skb->data) and the start of the IP hdr. |
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 0f9904fe3a5a..d0cc122fa3f0 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c | |||
@@ -2854,6 +2854,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2854 | return -ENOMEM; | 2854 | return -ENOMEM; |
2855 | } | 2855 | } |
2856 | 2856 | ||
2857 | SET_NETDEV_DEV(netdev, &pdev->dev); | ||
2858 | |||
2857 | mgp = netdev_priv(netdev); | 2859 | mgp = netdev_priv(netdev); |
2858 | memset(mgp, 0, sizeof(*mgp)); | 2860 | memset(mgp, 0, sizeof(*mgp)); |
2859 | mgp->dev = netdev; | 2861 | mgp->dev = netdev; |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 91f25e0a638e..619503742b7d 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -937,6 +937,7 @@ struct netxen_adapter { | |||
937 | struct netxen_ring_ctx *ctx_desc; | 937 | struct netxen_ring_ctx *ctx_desc; |
938 | struct pci_dev *ctx_desc_pdev; | 938 | struct pci_dev *ctx_desc_pdev; |
939 | dma_addr_t ctx_desc_phys_addr; | 939 | dma_addr_t ctx_desc_phys_addr; |
940 | int intr_scheme; | ||
940 | int (*enable_phy_interrupts) (struct netxen_adapter *); | 941 | int (*enable_phy_interrupts) (struct netxen_adapter *); |
941 | int (*disable_phy_interrupts) (struct netxen_adapter *); | 942 | int (*disable_phy_interrupts) (struct netxen_adapter *); |
942 | void (*handle_phy_intr) (struct netxen_adapter *); | 943 | void (*handle_phy_intr) (struct netxen_adapter *); |
@@ -951,6 +952,24 @@ struct netxen_adapter { | |||
951 | int (*stop_port) (struct netxen_adapter *); | 952 | int (*stop_port) (struct netxen_adapter *); |
952 | }; /* netxen_adapter structure */ | 953 | }; /* netxen_adapter structure */ |
953 | 954 | ||
955 | /* | ||
956 | * NetXen dma watchdog control structure | ||
957 | * | ||
958 | * Bit 0 : enabled => R/O: 1 watchdog active, 0 inactive | ||
959 | * Bit 1 : disable_request => 1 req disable dma watchdog | ||
960 | * Bit 2 : enable_request => 1 req enable dma watchdog | ||
961 | * Bit 3-31 : unused | ||
962 | */ | ||
963 | |||
964 | #define netxen_set_dma_watchdog_disable_req(config_word) \ | ||
965 | _netxen_set_bits(config_word, 1, 1, 1) | ||
966 | #define netxen_set_dma_watchdog_enable_req(config_word) \ | ||
967 | _netxen_set_bits(config_word, 2, 1, 1) | ||
968 | #define netxen_get_dma_watchdog_enabled(config_word) \ | ||
969 | ((config_word) & 0x1) | ||
970 | #define netxen_get_dma_watchdog_disabled(config_word) \ | ||
971 | (((config_word) >> 1) & 0x1) | ||
972 | |||
954 | /* Max number of xmit producer threads that can run simultaneously */ | 973 | /* Max number of xmit producer threads that can run simultaneously */ |
955 | #define MAX_XMIT_PRODUCERS 16 | 974 | #define MAX_XMIT_PRODUCERS 16 |
956 | 975 | ||
@@ -1030,8 +1049,8 @@ int netxen_nic_erase_pxe(struct netxen_adapter *adapter); | |||
1030 | /* Functions from netxen_nic_init.c */ | 1049 | /* Functions from netxen_nic_init.c */ |
1031 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); | 1050 | void netxen_free_adapter_offload(struct netxen_adapter *adapter); |
1032 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); | 1051 | int netxen_initialize_adapter_offload(struct netxen_adapter *adapter); |
1033 | void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); | 1052 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val); |
1034 | void netxen_load_firmware(struct netxen_adapter *adapter); | 1053 | int netxen_load_firmware(struct netxen_adapter *adapter); |
1035 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); | 1054 | int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose); |
1036 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); | 1055 | int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp); |
1037 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, | 1056 | int netxen_rom_fast_read_words(struct netxen_adapter *adapter, int addr, |
@@ -1080,37 +1099,106 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev); | |||
1080 | 1099 | ||
1081 | static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) | 1100 | static inline void netxen_nic_disable_int(struct netxen_adapter *adapter) |
1082 | { | 1101 | { |
1083 | /* | 1102 | uint32_t mask = 0x7ff; |
1084 | * ISR_INT_MASK: Can be read from window 0 or 1. | 1103 | int retries = 32; |
1085 | */ | 1104 | |
1086 | writel(0x7ff, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | 1105 | DPRINTK(1, INFO, "Entered ISR Disable \n"); |
1106 | |||
1107 | switch (adapter->portnum) { | ||
1108 | case 0: | ||
1109 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
1110 | break; | ||
1111 | case 1: | ||
1112 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
1113 | break; | ||
1114 | case 2: | ||
1115 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); | ||
1116 | break; | ||
1117 | case 3: | ||
1118 | writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); | ||
1119 | break; | ||
1120 | } | ||
1087 | 1121 | ||
1122 | if (adapter->intr_scheme != -1 && | ||
1123 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | ||
1124 | writel(mask, | ||
1125 | (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); | ||
1126 | } | ||
1127 | |||
1128 | /* Window = 0 or 1 */ | ||
1129 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | ||
1130 | do { | ||
1131 | writel(0xffffffff, (void *) | ||
1132 | (PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS))); | ||
1133 | mask = readl((void *) | ||
1134 | (pci_base_offset(adapter, ISR_INT_VECTOR))); | ||
1135 | if (!(mask & 0x80)) | ||
1136 | break; | ||
1137 | udelay(10); | ||
1138 | } while (--retries); | ||
1139 | |||
1140 | if (!retries) { | ||
1141 | printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n", | ||
1142 | netxen_nic_driver_name); | ||
1143 | } | ||
1144 | } | ||
1145 | |||
1146 | DPRINTK(1, INFO, "Done with Disable Int\n"); | ||
1147 | |||
1148 | return; | ||
1088 | } | 1149 | } |
1089 | 1150 | ||
1090 | static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) | 1151 | static inline void netxen_nic_enable_int(struct netxen_adapter *adapter) |
1091 | { | 1152 | { |
1092 | u32 mask; | 1153 | u32 mask; |
1093 | 1154 | ||
1094 | switch (adapter->ahw.board_type) { | 1155 | DPRINTK(1, INFO, "Entered ISR Enable \n"); |
1095 | case NETXEN_NIC_GBE: | 1156 | |
1096 | mask = 0x77b; | 1157 | if (adapter->intr_scheme != -1 && |
1158 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { | ||
1159 | switch (adapter->ahw.board_type) { | ||
1160 | case NETXEN_NIC_GBE: | ||
1161 | mask = 0x77b; | ||
1162 | break; | ||
1163 | case NETXEN_NIC_XGBE: | ||
1164 | mask = 0x77f; | ||
1165 | break; | ||
1166 | default: | ||
1167 | mask = 0x7ff; | ||
1168 | break; | ||
1169 | } | ||
1170 | |||
1171 | writel(mask, | ||
1172 | (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK))); | ||
1173 | } | ||
1174 | switch (adapter->portnum) { | ||
1175 | case 0: | ||
1176 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0)); | ||
1177 | break; | ||
1178 | case 1: | ||
1179 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1)); | ||
1097 | break; | 1180 | break; |
1098 | case NETXEN_NIC_XGBE: | 1181 | case 2: |
1099 | mask = 0x77f; | 1182 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2)); |
1100 | break; | 1183 | break; |
1101 | default: | 1184 | case 3: |
1102 | mask = 0x7ff; | 1185 | writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3)); |
1103 | break; | 1186 | break; |
1104 | } | 1187 | } |
1105 | 1188 | ||
1106 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)); | ||
1107 | |||
1108 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1189 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
1109 | mask = 0xbff; | 1190 | mask = 0xbff; |
1110 | writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1191 | if (adapter->intr_scheme != -1 && |
1111 | writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, | 1192 | adapter->intr_scheme != INTR_SCHEME_PERPORT) { |
1112 | ISR_INT_TARGET_MASK)); | 1193 | writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
1194 | } | ||
1195 | writel(mask, | ||
1196 | (void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK))); | ||
1113 | } | 1197 | } |
1198 | |||
1199 | DPRINTK(1, INFO, "Done with enable Int\n"); | ||
1200 | |||
1201 | return; | ||
1114 | } | 1202 | } |
1115 | 1203 | ||
1116 | /* | 1204 | /* |
@@ -1164,6 +1252,62 @@ static inline void get_brd_name_by_type(u32 type, char *name) | |||
1164 | name = "Unknown"; | 1252 | name = "Unknown"; |
1165 | } | 1253 | } |
1166 | 1254 | ||
1255 | static inline int | ||
1256 | dma_watchdog_shutdown_request(struct netxen_adapter *adapter) | ||
1257 | { | ||
1258 | u32 ctrl; | ||
1259 | |||
1260 | /* check if already inactive */ | ||
1261 | if (netxen_nic_hw_read_wx(adapter, | ||
1262 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | ||
1263 | printk(KERN_ERR "failed to read dma watchdog status\n"); | ||
1264 | |||
1265 | if (netxen_get_dma_watchdog_enabled(ctrl) == 0) | ||
1266 | return 1; | ||
1267 | |||
1268 | /* Send the disable request */ | ||
1269 | netxen_set_dma_watchdog_disable_req(ctrl); | ||
1270 | netxen_crb_writelit_adapter(adapter, | ||
1271 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); | ||
1272 | |||
1273 | return 0; | ||
1274 | } | ||
1275 | |||
1276 | static inline int | ||
1277 | dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter) | ||
1278 | { | ||
1279 | u32 ctrl; | ||
1280 | |||
1281 | if (netxen_nic_hw_read_wx(adapter, | ||
1282 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | ||
1283 | printk(KERN_ERR "failed to read dma watchdog status\n"); | ||
1284 | |||
1285 | return ((netxen_get_dma_watchdog_enabled(ctrl) == 0) && | ||
1286 | (netxen_get_dma_watchdog_disabled(ctrl) == 0)); | ||
1287 | } | ||
1288 | |||
1289 | static inline int | ||
1290 | dma_watchdog_wakeup(struct netxen_adapter *adapter) | ||
1291 | { | ||
1292 | u32 ctrl; | ||
1293 | |||
1294 | if (netxen_nic_hw_read_wx(adapter, | ||
1295 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4)) | ||
1296 | printk(KERN_ERR "failed to read dma watchdog status\n"); | ||
1297 | |||
1298 | if (netxen_get_dma_watchdog_enabled(ctrl)) | ||
1299 | return 1; | ||
1300 | |||
1301 | /* send the wakeup request */ | ||
1302 | netxen_set_dma_watchdog_enable_req(ctrl); | ||
1303 | |||
1304 | netxen_crb_writelit_adapter(adapter, | ||
1305 | NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), ctrl); | ||
1306 | |||
1307 | return 0; | ||
1308 | } | ||
1309 | |||
1310 | |||
1167 | int netxen_is_flash_supported(struct netxen_adapter *adapter); | 1311 | int netxen_is_flash_supported(struct netxen_adapter *adapter); |
1168 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); | 1312 | int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, u64 mac[]); |
1169 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); | 1313 | extern void netxen_change_ringparam(struct netxen_adapter *adapter); |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 608e37b349b4..3276866b17e2 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -687,4 +687,6 @@ enum { | |||
687 | 687 | ||
688 | #define PCIE_MAX_MASTER_SPLIT (0x14048) | 688 | #define PCIE_MAX_MASTER_SPLIT (0x14048) |
689 | 689 | ||
690 | #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL (0x14) | ||
691 | |||
690 | #endif /* __NETXEN_NIC_HDR_H_ */ | 692 | #endif /* __NETXEN_NIC_HDR_H_ */ |
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index c012764d1145..aac15421bd1e 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -377,7 +377,7 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
377 | recv_crb_registers[ctx]. | 377 | recv_crb_registers[ctx]. |
378 | crb_rcvpeg_state)); | 378 | crb_rcvpeg_state)); |
379 | while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { | 379 | while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) { |
380 | udelay(100); | 380 | msleep(1); |
381 | /* Window 1 call */ | 381 | /* Window 1 call */ |
382 | state = readl(NETXEN_CRB_NORMALIZE(adapter, | 382 | state = readl(NETXEN_CRB_NORMALIZE(adapter, |
383 | recv_crb_registers | 383 | recv_crb_registers |
@@ -392,7 +392,11 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter) | |||
392 | return err; | 392 | return err; |
393 | } | 393 | } |
394 | } | 394 | } |
395 | DPRINTK(INFO, "Recieve Peg ready too. starting stuff\n"); | 395 | adapter->intr_scheme = readl( |
396 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW)); | ||
397 | printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name, | ||
398 | adapter->intr_scheme); | ||
399 | DPRINTK(INFO, "Receive Peg ready too. starting stuff\n"); | ||
396 | 400 | ||
397 | addr = netxen_alloc(adapter->ahw.pdev, | 401 | addr = netxen_alloc(adapter->ahw.pdev, |
398 | sizeof(struct netxen_ring_ctx) + | 402 | sizeof(struct netxen_ring_ctx) + |
@@ -697,7 +701,7 @@ void netxen_nic_pci_change_crbwindow(struct netxen_adapter *adapter, u32 wndw) | |||
697 | adapter->curr_window = 0; | 701 | adapter->curr_window = 0; |
698 | } | 702 | } |
699 | 703 | ||
700 | void netxen_load_firmware(struct netxen_adapter *adapter) | 704 | int netxen_load_firmware(struct netxen_adapter *adapter) |
701 | { | 705 | { |
702 | int i; | 706 | int i; |
703 | u32 data, size = 0; | 707 | u32 data, size = 0; |
@@ -709,15 +713,24 @@ void netxen_load_firmware(struct netxen_adapter *adapter) | |||
709 | writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | 713 | writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); |
710 | 714 | ||
711 | for (i = 0; i < size; i++) { | 715 | for (i = 0; i < size; i++) { |
712 | if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) { | 716 | int retries = 10; |
713 | DPRINTK(ERR, | 717 | if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) |
714 | "Error in netxen_rom_fast_read(). Will skip" | 718 | return -EIO; |
715 | "loading flash image\n"); | 719 | |
716 | return; | ||
717 | } | ||
718 | off = netxen_nic_pci_set_window(adapter, memaddr); | 720 | off = netxen_nic_pci_set_window(adapter, memaddr); |
719 | addr = pci_base_offset(adapter, off); | 721 | addr = pci_base_offset(adapter, off); |
720 | writel(data, addr); | 722 | writel(data, addr); |
723 | do { | ||
724 | if (readl(addr) == data) | ||
725 | break; | ||
726 | msleep(100); | ||
727 | writel(data, addr); | ||
728 | } while (--retries); | ||
729 | if (!retries) { | ||
730 | printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n", | ||
731 | netxen_nic_driver_name, memaddr); | ||
732 | return -EIO; | ||
733 | } | ||
721 | flashaddr += 4; | 734 | flashaddr += 4; |
722 | memaddr += 4; | 735 | memaddr += 4; |
723 | } | 736 | } |
@@ -727,7 +740,7 @@ void netxen_load_firmware(struct netxen_adapter *adapter) | |||
727 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); | 740 | NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL)); |
728 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); | 741 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST)); |
729 | 742 | ||
730 | udelay(100); | 743 | return 0; |
731 | } | 744 | } |
732 | 745 | ||
733 | int | 746 | int |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index bb23f4c360db..1811bcb8c380 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -139,6 +139,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter) | |||
139 | return err; | 139 | return err; |
140 | } | 140 | } |
141 | /* Window 1 call */ | 141 | /* Window 1 call */ |
142 | writel(INTR_SCHEME_PERPORT, | ||
143 | NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST)); | ||
142 | writel(MPORT_MULTI_FUNCTION_MODE, | 144 | writel(MPORT_MULTI_FUNCTION_MODE, |
143 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); | 145 | NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE)); |
144 | writel(PHAN_INITIALIZE_ACK, | 146 | writel(PHAN_INITIALIZE_ACK, |
@@ -405,10 +407,7 @@ static inline int do_rom_fast_write(struct netxen_adapter *adapter, int addr, | |||
405 | static inline int | 407 | static inline int |
406 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) | 408 | do_rom_fast_read(struct netxen_adapter *adapter, int addr, int *valp) |
407 | { | 409 | { |
408 | if (jiffies > (last_schedule_time + (8 * HZ))) { | 410 | cond_resched(); |
409 | last_schedule_time = jiffies; | ||
410 | schedule(); | ||
411 | } | ||
412 | 411 | ||
413 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); | 412 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ADDRESS, addr); |
414 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); | 413 | netxen_nic_reg_write(adapter, NETXEN_ROMUSB_ROM_ABYTE_CNT, 3); |
@@ -854,10 +853,10 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
854 | netxen_nic_pci_change_crbwindow(adapter, 1); | 853 | netxen_nic_pci_change_crbwindow(adapter, 1); |
855 | } | 854 | } |
856 | if (init_delay == 1) { | 855 | if (init_delay == 1) { |
857 | ssleep(1); | 856 | msleep(2000); |
858 | init_delay = 0; | 857 | init_delay = 0; |
859 | } | 858 | } |
860 | msleep(1); | 859 | msleep(20); |
861 | } | 860 | } |
862 | kfree(buf); | 861 | kfree(buf); |
863 | 862 | ||
@@ -933,10 +932,6 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter) | |||
933 | void netxen_free_adapter_offload(struct netxen_adapter *adapter) | 932 | void netxen_free_adapter_offload(struct netxen_adapter *adapter) |
934 | { | 933 | { |
935 | if (adapter->dummy_dma.addr) { | 934 | if (adapter->dummy_dma.addr) { |
936 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
937 | CRB_HOST_DUMMY_BUF_ADDR_HI)); | ||
938 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
939 | CRB_HOST_DUMMY_BUF_ADDR_LO)); | ||
940 | pci_free_consistent(adapter->ahw.pdev, | 935 | pci_free_consistent(adapter->ahw.pdev, |
941 | NETXEN_HOST_DUMMY_DMA_SIZE, | 936 | NETXEN_HOST_DUMMY_DMA_SIZE, |
942 | adapter->dummy_dma.addr, | 937 | adapter->dummy_dma.addr, |
@@ -945,25 +940,32 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter) | |||
945 | } | 940 | } |
946 | } | 941 | } |
947 | 942 | ||
948 | void netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) | 943 | int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val) |
949 | { | 944 | { |
950 | u32 val = 0; | 945 | u32 val = 0; |
951 | int loops = 0; | 946 | int retries = 30; |
952 | 947 | ||
953 | if (!pegtune_val) { | 948 | if (!pegtune_val) { |
954 | val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | 949 | do { |
955 | while (val != PHAN_INITIALIZE_COMPLETE && | 950 | val = readl(NETXEN_CRB_NORMALIZE |
956 | val != PHAN_INITIALIZE_ACK && loops < 200000) { | ||
957 | udelay(100); | ||
958 | schedule(); | ||
959 | val = | ||
960 | readl(NETXEN_CRB_NORMALIZE | ||
961 | (adapter, CRB_CMDPEG_STATE)); | 951 | (adapter, CRB_CMDPEG_STATE)); |
962 | loops++; | 952 | pegtune_val = readl(NETXEN_CRB_NORMALIZE |
953 | (adapter, NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | ||
954 | |||
955 | if (val == PHAN_INITIALIZE_COMPLETE || | ||
956 | val == PHAN_INITIALIZE_ACK) | ||
957 | return 0; | ||
958 | |||
959 | msleep(1000); | ||
960 | } while (--retries); | ||
961 | if (!retries) { | ||
962 | printk(KERN_WARNING "netxen_phantom_init: init failed, " | ||
963 | "pegtune_val=%x\n", pegtune_val); | ||
964 | return -1; | ||
963 | } | 965 | } |
964 | if (val != PHAN_INITIALIZE_COMPLETE) | ||
965 | printk("WARNING: Initial boot wait loop failed...\n"); | ||
966 | } | 966 | } |
967 | |||
968 | return 0; | ||
967 | } | 969 | } |
968 | 970 | ||
969 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter) | 971 | int netxen_nic_rx_has_work(struct netxen_adapter *adapter) |
@@ -1120,6 +1122,7 @@ netxen_process_rcv(struct netxen_adapter *adapter, int ctxid, | |||
1120 | adapter->stats.csummed++; | 1122 | adapter->stats.csummed++; |
1121 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1123 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1122 | } | 1124 | } |
1125 | skb->dev = netdev; | ||
1123 | if (desc_ctx == RCV_DESC_LRO_CTXID) { | 1126 | if (desc_ctx == RCV_DESC_LRO_CTXID) { |
1124 | /* True length was only available on the last pkt */ | 1127 | /* True length was only available on the last pkt */ |
1125 | skb_put(skb, buffer->lro_length); | 1128 | skb_put(skb, buffer->lro_length); |
@@ -1224,6 +1227,7 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max) | |||
1224 | NETXEN_CRB_NORMALIZE(adapter, | 1227 | NETXEN_CRB_NORMALIZE(adapter, |
1225 | recv_crb_registers[adapter->portnum]. | 1228 | recv_crb_registers[adapter->portnum]. |
1226 | crb_rcv_status_consumer)); | 1229 | crb_rcv_status_consumer)); |
1230 | wmb(); | ||
1227 | } | 1231 | } |
1228 | 1232 | ||
1229 | return count; | 1233 | return count; |
@@ -1276,11 +1280,13 @@ int netxen_process_cmd_ring(unsigned long data) | |||
1276 | if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { | 1280 | if (skb && (cmpxchg(&buffer->skb, skb, 0) == skb)) { |
1277 | pci_unmap_single(pdev, frag->dma, frag->length, | 1281 | pci_unmap_single(pdev, frag->dma, frag->length, |
1278 | PCI_DMA_TODEVICE); | 1282 | PCI_DMA_TODEVICE); |
1283 | frag->dma = 0ULL; | ||
1279 | for (i = 1; i < buffer->frag_count; i++) { | 1284 | for (i = 1; i < buffer->frag_count; i++) { |
1280 | DPRINTK(INFO, "getting fragment no %d\n", i); | 1285 | DPRINTK(INFO, "getting fragment no %d\n", i); |
1281 | frag++; /* Get the next frag */ | 1286 | frag++; /* Get the next frag */ |
1282 | pci_unmap_page(pdev, frag->dma, frag->length, | 1287 | pci_unmap_page(pdev, frag->dma, frag->length, |
1283 | PCI_DMA_TODEVICE); | 1288 | PCI_DMA_TODEVICE); |
1289 | frag->dma = 0ULL; | ||
1284 | } | 1290 | } |
1285 | 1291 | ||
1286 | adapter->stats.skbfreed++; | 1292 | adapter->stats.skbfreed++; |
@@ -1446,6 +1452,7 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid) | |||
1446 | writel(msg, | 1452 | writel(msg, |
1447 | DB_NORMALIZE(adapter, | 1453 | DB_NORMALIZE(adapter, |
1448 | NETXEN_RCV_PRODUCER_OFFSET)); | 1454 | NETXEN_RCV_PRODUCER_OFFSET)); |
1455 | wmb(); | ||
1449 | } | 1456 | } |
1450 | } | 1457 | } |
1451 | } | 1458 | } |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 6167b58d2731..a66ff58366cf 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -308,7 +308,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
308 | 308 | ||
309 | adapter->netdev = netdev; | 309 | adapter->netdev = netdev; |
310 | adapter->pdev = pdev; | 310 | adapter->pdev = pdev; |
311 | |||
312 | /* this will be read from FW later */ | ||
313 | adapter->intr_scheme = -1; | ||
314 | |||
315 | /* This will be reset for mezz cards */ | ||
311 | adapter->portnum = pci_func_id; | 316 | adapter->portnum = pci_func_id; |
317 | adapter->status &= ~NETXEN_NETDEV_STATUS; | ||
312 | 318 | ||
313 | netdev->open = netxen_nic_open; | 319 | netdev->open = netxen_nic_open; |
314 | netdev->stop = netxen_nic_close; | 320 | netdev->stop = netxen_nic_close; |
@@ -336,11 +342,9 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
336 | if (pci_using_dac) | 342 | if (pci_using_dac) |
337 | netdev->features |= NETIF_F_HIGHDMA; | 343 | netdev->features |= NETIF_F_HIGHDMA; |
338 | 344 | ||
339 | if (pci_enable_msi(pdev)) { | 345 | if (pci_enable_msi(pdev)) |
340 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; | 346 | adapter->flags &= ~NETXEN_NIC_MSI_ENABLED; |
341 | printk(KERN_WARNING "%s: unable to allocate MSI interrupt" | 347 | else |
342 | " error\n", netxen_nic_driver_name); | ||
343 | } else | ||
344 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; | 348 | adapter->flags |= NETXEN_NIC_MSI_ENABLED; |
345 | 349 | ||
346 | netdev->irq = pdev->irq; | 350 | netdev->irq = pdev->irq; |
@@ -355,13 +359,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
355 | /* initialize the adapter */ | 359 | /* initialize the adapter */ |
356 | netxen_initialize_adapter_hw(adapter); | 360 | netxen_initialize_adapter_hw(adapter); |
357 | 361 | ||
358 | #ifdef CONFIG_PPC | ||
359 | if ((adapter->ahw.boardcfg.board_type == | ||
360 | NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) && | ||
361 | (pci_func_id == 2)) | ||
362 | goto err_out_free_adapter; | ||
363 | #endif /* CONFIG_PPC */ | ||
364 | |||
365 | /* | 362 | /* |
366 | * Adapter in our case is quad port so initialize it before | 363 | * Adapter in our case is quad port so initialize it before |
367 | * initializing the ports | 364 | * initializing the ports |
@@ -509,22 +506,30 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
509 | NETXEN_CAM_RAM(0x1fc))); | 506 | NETXEN_CAM_RAM(0x1fc))); |
510 | if (val == 0x55555555) { | 507 | if (val == 0x55555555) { |
511 | /* This is the first boot after power up */ | 508 | /* This is the first boot after power up */ |
509 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
510 | if (!(val & 0x4)) { | ||
511 | val |= 0x4; | ||
512 | netxen_nic_write_w0(adapter, NETXEN_PCIE_REG(0x4), val); | ||
513 | netxen_nic_read_w0(adapter, NETXEN_PCIE_REG(0x4), &val); | ||
514 | if (!(val & 0x4)) | ||
515 | printk(KERN_ERR "%s: failed to set MSI bit in PCI-e reg\n", | ||
516 | netxen_nic_driver_name); | ||
517 | } | ||
512 | val = readl(NETXEN_CRB_NORMALIZE(adapter, | 518 | val = readl(NETXEN_CRB_NORMALIZE(adapter, |
513 | NETXEN_ROMUSB_GLB_SW_RESET)); | 519 | NETXEN_ROMUSB_GLB_SW_RESET)); |
514 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); | 520 | printk(KERN_INFO"NetXen: read 0x%08x for reset reg.\n",val); |
515 | if (val != 0x80000f) { | 521 | if (val != 0x80000f) { |
516 | /* clear the register for future unloads/loads */ | 522 | /* clear the register for future unloads/loads */ |
517 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | 523 | writel(0, NETXEN_CRB_NORMALIZE(adapter, |
518 | NETXEN_CAM_RAM(0x1fc))); | 524 | NETXEN_CAM_RAM(0x1fc))); |
519 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); | 525 | printk(KERN_ERR "ERROR in NetXen HW init sequence.\n"); |
520 | err = -ENODEV; | 526 | err = -ENODEV; |
521 | goto err_out_free_dev; | 527 | goto err_out_free_dev; |
522 | } | 528 | } |
523 | |||
524 | /* clear the register for future unloads/loads */ | ||
525 | writel(0, NETXEN_CRB_NORMALIZE(adapter, | ||
526 | NETXEN_CAM_RAM(0x1fc))); | ||
527 | } | 529 | } |
530 | |||
531 | /* clear the register for future unloads/loads */ | ||
532 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | ||
528 | printk(KERN_INFO "State: 0x%0x\n", | 533 | printk(KERN_INFO "State: 0x%0x\n", |
529 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | 534 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); |
530 | 535 | ||
@@ -542,13 +547,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
542 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); | 547 | NETXEN_ROMUSB_GLB_PEGTUNE_DONE)); |
543 | /* Handshake with the card before we register the devices. */ | 548 | /* Handshake with the card before we register the devices. */ |
544 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | 549 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); |
545 | |||
546 | /* leave the hw in the same state as reboot */ | ||
547 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
548 | netxen_pinit_from_rom(adapter, 0); | ||
549 | udelay(500); | ||
550 | netxen_load_firmware(adapter); | ||
551 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
552 | } | 550 | } |
553 | 551 | ||
554 | /* | 552 | /* |
@@ -639,8 +637,8 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
639 | struct netxen_rx_buffer *buffer; | 637 | struct netxen_rx_buffer *buffer; |
640 | struct netxen_recv_context *recv_ctx; | 638 | struct netxen_recv_context *recv_ctx; |
641 | struct netxen_rcv_desc_ctx *rcv_desc; | 639 | struct netxen_rcv_desc_ctx *rcv_desc; |
642 | int i; | 640 | int i, ctxid, ring; |
643 | int ctxid, ring; | 641 | static int init_firmware_done = 0; |
644 | 642 | ||
645 | adapter = pci_get_drvdata(pdev); | 643 | adapter = pci_get_drvdata(pdev); |
646 | if (adapter == NULL) | 644 | if (adapter == NULL) |
@@ -648,30 +646,20 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
648 | 646 | ||
649 | netdev = adapter->netdev; | 647 | netdev = adapter->netdev; |
650 | 648 | ||
651 | netxen_nic_disable_int(adapter); | 649 | unregister_netdev(netdev); |
652 | if (adapter->irq) | 650 | |
653 | free_irq(adapter->irq, adapter); | ||
654 | |||
655 | if (adapter->stop_port) | 651 | if (adapter->stop_port) |
656 | adapter->stop_port(adapter); | 652 | adapter->stop_port(adapter); |
657 | 653 | ||
658 | if ((adapter->flags & NETXEN_NIC_MSI_ENABLED)) | 654 | netxen_nic_disable_int(adapter); |
659 | pci_disable_msi(pdev); | ||
660 | |||
661 | if (adapter->portnum == 0) | ||
662 | netxen_free_adapter_offload(adapter); | ||
663 | 655 | ||
664 | if(adapter->portnum == 0) { | 656 | if (adapter->irq) |
665 | /* leave the hw in the same state as reboot */ | 657 | free_irq(adapter->irq, adapter); |
666 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
667 | netxen_pinit_from_rom(adapter, 0); | ||
668 | udelay(500); | ||
669 | netxen_load_firmware(adapter); | ||
670 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
671 | } | ||
672 | 658 | ||
673 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) | 659 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
660 | init_firmware_done++; | ||
674 | netxen_free_hw_resources(adapter); | 661 | netxen_free_hw_resources(adapter); |
662 | } | ||
675 | 663 | ||
676 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { | 664 | for (ctxid = 0; ctxid < MAX_RCV_CTX; ++ctxid) { |
677 | recv_ctx = &adapter->recv_ctx[ctxid]; | 665 | recv_ctx = &adapter->recv_ctx[ctxid]; |
@@ -691,17 +679,73 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev) | |||
691 | } | 679 | } |
692 | } | 680 | } |
693 | 681 | ||
694 | unregister_netdev(netdev); | 682 | if (adapter->flags & NETXEN_NIC_MSI_ENABLED) |
683 | pci_disable_msi(pdev); | ||
695 | 684 | ||
696 | vfree(adapter->cmd_buf_arr); | 685 | vfree(adapter->cmd_buf_arr); |
697 | 686 | ||
687 | pci_disable_device(pdev); | ||
688 | |||
689 | if (adapter->portnum == 0) { | ||
690 | if (init_firmware_done) { | ||
691 | dma_watchdog_shutdown_request(adapter); | ||
692 | msleep(100); | ||
693 | i = 100; | ||
694 | while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) { | ||
695 | printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n"); | ||
696 | msleep(100); | ||
697 | i--; | ||
698 | } | ||
699 | |||
700 | if (i == 0) { | ||
701 | printk(KERN_ERR "dma_watchdog_shutdown_request failed\n"); | ||
702 | return; | ||
703 | } | ||
704 | |||
705 | /* clear the register for future unloads/loads */ | ||
706 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | ||
707 | printk(KERN_INFO "State: 0x%0x\n", | ||
708 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | ||
709 | |||
710 | /* leave the hw in the same state as reboot */ | ||
711 | writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)); | ||
712 | if (netxen_pinit_from_rom(adapter, 0)) | ||
713 | return; | ||
714 | msleep(1); | ||
715 | if (netxen_load_firmware(adapter)) | ||
716 | return; | ||
717 | netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE); | ||
718 | } | ||
719 | |||
720 | /* clear the register for future unloads/loads */ | ||
721 | writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc))); | ||
722 | printk(KERN_INFO "State: 0x%0x\n", | ||
723 | readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE))); | ||
724 | |||
725 | dma_watchdog_shutdown_request(adapter); | ||
726 | msleep(100); | ||
727 | i = 100; | ||
728 | while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) { | ||
729 | printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n"); | ||
730 | msleep(100); | ||
731 | i--; | ||
732 | } | ||
733 | |||
734 | if (i) { | ||
735 | netxen_free_adapter_offload(adapter); | ||
736 | } else { | ||
737 | printk(KERN_ERR "failed to dma shutdown\n"); | ||
738 | return; | ||
739 | } | ||
740 | |||
741 | } | ||
742 | |||
698 | iounmap(adapter->ahw.db_base); | 743 | iounmap(adapter->ahw.db_base); |
699 | iounmap(adapter->ahw.pci_base0); | 744 | iounmap(adapter->ahw.pci_base0); |
700 | iounmap(adapter->ahw.pci_base1); | 745 | iounmap(adapter->ahw.pci_base1); |
701 | iounmap(adapter->ahw.pci_base2); | 746 | iounmap(adapter->ahw.pci_base2); |
702 | 747 | ||
703 | pci_release_regions(pdev); | 748 | pci_release_regions(pdev); |
704 | pci_disable_device(pdev); | ||
705 | pci_set_drvdata(pdev, NULL); | 749 | pci_set_drvdata(pdev, NULL); |
706 | 750 | ||
707 | free_netdev(netdev); | 751 | free_netdev(netdev); |
@@ -798,7 +842,7 @@ static int netxen_nic_close(struct net_device *netdev) | |||
798 | if (buffrag->dma) { | 842 | if (buffrag->dma) { |
799 | pci_unmap_single(adapter->pdev, buffrag->dma, | 843 | pci_unmap_single(adapter->pdev, buffrag->dma, |
800 | buffrag->length, PCI_DMA_TODEVICE); | 844 | buffrag->length, PCI_DMA_TODEVICE); |
801 | buffrag->dma = (u64) NULL; | 845 | buffrag->dma = 0ULL; |
802 | } | 846 | } |
803 | for (j = 0; j < cmd_buff->frag_count; j++) { | 847 | for (j = 0; j < cmd_buff->frag_count; j++) { |
804 | buffrag++; | 848 | buffrag++; |
@@ -806,7 +850,7 @@ static int netxen_nic_close(struct net_device *netdev) | |||
806 | pci_unmap_page(adapter->pdev, buffrag->dma, | 850 | pci_unmap_page(adapter->pdev, buffrag->dma, |
807 | buffrag->length, | 851 | buffrag->length, |
808 | PCI_DMA_TODEVICE); | 852 | PCI_DMA_TODEVICE); |
809 | buffrag->dma = (u64) NULL; | 853 | buffrag->dma = 0ULL; |
810 | } | 854 | } |
811 | } | 855 | } |
812 | /* Free the skb we received in netxen_nic_xmit_frame */ | 856 | /* Free the skb we received in netxen_nic_xmit_frame */ |
@@ -816,8 +860,10 @@ static int netxen_nic_close(struct net_device *netdev) | |||
816 | } | 860 | } |
817 | cmd_buff++; | 861 | cmd_buff++; |
818 | } | 862 | } |
819 | FLUSH_SCHEDULED_WORK(); | 863 | if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { |
820 | del_timer_sync(&adapter->watchdog_timer); | 864 | FLUSH_SCHEDULED_WORK(); |
865 | del_timer_sync(&adapter->watchdog_timer); | ||
866 | } | ||
821 | 867 | ||
822 | return 0; | 868 | return 0; |
823 | } | 869 | } |
@@ -1103,28 +1149,26 @@ static int | |||
1103 | netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | 1149 | netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) |
1104 | { | 1150 | { |
1105 | u32 ret = 0; | 1151 | u32 ret = 0; |
1152 | u32 our_int = 0; | ||
1106 | 1153 | ||
1107 | DPRINTK(INFO, "Entered handle ISR\n"); | 1154 | DPRINTK(INFO, "Entered handle ISR\n"); |
1108 | adapter->stats.ints++; | 1155 | adapter->stats.ints++; |
1109 | 1156 | ||
1110 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | 1157 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { |
1111 | int count = 0; | ||
1112 | u32 mask; | ||
1113 | u32 our_int = 0; | ||
1114 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | 1158 | our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); |
1115 | /* not our interrupt */ | 1159 | /* not our interrupt */ |
1116 | if ((our_int & (0x80 << adapter->portnum)) == 0) | 1160 | if ((our_int & (0x80 << adapter->portnum)) == 0) |
1117 | return ret; | 1161 | return ret; |
1118 | netxen_nic_disable_int(adapter); | 1162 | } |
1119 | /* Window = 0 or 1 */ | ||
1120 | do { | ||
1121 | writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter, | ||
1122 | ISR_INT_TARGET_STATUS)); | ||
1123 | mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR)); | ||
1124 | } while (((mask & 0x80) != 0) && (++count < 32)); | ||
1125 | if ((mask & 0x80) != 0) | ||
1126 | printk("Could not disable interrupt completely\n"); | ||
1127 | 1163 | ||
1164 | netxen_nic_disable_int(adapter); | ||
1165 | |||
1166 | if (adapter->intr_scheme == INTR_SCHEME_PERPORT) { | ||
1167 | /* claim interrupt */ | ||
1168 | if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) { | ||
1169 | writel(our_int & ~((u32)(0x80 << adapter->portnum)), | ||
1170 | NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR)); | ||
1171 | } | ||
1128 | } | 1172 | } |
1129 | 1173 | ||
1130 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { | 1174 | if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) { |
@@ -1136,7 +1180,7 @@ netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev) | |||
1136 | } else { | 1180 | } else { |
1137 | static unsigned int intcount = 0; | 1181 | static unsigned int intcount = 0; |
1138 | if ((++intcount & 0xfff) == 0xfff) | 1182 | if ((++intcount & 0xfff) == 0xfff) |
1139 | printk(KERN_ERR | 1183 | DPRINTK(KERN_ERR |
1140 | "%s: %s interrupt %d while in poll\n", | 1184 | "%s: %s interrupt %d while in poll\n", |
1141 | netxen_nic_driver_name, netdev->name, | 1185 | netxen_nic_driver_name, netdev->name, |
1142 | intcount); | 1186 | intcount); |
@@ -1258,6 +1302,7 @@ static void __exit netxen_exit_module(void) | |||
1258 | /* | 1302 | /* |
1259 | * Wait for some time to allow the dma to drain, if any. | 1303 | * Wait for some time to allow the dma to drain, if any. |
1260 | */ | 1304 | */ |
1305 | msleep(100); | ||
1261 | pci_unregister_driver(&netxen_driver); | 1306 | pci_unregister_driver(&netxen_driver); |
1262 | destroy_workqueue(netxen_workq); | 1307 | destroy_workqueue(netxen_workq); |
1263 | } | 1308 | } |
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h index 9457fc7249c8..10fe6fafa6f6 100644 --- a/drivers/net/netxen/netxen_nic_phan_reg.h +++ b/drivers/net/netxen/netxen_nic_phan_reg.h | |||
@@ -114,6 +114,20 @@ | |||
114 | #define CRB_V2P_3 NETXEN_NIC_REG(0x29c) | 114 | #define CRB_V2P_3 NETXEN_NIC_REG(0x29c) |
115 | #define CRB_V2P(port) (CRB_V2P_0+((port)*4)) | 115 | #define CRB_V2P(port) (CRB_V2P_0+((port)*4)) |
116 | #define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) | 116 | #define CRB_DRIVER_VERSION NETXEN_NIC_REG(0x2a0) |
117 | /* sw int status/mask registers */ | ||
118 | #define CRB_SW_INT_MASK_0 NETXEN_NIC_REG(0x1d8) | ||
119 | #define CRB_SW_INT_MASK_1 NETXEN_NIC_REG(0x1e0) | ||
120 | #define CRB_SW_INT_MASK_2 NETXEN_NIC_REG(0x1e4) | ||
121 | #define CRB_SW_INT_MASK_3 NETXEN_NIC_REG(0x1e8) | ||
122 | |||
123 | /* | ||
124 | * capabilities register, can be used to selectively enable/disable features | ||
125 | * for backward compability | ||
126 | */ | ||
127 | #define CRB_NIC_CAPABILITIES_HOST NETXEN_NIC_REG(0x1a8) | ||
128 | #define CRB_NIC_CAPABILITIES_FW NETXEN_NIC_REG(0x1dc) | ||
129 | |||
130 | #define INTR_SCHEME_PERPORT 0x1 | ||
117 | 131 | ||
118 | /* used for ethtool tests */ | 132 | /* used for ethtool tests */ |
119 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) | 133 | #define CRB_SCRATCHPAD_TEST NETXEN_NIC_REG(0x280) |
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index 717d8e9b9833..104aab3c957f 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c | |||
@@ -1831,11 +1831,13 @@ static int __devinit ns83820_init_one(struct pci_dev *pci_dev, const struct pci_ | |||
1831 | 1831 | ||
1832 | ndev = alloc_etherdev(sizeof(struct ns83820)); | 1832 | ndev = alloc_etherdev(sizeof(struct ns83820)); |
1833 | dev = PRIV(ndev); | 1833 | dev = PRIV(ndev); |
1834 | dev->ndev = ndev; | 1834 | |
1835 | err = -ENOMEM; | 1835 | err = -ENOMEM; |
1836 | if (!dev) | 1836 | if (!dev) |
1837 | goto out; | 1837 | goto out; |
1838 | 1838 | ||
1839 | dev->ndev = ndev; | ||
1840 | |||
1839 | spin_lock_init(&dev->rx_info.lock); | 1841 | spin_lock_init(&dev->rx_info.lock); |
1840 | spin_lock_init(&dev->tx_lock); | 1842 | spin_lock_init(&dev->tx_lock); |
1841 | spin_lock_init(&dev->misc_lock); | 1843 | spin_lock_init(&dev->misc_lock); |
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c index 143ae2ff309e..503f2685fb73 100644 --- a/drivers/net/pcmcia/3c589_cs.c +++ b/drivers/net/pcmcia/3c589_cs.c | |||
@@ -629,9 +629,9 @@ static int el3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
629 | outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); | 629 | outw(SetTxThreshold + 1536, ioaddr + EL3_CMD); |
630 | } | 630 | } |
631 | 631 | ||
632 | dev_kfree_skb(skb); | ||
633 | pop_tx_status(dev); | 632 | pop_tx_status(dev); |
634 | spin_unlock_irqrestore(&priv->lock, flags); | 633 | spin_unlock_irqrestore(&priv->lock, flags); |
634 | dev_kfree_skb(skb); | ||
635 | 635 | ||
636 | return 0; | 636 | return 0; |
637 | } | 637 | } |
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 9d6e454a8f98..786d4b9c07ec 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c | |||
@@ -152,7 +152,7 @@ static int full_duplex[MAX_UNITS] = {0, }; | |||
152 | * This SUCKS. | 152 | * This SUCKS. |
153 | * We need a much better method to determine if dma_addr_t is 64-bit. | 153 | * We need a much better method to determine if dma_addr_t is 64-bit. |
154 | */ | 154 | */ |
155 | #if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) | 155 | #if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) |
156 | /* 64-bit dma_addr_t */ | 156 | /* 64-bit dma_addr_t */ |
157 | #define ADDR_64BITS /* This chip uses 64 bit addresses. */ | 157 | #define ADDR_64BITS /* This chip uses 64 bit addresses. */ |
158 | #define netdrv_addr_t u64 | 158 | #define netdrv_addr_t u64 |
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 675ac99a79c6..a42acc3cc609 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c | |||
@@ -144,14 +144,14 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
144 | * modem interface from an RNDIS non-modem. | 144 | * modem interface from an RNDIS non-modem. |
145 | */ | 145 | */ |
146 | if (rndis) { | 146 | if (rndis) { |
147 | struct usb_cdc_acm_descriptor *d; | 147 | struct usb_cdc_acm_descriptor *acm; |
148 | 148 | ||
149 | d = (void *) buf; | 149 | acm = (void *) buf; |
150 | if (d->bmCapabilities) { | 150 | if (acm->bmCapabilities) { |
151 | dev_dbg(&intf->dev, | 151 | dev_dbg(&intf->dev, |
152 | "ACM capabilities %02x, " | 152 | "ACM capabilities %02x, " |
153 | "not really RNDIS?\n", | 153 | "not really RNDIS?\n", |
154 | d->bmCapabilities); | 154 | acm->bmCapabilities); |
155 | goto bad_desc; | 155 | goto bad_desc; |
156 | } | 156 | } |
157 | } | 157 | } |
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c index a67638601477..16c7a0e87850 100644 --- a/drivers/net/usb/dm9601.c +++ b/drivers/net/usb/dm9601.c | |||
@@ -414,18 +414,16 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf) | |||
414 | dev->mii.reg_num_mask = 0x1f; | 414 | dev->mii.reg_num_mask = 0x1f; |
415 | 415 | ||
416 | /* reset */ | 416 | /* reset */ |
417 | ret = dm_write_reg(dev, DM_NET_CTRL, 1); | 417 | dm_write_reg(dev, DM_NET_CTRL, 1); |
418 | udelay(20); | 418 | udelay(20); |
419 | 419 | ||
420 | /* read MAC */ | 420 | /* read MAC */ |
421 | ret = dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr); | 421 | if (dm_read(dev, DM_PHY_ADDR, ETH_ALEN, dev->net->dev_addr) < 0) { |
422 | if (ret < 0) { | ||
423 | printk(KERN_ERR "Error reading MAC address\n"); | 422 | printk(KERN_ERR "Error reading MAC address\n"); |
424 | ret = -ENODEV; | 423 | ret = -ENODEV; |
425 | goto out; | 424 | goto out; |
426 | } | 425 | } |
427 | 426 | ||
428 | |||
429 | /* power up phy */ | 427 | /* power up phy */ |
430 | dm_write_reg(dev, DM_GPR_CTRL, 1); | 428 | dm_write_reg(dev, DM_GPR_CTRL, 1); |
431 | dm_write_reg(dev, DM_GPR_DATA, 0); | 429 | dm_write_reg(dev, DM_GPR_DATA, 0); |
@@ -489,6 +487,8 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
489 | b3..n: packet data | 487 | b3..n: packet data |
490 | */ | 488 | */ |
491 | 489 | ||
490 | len = skb->len; | ||
491 | |||
492 | if (skb_headroom(skb) < DM_TX_OVERHEAD) { | 492 | if (skb_headroom(skb) < DM_TX_OVERHEAD) { |
493 | struct sk_buff *skb2; | 493 | struct sk_buff *skb2; |
494 | 494 | ||
@@ -501,10 +501,9 @@ static struct sk_buff *dm9601_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
501 | 501 | ||
502 | __skb_push(skb, DM_TX_OVERHEAD); | 502 | __skb_push(skb, DM_TX_OVERHEAD); |
503 | 503 | ||
504 | len = skb->len; | ||
505 | /* usbnet adds padding if length is a multiple of packet size | 504 | /* usbnet adds padding if length is a multiple of packet size |
506 | if so, adjust length value in header */ | 505 | if so, adjust length value in header */ |
507 | if ((len % dev->maxpacket) == 0) | 506 | if ((skb->len % dev->maxpacket) == 0) |
508 | len++; | 507 | len++; |
509 | 508 | ||
510 | skb->data[0] = len; | 509 | skb->data[0] = len; |
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c index 5b16d9a1269a..a12f576391cf 100644 --- a/drivers/net/usb/usbnet.c +++ b/drivers/net/usb/usbnet.c | |||
@@ -953,11 +953,14 @@ static int usbnet_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
953 | /* don't assume the hardware handles USB_ZERO_PACKET | 953 | /* don't assume the hardware handles USB_ZERO_PACKET |
954 | * NOTE: strictly conforming cdc-ether devices should expect | 954 | * NOTE: strictly conforming cdc-ether devices should expect |
955 | * the ZLP here, but ignore the one-byte packet. | 955 | * the ZLP here, but ignore the one-byte packet. |
956 | * | ||
957 | * FIXME zero that byte, if it doesn't require a new skb. | ||
958 | */ | 956 | */ |
959 | if ((length % dev->maxpacket) == 0) | 957 | if ((length % dev->maxpacket) == 0) { |
960 | urb->transfer_buffer_length++; | 958 | urb->transfer_buffer_length++; |
959 | if (skb_tailroom(skb)) { | ||
960 | skb->data[skb->len] = 0; | ||
961 | __skb_put(skb, 1); | ||
962 | } | ||
963 | } | ||
961 | 964 | ||
962 | spin_lock_irqsave (&dev->txq.lock, flags); | 965 | spin_lock_irqsave (&dev->txq.lock, flags); |
963 | 966 | ||
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile index a1097f59fd46..32ed4136b0d4 100644 --- a/drivers/net/wireless/libertas/Makefile +++ b/drivers/net/wireless/libertas/Makefile | |||
@@ -2,7 +2,7 @@ libertas-objs := main.o fw.o wext.o \ | |||
2 | rx.o tx.o cmd.o \ | 2 | rx.o tx.o cmd.o \ |
3 | cmdresp.o scan.o \ | 3 | cmdresp.o scan.o \ |
4 | join.o 11d.o \ | 4 | join.o 11d.o \ |
5 | ioctl.o debugfs.o \ | 5 | debugfs.o \ |
6 | ethtool.o assoc.o | 6 | ethtool.o assoc.o |
7 | 7 | ||
8 | usb8xxx-objs += if_bootcmd.o | 8 | usb8xxx-objs += if_bootcmd.o |
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README index 1f92f50b643c..0b133ce63805 100644 --- a/drivers/net/wireless/libertas/README +++ b/drivers/net/wireless/libertas/README | |||
@@ -28,281 +28,6 @@ DRIVER LOADING | |||
28 | 28 | ||
29 | insmod usb8388.ko [fw_name=usb8388.bin] | 29 | insmod usb8388.ko [fw_name=usb8388.bin] |
30 | 30 | ||
31 | ===================== | ||
32 | IWPRIV COMMAND | ||
33 | ===================== | ||
34 | |||
35 | NAME | ||
36 | This manual describes the usage of private commands used in Marvell WLAN | ||
37 | Linux Driver. All the commands available in Wlanconfig will not be available | ||
38 | in the iwpriv. | ||
39 | |||
40 | SYNOPSIS | ||
41 | iwpriv <ethX> <command> [sub-command] ... | ||
42 | |||
43 | iwpriv ethX setregioncode <n> | ||
44 | iwpriv ethX getregioncode | ||
45 | |||
46 | Version 5 Command: | ||
47 | iwpriv ethX ledgpio <n> | ||
48 | |||
49 | BT Commands: | ||
50 | The blinding table (BT) contains a list of mac addresses that will be, | ||
51 | by default, ignored by the firmware. It is also possible to invert this | ||
52 | behavior so that we will ignore all traffic except for the portion | ||
53 | coming from mac addresess in the list. It is primarily used for | ||
54 | debugging and testing networks. It can be edited and inspected with | ||
55 | the following commands: | ||
56 | |||
57 | iwpriv ethX bt_reset | ||
58 | iwpriv ethX bt_add <mac_address> | ||
59 | iwpriv ethX bt_del <mac_address> | ||
60 | iwpriv ethX bt_list <id> | ||
61 | iwpriv ethX bt_get_invert <n> | ||
62 | iwpriv ethX bt_set_invert <n> | ||
63 | |||
64 | FWT Commands: | ||
65 | The forwarding table (FWT) is a feature used to manage mesh network | ||
66 | routing in the firmware. The FWT is essentially a routing table that | ||
67 | associates a destination mac address (da) with a next hop receiver | ||
68 | address (ra). The FWT can be inspected and edited with the following | ||
69 | iwpriv commands, which are described in greater detail below. | ||
70 | Eventually, the table will be automatically maintained by a custom | ||
71 | routing protocol. | ||
72 | |||
73 | NOTE: FWT commands replace the previous DFT commands. What were the DFT | ||
74 | commands?, you might ask. They were an earlier API to the firmware that | ||
75 | implemented a simple MAC-layer forwarding mechanism. In the unlikely | ||
76 | event that you were using these commands, you must migrate to the new | ||
77 | FWT commands which can be used to achieve the same functionality. | ||
78 | |||
79 | iwpriv ethX fwt_add [parameters] | ||
80 | iwpriv ethX fwt_del [parameters] | ||
81 | iwpriv ethX fwt_lookup [parameters] | ||
82 | iwpriv ethX fwt_list [parameters] | ||
83 | iwpriv ethX fwt_list_route [parameters] | ||
84 | iwpriv ethX fwt_list_neigh [parameters] | ||
85 | iwpriv ethX fwt_reset [parameters] | ||
86 | iwpriv ethX fwt_cleanup | ||
87 | iwpriv ethX fwt_time | ||
88 | |||
89 | MESH Commands: | ||
90 | |||
91 | The MESH commands are used to configure various features of the mesh | ||
92 | routing protocol. The following commands are supported: | ||
93 | |||
94 | iwpriv ethX mesh_get_ttl | ||
95 | iwpriv ethX mesh_set_ttl ttl | ||
96 | |||
97 | DESCRIPTION | ||
98 | Those commands are used to send additional commands to the Marvell WLAN | ||
99 | card via the Linux device driver. | ||
100 | |||
101 | The ethX parameter specifies the network device that is to be used to | ||
102 | perform this command on. it could be eth0, eth1 etc. | ||
103 | |||
104 | setregioncode | ||
105 | This command is used to set the region code in the station. | ||
106 | where value is 'region code' for various regions like | ||
107 | USA FCC, Canada IC, Spain, France, Europe ETSI, Japan ... | ||
108 | |||
109 | Usage: | ||
110 | iwpriv ethX setregioncode 0x10: set region code to USA (0x10). | ||
111 | |||
112 | getregioncode | ||
113 | This command is used to get the region code information set in the | ||
114 | station. | ||
115 | |||
116 | ledgpio | ||
117 | This command is used to set/get LEDs. | ||
118 | |||
119 | iwpriv ethX ledgpio <LEDs> | ||
120 | will set the corresponding LED for the GPIO Line. | ||
121 | |||
122 | iwpriv ethX ledgpio | ||
123 | will give u which LEDs are Enabled. | ||
124 | |||
125 | Usage: | ||
126 | iwpriv eth1 ledgpio 1 0 2 1 3 4 | ||
127 | will enable | ||
128 | LED 1 -> GPIO 0 | ||
129 | LED 2 -> GPIO 1 | ||
130 | LED 3 -> GPIO 4 | ||
131 | |||
132 | iwpriv eth1 ledgpio | ||
133 | shows LED information in the format as mentioned above. | ||
134 | |||
135 | Note: LED0 is invalid | ||
136 | Note: Maximum Number of LEDs are 16. | ||
137 | |||
138 | fwt_add | ||
139 | This command is used to insert an entry into the FWT table. The list of | ||
140 | parameters must follow the following structure: | ||
141 | |||
142 | iwpriv ethX fwt_add da ra [metric dir rate ssn dsn hopcount ttl expiration sleepmode snr] | ||
143 | |||
144 | The parameters between brackets are optional, but they must appear in | ||
145 | the order specified. For example, if you want to specify the metric, | ||
146 | you must also specify the dir, ssn, and dsn but you need not specify the | ||
147 | hopcount, expiration, sleepmode, or snr. Any unspecified parameters | ||
148 | will be assigned the defaults specified below. | ||
149 | |||
150 | The different parameters are:- | ||
151 | da -- DA MAC address in the form 00:11:22:33:44:55 | ||
152 | ra -- RA MAC address in the form 00:11:22:33:44:55 | ||
153 | metric -- route metric (cost: smaller-metric routes are | ||
154 | preferred, default is 0) | ||
155 | dir -- direction (1 for direct, 0 for reverse, | ||
156 | default is 1) | ||
157 | rate -- data rate used for transmission to the RA, | ||
158 | as specified for the rateadapt command, | ||
159 | default is 3 (11Mbps) | ||
160 | ssn -- Source Sequence Number (time at the RA for | ||
161 | reverse routes. Default is 0) | ||
162 | dsn -- Destination Sequence Number (time at the DA | ||
163 | for direct routes. Default is 0) | ||
164 | hopcount -- hop count (currently unused, default is 0) | ||
165 | ttl -- TTL (Only used in reverse entries) | ||
166 | expiration -- entry expiration (in ticks, where a tick is | ||
167 | 1024us, or ~ 1ms. Use 0 for an indefinite | ||
168 | entry, default is 0) | ||
169 | sleepmode -- RA's sleep mode (currently unused, default is | ||
170 | 0) | ||
171 | snr -- SNR in the link to RA (currently unused, | ||
172 | default is 0) | ||
173 | |||
174 | The command does not return anything. | ||
175 | |||
176 | fwt_del | ||
177 | This command is used to remove an entry to the FWT table. The list of | ||
178 | parameters must follow the following structure: | ||
179 | |||
180 | iwpriv ethX fwt_del da ra [dir] | ||
181 | |||
182 | where the different parameters are:- | ||
183 | da -- DA MAC address (in the form "00:11:22:33:44:55") | ||
184 | ra -- RA MAC address (in the form "00:11:22:33:44:55") | ||
185 | dir -- direction (1 for direct, 0 for reverse, | ||
186 | default is 1) | ||
187 | |||
188 | The command does not return anything. | ||
189 | |||
190 | fwt_lookup | ||
191 | This command is used to get the best route in the FWT table to a given | ||
192 | host. The only parameter is the MAC address of the host that is being | ||
193 | looked for. | ||
194 | |||
195 | iwpriv ethX fwt_lookup da | ||
196 | |||
197 | where:- | ||
198 | da -- DA MAC address (in the form "00:11:22:33:44:55") | ||
199 | |||
200 | The command returns an output string identical to the one returned by | ||
201 | fwt_list described below. | ||
202 | |||
203 | |||
204 | fwt_list | ||
205 | This command is used to list a route from the FWT table. The only | ||
206 | parameter is the index into the table. If you want to list all the | ||
207 | routes in a table, start with index=0, and keep listing until you get a | ||
208 | "(null)" string. Note that the indicies may change as the fwt is | ||
209 | updated. It is expected that most users will not use fwt_list directly, | ||
210 | but that a utility similar to the traditional route command will be used | ||
211 | to invoke fwt_list over and over. | ||
212 | |||
213 | iwpriv ethX fwt_list index | ||
214 | |||
215 | The output is a string of the following form: | ||
216 | |||
217 | da ra valid metric dir rate ssn dsn hopcount ttl expiration | ||
218 | sleepmode snr precursor | ||
219 | |||
220 | where the different fields are:- | ||
221 | da -- DA MAC address (in the form "00:11:22:33:44:55") | ||
222 | ra -- RA MAC address (in the form "00:11:22:33:44:55") | ||
223 | valid -- whether the route is valid (0 if not valid) | ||
224 | metric -- route metric (cost: smaller-metric routes are preferred) | ||
225 | dir -- direction (1 for direct, 0 for reverse) | ||
226 | rate -- data rate used for transmission to the RA, | ||
227 | as specified for the rateadapt command | ||
228 | ssn -- Source Sequence Number (time at the RA for reverse routes) | ||
229 | dsn -- Destination Sequence Number (time at the DA for direct routes) | ||
230 | hopcount -- hop count (currently unused) | ||
231 | ttl -- TTL (only used in reverse entries) | ||
232 | expiration -- entry expiration (in ticks, where a tick is 1024us, or ~ 1ms. Use 0 for an indefinite entry) | ||
233 | sleepmode -- RA's sleep mode (currently unused) | ||
234 | snr -- SNR in the link to RA (currently unused) | ||
235 | precursor -- predecessor in direct routes | ||
236 | |||
237 | fwt_list_route | ||
238 | This command is equivalent to fwt_list. | ||
239 | |||
240 | fwt_list_neigh | ||
241 | This command is used to list a neighbor from the FWT table. The only | ||
242 | parameter is the neighbor ID. If you want to list all the neighbors in a | ||
243 | table, start with nid=0, and keep incrementing nid until you get a | ||
244 | "(null)" string. Note that the nid from a fwt_list_route command can be | ||
245 | used as an input to this command. Also note that this command is meant | ||
246 | mostly for debugging. It is expected that users will use fwt_lookup. | ||
247 | One important reason for this is that the neighbor id may change as the | ||
248 | neighbor table is altered. | ||
249 | |||
250 | iwpriv ethX fwt_list_neigh nid | ||
251 | |||
252 | The output is a string of the following form: | ||
253 | |||
254 | ra sleepmode snr references | ||
255 | |||
256 | where the different fields are:- | ||
257 | ra -- RA MAC address (in the form "00:11:22:33:44:55") | ||
258 | sleepmode -- RA's sleep mode (currently unused) | ||
259 | snr -- SNR in the link to RA (currently unused) | ||
260 | references -- RA's reference counter | ||
261 | |||
262 | fwt_reset | ||
263 | This command is used to reset the FWT table, getting rid of all the | ||
264 | entries. There are no input parameters. | ||
265 | |||
266 | iwpriv ethX fwt_reset | ||
267 | |||
268 | The command does not return anything. | ||
269 | |||
270 | fwt_cleanup | ||
271 | This command is used to perform user-based garbage recollection. The | ||
272 | FWT table is checked, and all the entries that are expired or invalid | ||
273 | are cleaned. Note that this is exported to the driver for debugging | ||
274 | purposes, as garbage collection is also fired by the firmware when in | ||
275 | space problems. There are no input parameters. | ||
276 | |||
277 | iwpriv ethX fwt_cleanup | ||
278 | |||
279 | The command does returns the number of invalid/expired routes deleted. | ||
280 | |||
281 | fwt_time | ||
282 | This command returns a card's internal time representation. It is this | ||
283 | time that is used to represent the expiration times of FWT entries. The | ||
284 | number is not consistent from card to card; it is simply a timer count. | ||
285 | The fwt_time command is used to inspect the timer so that expiration | ||
286 | times reported by fwt_list can be properly interpreted. | ||
287 | |||
288 | iwpriv ethX fwt_time | ||
289 | |||
290 | mesh_get_ttl | ||
291 | |||
292 | The mesh ttl is the number of hops a mesh packet can traverse before it | ||
293 | is dropped. This parameter is used to prevent infinite loops in the | ||
294 | mesh network. The value returned by this function is the ttl assigned | ||
295 | to all mesh packets. Currently there is no way to control the ttl on a | ||
296 | per packet or per socket basis. | ||
297 | |||
298 | iwpriv ethX mesh_get_ttl | ||
299 | |||
300 | mesh_set_ttl ttl | ||
301 | |||
302 | Set the ttl. The argument must be between 0 and 255. | ||
303 | |||
304 | iwpriv ethX mesh_set_ttl <ttl> | ||
305 | |||
306 | ========================= | 31 | ========================= |
307 | ETHTOOL | 32 | ETHTOOL |
308 | ========================= | 33 | ========================= |
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index f67efa0815fe..afd5617dd92b 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -323,6 +323,8 @@ static int assoc_helper_secinfo(wlan_private *priv, | |||
323 | { | 323 | { |
324 | wlan_adapter *adapter = priv->adapter; | 324 | wlan_adapter *adapter = priv->adapter; |
325 | int ret = 0; | 325 | int ret = 0; |
326 | u32 do_wpa; | ||
327 | u32 rsn = 0; | ||
326 | 328 | ||
327 | lbs_deb_enter(LBS_DEB_ASSOC); | 329 | lbs_deb_enter(LBS_DEB_ASSOC); |
328 | 330 | ||
@@ -333,12 +335,34 @@ static int assoc_helper_secinfo(wlan_private *priv, | |||
333 | if (ret) | 335 | if (ret) |
334 | goto out; | 336 | goto out; |
335 | 337 | ||
336 | /* enable/disable RSN */ | 338 | /* If RSN is already enabled, don't try to enable it again, since |
339 | * ENABLE_RSN resets internal state machines and will clobber the | ||
340 | * 4-way WPA handshake. | ||
341 | */ | ||
342 | |||
343 | /* Get RSN enabled/disabled */ | ||
337 | ret = libertas_prepare_and_send_command(priv, | 344 | ret = libertas_prepare_and_send_command(priv, |
338 | cmd_802_11_enable_rsn, | 345 | cmd_802_11_enable_rsn, |
339 | cmd_act_set, | 346 | cmd_act_set, |
340 | cmd_option_waitforrsp, | 347 | cmd_option_waitforrsp, |
341 | 0, assoc_req); | 348 | 0, &rsn); |
349 | if (ret) { | ||
350 | lbs_deb_assoc("Failed to get RSN status: %d", ret); | ||
351 | goto out; | ||
352 | } | ||
353 | |||
354 | /* Don't re-enable RSN if it's already enabled */ | ||
355 | do_wpa = (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled); | ||
356 | if (do_wpa == rsn) | ||
357 | goto out; | ||
358 | |||
359 | /* Set RSN enabled/disabled */ | ||
360 | rsn = do_wpa; | ||
361 | ret = libertas_prepare_and_send_command(priv, | ||
362 | cmd_802_11_enable_rsn, | ||
363 | cmd_act_set, | ||
364 | cmd_option_waitforrsp, | ||
365 | 0, &rsn); | ||
342 | 366 | ||
343 | out: | 367 | out: |
344 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | 368 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c index 124e029f1bf4..13f6528abb00 100644 --- a/drivers/net/wireless/libertas/cmd.c +++ b/drivers/net/wireless/libertas/cmd.c | |||
@@ -228,17 +228,19 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv, | |||
228 | void * pdata_buf) | 228 | void * pdata_buf) |
229 | { | 229 | { |
230 | struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn; | 230 | struct cmd_ds_802_11_enable_rsn *penableRSN = &cmd->params.enbrsn; |
231 | struct assoc_request * assoc_req = pdata_buf; | 231 | u32 * enable = pdata_buf; |
232 | 232 | ||
233 | lbs_deb_enter(LBS_DEB_CMD); | 233 | lbs_deb_enter(LBS_DEB_CMD); |
234 | 234 | ||
235 | cmd->command = cpu_to_le16(cmd_802_11_enable_rsn); | 235 | cmd->command = cpu_to_le16(cmd_802_11_enable_rsn); |
236 | cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); | 236 | cmd->size = cpu_to_le16(sizeof(*penableRSN) + S_DS_GEN); |
237 | penableRSN->action = cpu_to_le16(cmd_action); | 237 | penableRSN->action = cpu_to_le16(cmd_action); |
238 | if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { | 238 | |
239 | penableRSN->enable = cpu_to_le16(cmd_enable_rsn); | 239 | if (cmd_action == cmd_act_set) { |
240 | } else { | 240 | if (*enable) |
241 | penableRSN->enable = cpu_to_le16(cmd_disable_rsn); | 241 | penableRSN->enable = cpu_to_le16(cmd_enable_rsn); |
242 | else | ||
243 | penableRSN->enable = cpu_to_le16(cmd_enable_rsn); | ||
242 | } | 244 | } |
243 | 245 | ||
244 | lbs_deb_leave(LBS_DEB_CMD); | 246 | lbs_deb_leave(LBS_DEB_CMD); |
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c index 0c3b9a583d83..6ac0d4752fa4 100644 --- a/drivers/net/wireless/libertas/cmdresp.c +++ b/drivers/net/wireless/libertas/cmdresp.c | |||
@@ -537,6 +537,24 @@ static int wlan_ret_get_log(wlan_private * priv, | |||
537 | return 0; | 537 | return 0; |
538 | } | 538 | } |
539 | 539 | ||
540 | static int libertas_ret_802_11_enable_rsn(wlan_private * priv, | ||
541 | struct cmd_ds_command *resp) | ||
542 | { | ||
543 | struct cmd_ds_802_11_enable_rsn *enable_rsn = &resp->params.enbrsn; | ||
544 | wlan_adapter *adapter = priv->adapter; | ||
545 | u32 * pdata_buf = adapter->cur_cmd->pdata_buf; | ||
546 | |||
547 | lbs_deb_enter(LBS_DEB_CMD); | ||
548 | |||
549 | if (enable_rsn->action == cpu_to_le16(cmd_act_get)) { | ||
550 | if (pdata_buf) | ||
551 | *pdata_buf = (u32) le16_to_cpu(enable_rsn->enable); | ||
552 | } | ||
553 | |||
554 | lbs_deb_enter(LBS_DEB_CMD); | ||
555 | return 0; | ||
556 | } | ||
557 | |||
540 | static inline int handle_cmd_response(u16 respcmd, | 558 | static inline int handle_cmd_response(u16 respcmd, |
541 | struct cmd_ds_command *resp, | 559 | struct cmd_ds_command *resp, |
542 | wlan_private *priv) | 560 | wlan_private *priv) |
@@ -610,7 +628,10 @@ static inline int handle_cmd_response(u16 respcmd, | |||
610 | case cmd_ret_802_11_authenticate: | 628 | case cmd_ret_802_11_authenticate: |
611 | case cmd_ret_802_11_radio_control: | 629 | case cmd_ret_802_11_radio_control: |
612 | case cmd_ret_802_11_beacon_stop: | 630 | case cmd_ret_802_11_beacon_stop: |
631 | break; | ||
632 | |||
613 | case cmd_ret_802_11_enable_rsn: | 633 | case cmd_ret_802_11_enable_rsn: |
634 | ret = libertas_ret_802_11_enable_rsn(priv, resp); | ||
614 | break; | 635 | break; |
615 | 636 | ||
616 | case cmd_ret_802_11_data_rate: | 637 | case cmd_ret_802_11_data_rate: |
diff --git a/drivers/net/wireless/libertas/hostcmd.h b/drivers/net/wireless/libertas/hostcmd.h index 3acf93988125..09b898f6719c 100644 --- a/drivers/net/wireless/libertas/hostcmd.h +++ b/drivers/net/wireless/libertas/hostcmd.h | |||
@@ -503,7 +503,7 @@ struct cmd_ds_802_11_ad_hoc_join { | |||
503 | struct cmd_ds_802_11_enable_rsn { | 503 | struct cmd_ds_802_11_enable_rsn { |
504 | __le16 action; | 504 | __le16 action; |
505 | __le16 enable; | 505 | __le16 enable; |
506 | }; | 506 | } __attribute__ ((packed)); |
507 | 507 | ||
508 | struct MrvlIEtype_keyParamSet { | 508 | struct MrvlIEtype_keyParamSet { |
509 | /* type ID */ | 509 | /* type ID */ |
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c deleted file mode 100644 index f41081585564..000000000000 --- a/drivers/net/wireless/libertas/ioctl.c +++ /dev/null | |||
@@ -1,1081 +0,0 @@ | |||
1 | /** | ||
2 | * This file contains ioctl functions | ||
3 | */ | ||
4 | |||
5 | #include <linux/ctype.h> | ||
6 | #include <linux/delay.h> | ||
7 | #include <linux/if.h> | ||
8 | #include <linux/if_arp.h> | ||
9 | #include <linux/wireless.h> | ||
10 | |||
11 | #include <net/iw_handler.h> | ||
12 | #include <net/ieee80211.h> | ||
13 | |||
14 | #include "host.h" | ||
15 | #include "radiotap.h" | ||
16 | #include "decl.h" | ||
17 | #include "defs.h" | ||
18 | #include "dev.h" | ||
19 | #include "join.h" | ||
20 | #include "wext.h" | ||
21 | |||
22 | #define MAX_SCAN_CELL_SIZE (IW_EV_ADDR_LEN + \ | ||
23 | IW_ESSID_MAX_SIZE + \ | ||
24 | IW_EV_UINT_LEN + IW_EV_FREQ_LEN + \ | ||
25 | IW_EV_QUAL_LEN + IW_ESSID_MAX_SIZE + \ | ||
26 | IW_EV_PARAM_LEN + 40) /* 40 for WPAIE */ | ||
27 | |||
28 | #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ) | ||
29 | |||
30 | static int wlan_set_region(wlan_private * priv, u16 region_code) | ||
31 | { | ||
32 | int i; | ||
33 | int ret = 0; | ||
34 | |||
35 | for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) { | ||
36 | // use the region code to search for the index | ||
37 | if (region_code == libertas_region_code_to_index[i]) { | ||
38 | priv->adapter->regiontableindex = (u16) i; | ||
39 | priv->adapter->regioncode = region_code; | ||
40 | break; | ||
41 | } | ||
42 | } | ||
43 | |||
44 | // if it's unidentified region code | ||
45 | if (i >= MRVDRV_MAX_REGION_CODE) { | ||
46 | lbs_deb_ioctl("region Code not identified\n"); | ||
47 | ret = -1; | ||
48 | goto done; | ||
49 | } | ||
50 | |||
51 | if (libertas_set_regiontable(priv, priv->adapter->regioncode, 0)) { | ||
52 | ret = -EINVAL; | ||
53 | } | ||
54 | |||
55 | done: | ||
56 | lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static inline int hex2int(char c) | ||
61 | { | ||
62 | if (c >= '0' && c <= '9') | ||
63 | return (c - '0'); | ||
64 | if (c >= 'a' && c <= 'f') | ||
65 | return (c - 'a' + 10); | ||
66 | if (c >= 'A' && c <= 'F') | ||
67 | return (c - 'A' + 10); | ||
68 | return -1; | ||
69 | } | ||
70 | |||
71 | /* Convert a string representation of a MAC address ("xx:xx:xx:xx:xx:xx") | ||
72 | into binary format (6 bytes). | ||
73 | |||
74 | This function expects that each byte is represented with 2 characters | ||
75 | (e.g., 11:2:11:11:11:11 is invalid) | ||
76 | |||
77 | */ | ||
78 | static char *eth_str2addr(char *ethstr, u8 * addr) | ||
79 | { | ||
80 | int i, val, val2; | ||
81 | char *pos = ethstr; | ||
82 | |||
83 | /* get rid of initial blanks */ | ||
84 | while (*pos == ' ' || *pos == '\t') | ||
85 | ++pos; | ||
86 | |||
87 | for (i = 0; i < 6; i++) { | ||
88 | val = hex2int(*pos++); | ||
89 | if (val < 0) | ||
90 | return NULL; | ||
91 | val2 = hex2int(*pos++); | ||
92 | if (val2 < 0) | ||
93 | return NULL; | ||
94 | addr[i] = (val * 16 + val2) & 0xff; | ||
95 | |||
96 | if (i < 5 && *pos++ != ':') | ||
97 | return NULL; | ||
98 | } | ||
99 | return pos; | ||
100 | } | ||
101 | |||
102 | /* this writes xx:xx:xx:xx:xx:xx into ethstr | ||
103 | (ethstr must have space for 18 chars) */ | ||
104 | static int eth_addr2str(u8 * addr, char *ethstr) | ||
105 | { | ||
106 | int i; | ||
107 | char *pos = ethstr; | ||
108 | |||
109 | for (i = 0; i < 6; i++) { | ||
110 | sprintf(pos, "%02x", addr[i] & 0xff); | ||
111 | pos += 2; | ||
112 | if (i < 5) | ||
113 | *pos++ = ':'; | ||
114 | } | ||
115 | return 17; | ||
116 | } | ||
117 | |||
118 | /** | ||
119 | * @brief Add an entry to the BT table | ||
120 | * @param priv A pointer to wlan_private structure | ||
121 | * @param req A pointer to ifreq structure | ||
122 | * @return 0 --success, otherwise fail | ||
123 | */ | ||
124 | static int wlan_bt_add_ioctl(wlan_private * priv, struct ifreq *req) | ||
125 | { | ||
126 | struct iwreq *wrq = (struct iwreq *)req; | ||
127 | char ethaddrs_str[18]; | ||
128 | char *pos; | ||
129 | u8 ethaddr[ETH_ALEN]; | ||
130 | int ret; | ||
131 | |||
132 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
133 | |||
134 | if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, | ||
135 | sizeof(ethaddrs_str))) | ||
136 | return -EFAULT; | ||
137 | |||
138 | if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { | ||
139 | lbs_pr_info("BT_ADD: Invalid MAC address\n"); | ||
140 | return -EINVAL; | ||
141 | } | ||
142 | |||
143 | lbs_deb_ioctl("BT: adding %s\n", ethaddrs_str); | ||
144 | ret = libertas_prepare_and_send_command(priv, cmd_bt_access, | ||
145 | cmd_act_bt_access_add, | ||
146 | cmd_option_waitforrsp, 0, ethaddr); | ||
147 | lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | /** | ||
152 | * @brief Delete an entry from the BT table | ||
153 | * @param priv A pointer to wlan_private structure | ||
154 | * @param req A pointer to ifreq structure | ||
155 | * @return 0 --success, otherwise fail | ||
156 | */ | ||
157 | static int wlan_bt_del_ioctl(wlan_private * priv, struct ifreq *req) | ||
158 | { | ||
159 | struct iwreq *wrq = (struct iwreq *)req; | ||
160 | char ethaddrs_str[18]; | ||
161 | u8 ethaddr[ETH_ALEN]; | ||
162 | char *pos; | ||
163 | |||
164 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
165 | |||
166 | if (copy_from_user(ethaddrs_str, wrq->u.data.pointer, | ||
167 | sizeof(ethaddrs_str))) | ||
168 | return -EFAULT; | ||
169 | |||
170 | if ((pos = eth_str2addr(ethaddrs_str, ethaddr)) == NULL) { | ||
171 | lbs_pr_info("Invalid MAC address\n"); | ||
172 | return -EINVAL; | ||
173 | } | ||
174 | |||
175 | lbs_deb_ioctl("BT: deleting %s\n", ethaddrs_str); | ||
176 | |||
177 | return (libertas_prepare_and_send_command(priv, | ||
178 | cmd_bt_access, | ||
179 | cmd_act_bt_access_del, | ||
180 | cmd_option_waitforrsp, 0, ethaddr)); | ||
181 | |||
182 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
183 | return 0; | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * @brief Reset all entries from the BT table | ||
188 | * @param priv A pointer to wlan_private structure | ||
189 | * @return 0 --success, otherwise fail | ||
190 | */ | ||
191 | static int wlan_bt_reset_ioctl(wlan_private * priv) | ||
192 | { | ||
193 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
194 | |||
195 | lbs_pr_alert( "BT: resetting\n"); | ||
196 | |||
197 | return (libertas_prepare_and_send_command(priv, | ||
198 | cmd_bt_access, | ||
199 | cmd_act_bt_access_reset, | ||
200 | cmd_option_waitforrsp, 0, NULL)); | ||
201 | |||
202 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /** | ||
207 | * @brief List an entry from the BT table | ||
208 | * @param priv A pointer to wlan_private structure | ||
209 | * @param req A pointer to ifreq structure | ||
210 | * @return 0 --success, otherwise fail | ||
211 | */ | ||
212 | static int wlan_bt_list_ioctl(wlan_private * priv, struct ifreq *req) | ||
213 | { | ||
214 | int pos; | ||
215 | char *addr1; | ||
216 | struct iwreq *wrq = (struct iwreq *)req; | ||
217 | /* used to pass id and store the bt entry returned by the FW */ | ||
218 | union { | ||
219 | u32 id; | ||
220 | char addr1addr2[2 * ETH_ALEN]; | ||
221 | } param; | ||
222 | static char outstr[64]; | ||
223 | char *pbuf = outstr; | ||
224 | int ret; | ||
225 | |||
226 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
227 | |||
228 | if (copy_from_user(outstr, wrq->u.data.pointer, sizeof(outstr))) { | ||
229 | lbs_deb_ioctl("Copy from user failed\n"); | ||
230 | return -1; | ||
231 | } | ||
232 | param.id = simple_strtoul(outstr, NULL, 10); | ||
233 | pos = sprintf(pbuf, "%d: ", param.id); | ||
234 | pbuf += pos; | ||
235 | |||
236 | ret = libertas_prepare_and_send_command(priv, cmd_bt_access, | ||
237 | cmd_act_bt_access_list, | ||
238 | cmd_option_waitforrsp, 0, | ||
239 | (char *)¶m); | ||
240 | |||
241 | if (ret == 0) { | ||
242 | addr1 = param.addr1addr2; | ||
243 | |||
244 | pos = sprintf(pbuf, "BT includes node "); | ||
245 | pbuf += pos; | ||
246 | pos = eth_addr2str(addr1, pbuf); | ||
247 | pbuf += pos; | ||
248 | } else { | ||
249 | sprintf(pbuf, "(null)"); | ||
250 | pbuf += pos; | ||
251 | } | ||
252 | |||
253 | wrq->u.data.length = strlen(outstr); | ||
254 | if (copy_to_user(wrq->u.data.pointer, (char *)outstr, | ||
255 | wrq->u.data.length)) { | ||
256 | lbs_deb_ioctl("BT_LIST: Copy to user failed!\n"); | ||
257 | return -EFAULT; | ||
258 | } | ||
259 | |||
260 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
261 | return 0 ; | ||
262 | } | ||
263 | |||
264 | /** | ||
265 | * @brief Sets inverted state of blacklist (non-zero if inverted) | ||
266 | * @param priv A pointer to wlan_private structure | ||
267 | * @param req A pointer to ifreq structure | ||
268 | * @return 0 --success, otherwise fail | ||
269 | */ | ||
270 | static int wlan_bt_set_invert_ioctl(wlan_private * priv, struct ifreq *req) | ||
271 | { | ||
272 | int ret; | ||
273 | struct iwreq *wrq = (struct iwreq *)req; | ||
274 | union { | ||
275 | u32 id; | ||
276 | char addr1addr2[2 * ETH_ALEN]; | ||
277 | } param; | ||
278 | |||
279 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
280 | |||
281 | param.id = SUBCMD_DATA(wrq) ; | ||
282 | ret = libertas_prepare_and_send_command(priv, cmd_bt_access, | ||
283 | cmd_act_bt_access_set_invert, | ||
284 | cmd_option_waitforrsp, 0, | ||
285 | (char *)¶m); | ||
286 | if (ret != 0) | ||
287 | return -EFAULT; | ||
288 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | /** | ||
293 | * @brief Gets inverted state of blacklist (non-zero if inverted) | ||
294 | * @param priv A pointer to wlan_private structure | ||
295 | * @param req A pointer to ifreq structure | ||
296 | * @return 0 --success, otherwise fail | ||
297 | */ | ||
298 | static int wlan_bt_get_invert_ioctl(wlan_private * priv, struct ifreq *req) | ||
299 | { | ||
300 | struct iwreq *wrq = (struct iwreq *)req; | ||
301 | int ret; | ||
302 | union { | ||
303 | u32 id; | ||
304 | char addr1addr2[2 * ETH_ALEN]; | ||
305 | } param; | ||
306 | |||
307 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
308 | |||
309 | ret = libertas_prepare_and_send_command(priv, cmd_bt_access, | ||
310 | cmd_act_bt_access_get_invert, | ||
311 | cmd_option_waitforrsp, 0, | ||
312 | (char *)¶m); | ||
313 | |||
314 | if (ret == 0) | ||
315 | wrq->u.param.value = le32_to_cpu(param.id); | ||
316 | else | ||
317 | return -EFAULT; | ||
318 | |||
319 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | /** | ||
324 | * @brief Find the next parameter in an input string | ||
325 | * @param ptr A pointer to the input parameter string | ||
326 | * @return A pointer to the next parameter, or 0 if no parameters left. | ||
327 | */ | ||
328 | static char * next_param(char * ptr) | ||
329 | { | ||
330 | if (!ptr) return NULL; | ||
331 | while (*ptr == ' ' || *ptr == '\t') ++ptr; | ||
332 | return (*ptr == '\0') ? NULL : ptr; | ||
333 | } | ||
334 | |||
335 | /** | ||
336 | * @brief Add an entry to the FWT table | ||
337 | * @param priv A pointer to wlan_private structure | ||
338 | * @param req A pointer to ifreq structure | ||
339 | * @return 0 --success, otherwise fail | ||
340 | */ | ||
341 | static int wlan_fwt_add_ioctl(wlan_private * priv, struct ifreq *req) | ||
342 | { | ||
343 | struct iwreq *wrq = (struct iwreq *)req; | ||
344 | char in_str[128]; | ||
345 | static struct cmd_ds_fwt_access fwt_access; | ||
346 | char *ptr; | ||
347 | int ret; | ||
348 | |||
349 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
350 | |||
351 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) | ||
352 | return -EFAULT; | ||
353 | |||
354 | if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { | ||
355 | lbs_pr_alert( "FWT_ADD: Invalid MAC address 1\n"); | ||
356 | return -EINVAL; | ||
357 | } | ||
358 | |||
359 | if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { | ||
360 | lbs_pr_alert( "FWT_ADD: Invalid MAC address 2\n"); | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | |||
364 | if ((ptr = next_param(ptr))) | ||
365 | fwt_access.metric = | ||
366 | cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
367 | else | ||
368 | fwt_access.metric = cpu_to_le32(FWT_DEFAULT_METRIC); | ||
369 | |||
370 | if ((ptr = next_param(ptr))) | ||
371 | fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); | ||
372 | else | ||
373 | fwt_access.dir = FWT_DEFAULT_DIR; | ||
374 | |||
375 | if ((ptr = next_param(ptr))) | ||
376 | fwt_access.rate = (u8) simple_strtoul(ptr, &ptr, 10); | ||
377 | else | ||
378 | fwt_access.rate = FWT_DEFAULT_RATE; | ||
379 | |||
380 | if ((ptr = next_param(ptr))) | ||
381 | fwt_access.ssn = | ||
382 | cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
383 | else | ||
384 | fwt_access.ssn = cpu_to_le32(FWT_DEFAULT_SSN); | ||
385 | |||
386 | if ((ptr = next_param(ptr))) | ||
387 | fwt_access.dsn = | ||
388 | cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
389 | else | ||
390 | fwt_access.dsn = cpu_to_le32(FWT_DEFAULT_DSN); | ||
391 | |||
392 | if ((ptr = next_param(ptr))) | ||
393 | fwt_access.hopcount = simple_strtoul(ptr, &ptr, 10); | ||
394 | else | ||
395 | fwt_access.hopcount = FWT_DEFAULT_HOPCOUNT; | ||
396 | |||
397 | if ((ptr = next_param(ptr))) | ||
398 | fwt_access.ttl = simple_strtoul(ptr, &ptr, 10); | ||
399 | else | ||
400 | fwt_access.ttl = FWT_DEFAULT_TTL; | ||
401 | |||
402 | if ((ptr = next_param(ptr))) | ||
403 | fwt_access.expiration = | ||
404 | cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
405 | else | ||
406 | fwt_access.expiration = cpu_to_le32(FWT_DEFAULT_EXPIRATION); | ||
407 | |||
408 | if ((ptr = next_param(ptr))) | ||
409 | fwt_access.sleepmode = (u8)simple_strtoul(ptr, &ptr, 10); | ||
410 | else | ||
411 | fwt_access.sleepmode = FWT_DEFAULT_SLEEPMODE; | ||
412 | |||
413 | if ((ptr = next_param(ptr))) | ||
414 | fwt_access.snr = | ||
415 | cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
416 | else | ||
417 | fwt_access.snr = cpu_to_le32(FWT_DEFAULT_SNR); | ||
418 | |||
419 | #ifdef DEBUG | ||
420 | { | ||
421 | char ethaddr1_str[18], ethaddr2_str[18]; | ||
422 | eth_addr2str(fwt_access.da, ethaddr1_str); | ||
423 | eth_addr2str(fwt_access.ra, ethaddr2_str); | ||
424 | lbs_deb_ioctl("FWT_ADD: adding (da:%s,%i,ra:%s)\n", ethaddr1_str, | ||
425 | fwt_access.dir, ethaddr2_str); | ||
426 | lbs_deb_ioctl("FWT_ADD: ssn:%u dsn:%u met:%u hop:%u ttl:%u exp:%u slp:%u snr:%u\n", | ||
427 | fwt_access.ssn, fwt_access.dsn, fwt_access.metric, | ||
428 | fwt_access.hopcount, fwt_access.ttl, fwt_access.expiration, | ||
429 | fwt_access.sleepmode, fwt_access.snr); | ||
430 | } | ||
431 | #endif | ||
432 | |||
433 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
434 | cmd_act_fwt_access_add, | ||
435 | cmd_option_waitforrsp, 0, | ||
436 | (void *)&fwt_access); | ||
437 | |||
438 | lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); | ||
439 | return ret; | ||
440 | } | ||
441 | |||
442 | /** | ||
443 | * @brief Delete an entry from the FWT table | ||
444 | * @param priv A pointer to wlan_private structure | ||
445 | * @param req A pointer to ifreq structure | ||
446 | * @return 0 --success, otherwise fail | ||
447 | */ | ||
448 | static int wlan_fwt_del_ioctl(wlan_private * priv, struct ifreq *req) | ||
449 | { | ||
450 | struct iwreq *wrq = (struct iwreq *)req; | ||
451 | char in_str[64]; | ||
452 | static struct cmd_ds_fwt_access fwt_access; | ||
453 | char *ptr; | ||
454 | int ret; | ||
455 | |||
456 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
457 | |||
458 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) | ||
459 | return -EFAULT; | ||
460 | |||
461 | if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { | ||
462 | lbs_pr_alert( "FWT_DEL: Invalid MAC address 1\n"); | ||
463 | return -EINVAL; | ||
464 | } | ||
465 | |||
466 | if ((ptr = eth_str2addr(ptr, fwt_access.ra)) == NULL) { | ||
467 | lbs_pr_alert( "FWT_DEL: Invalid MAC address 2\n"); | ||
468 | return -EINVAL; | ||
469 | } | ||
470 | |||
471 | if ((ptr = next_param(ptr))) | ||
472 | fwt_access.dir = (u8)simple_strtoul(ptr, &ptr, 10); | ||
473 | else | ||
474 | fwt_access.dir = FWT_DEFAULT_DIR; | ||
475 | |||
476 | #ifdef DEBUG | ||
477 | { | ||
478 | char ethaddr1_str[18], ethaddr2_str[18]; | ||
479 | lbs_deb_ioctl("FWT_DEL: line is %s\n", in_str); | ||
480 | eth_addr2str(fwt_access.da, ethaddr1_str); | ||
481 | eth_addr2str(fwt_access.ra, ethaddr2_str); | ||
482 | lbs_deb_ioctl("FWT_DEL: removing (da:%s,ra:%s,dir:%d)\n", ethaddr1_str, | ||
483 | ethaddr2_str, fwt_access.dir); | ||
484 | } | ||
485 | #endif | ||
486 | |||
487 | ret = libertas_prepare_and_send_command(priv, | ||
488 | cmd_fwt_access, | ||
489 | cmd_act_fwt_access_del, | ||
490 | cmd_option_waitforrsp, 0, | ||
491 | (void *)&fwt_access); | ||
492 | lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); | ||
493 | return ret; | ||
494 | } | ||
495 | |||
496 | |||
497 | /** | ||
498 | * @brief Print route parameters | ||
499 | * @param fwt_access struct cmd_ds_fwt_access with route info | ||
500 | * @param buf destination buffer for route info | ||
501 | */ | ||
502 | static void print_route(struct cmd_ds_fwt_access fwt_access, char *buf) | ||
503 | { | ||
504 | buf += sprintf(buf, " "); | ||
505 | buf += eth_addr2str(fwt_access.da, buf); | ||
506 | buf += sprintf(buf, " "); | ||
507 | buf += eth_addr2str(fwt_access.ra, buf); | ||
508 | buf += sprintf(buf, " %u", fwt_access.valid); | ||
509 | buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.metric)); | ||
510 | buf += sprintf(buf, " %u", fwt_access.dir); | ||
511 | buf += sprintf(buf, " %u", fwt_access.rate); | ||
512 | buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.ssn)); | ||
513 | buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.dsn)); | ||
514 | buf += sprintf(buf, " %u", fwt_access.hopcount); | ||
515 | buf += sprintf(buf, " %u", fwt_access.ttl); | ||
516 | buf += sprintf(buf, " %u", le32_to_cpu(fwt_access.expiration)); | ||
517 | buf += sprintf(buf, " %u", fwt_access.sleepmode); | ||
518 | buf += sprintf(buf, " %u ", le32_to_cpu(fwt_access.snr)); | ||
519 | buf += eth_addr2str(fwt_access.prec, buf); | ||
520 | } | ||
521 | |||
522 | /** | ||
523 | * @brief Lookup an entry in the FWT table | ||
524 | * @param priv A pointer to wlan_private structure | ||
525 | * @param req A pointer to ifreq structure | ||
526 | * @return 0 --success, otherwise fail | ||
527 | */ | ||
528 | static int wlan_fwt_lookup_ioctl(wlan_private * priv, struct ifreq *req) | ||
529 | { | ||
530 | struct iwreq *wrq = (struct iwreq *)req; | ||
531 | char in_str[64]; | ||
532 | char *ptr; | ||
533 | static struct cmd_ds_fwt_access fwt_access; | ||
534 | static char out_str[128]; | ||
535 | int ret; | ||
536 | |||
537 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
538 | |||
539 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) | ||
540 | return -EFAULT; | ||
541 | |||
542 | if ((ptr = eth_str2addr(in_str, fwt_access.da)) == NULL) { | ||
543 | lbs_pr_alert( "FWT_LOOKUP: Invalid MAC address\n"); | ||
544 | return -EINVAL; | ||
545 | } | ||
546 | |||
547 | #ifdef DEBUG | ||
548 | { | ||
549 | char ethaddr1_str[18]; | ||
550 | lbs_deb_ioctl("FWT_LOOKUP: line is %s\n", in_str); | ||
551 | eth_addr2str(fwt_access.da, ethaddr1_str); | ||
552 | lbs_deb_ioctl("FWT_LOOKUP: looking for (da:%s)\n", ethaddr1_str); | ||
553 | } | ||
554 | #endif | ||
555 | |||
556 | ret = libertas_prepare_and_send_command(priv, | ||
557 | cmd_fwt_access, | ||
558 | cmd_act_fwt_access_lookup, | ||
559 | cmd_option_waitforrsp, 0, | ||
560 | (void *)&fwt_access); | ||
561 | |||
562 | if (ret == 0) | ||
563 | print_route(fwt_access, out_str); | ||
564 | else | ||
565 | sprintf(out_str, "(null)"); | ||
566 | |||
567 | wrq->u.data.length = strlen(out_str); | ||
568 | if (copy_to_user(wrq->u.data.pointer, (char *)out_str, | ||
569 | wrq->u.data.length)) { | ||
570 | lbs_deb_ioctl("FWT_LOOKUP: Copy to user failed!\n"); | ||
571 | return -EFAULT; | ||
572 | } | ||
573 | |||
574 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * @brief Reset all entries from the FWT table | ||
580 | * @param priv A pointer to wlan_private structure | ||
581 | * @return 0 --success, otherwise fail | ||
582 | */ | ||
583 | static int wlan_fwt_reset_ioctl(wlan_private * priv) | ||
584 | { | ||
585 | lbs_deb_ioctl("FWT: resetting\n"); | ||
586 | |||
587 | return (libertas_prepare_and_send_command(priv, | ||
588 | cmd_fwt_access, | ||
589 | cmd_act_fwt_access_reset, | ||
590 | cmd_option_waitforrsp, 0, NULL)); | ||
591 | } | ||
592 | |||
593 | /** | ||
594 | * @brief List an entry from the FWT table | ||
595 | * @param priv A pointer to wlan_private structure | ||
596 | * @param req A pointer to ifreq structure | ||
597 | * @return 0 --success, otherwise fail | ||
598 | */ | ||
599 | static int wlan_fwt_list_ioctl(wlan_private * priv, struct ifreq *req) | ||
600 | { | ||
601 | struct iwreq *wrq = (struct iwreq *)req; | ||
602 | char in_str[8]; | ||
603 | static struct cmd_ds_fwt_access fwt_access; | ||
604 | char *ptr = in_str; | ||
605 | static char out_str[128]; | ||
606 | char *pbuf = out_str; | ||
607 | int ret = 0; | ||
608 | |||
609 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
610 | |||
611 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) { | ||
612 | ret = -EFAULT; | ||
613 | goto out; | ||
614 | } | ||
615 | |||
616 | fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
617 | |||
618 | #ifdef DEBUG | ||
619 | { | ||
620 | lbs_deb_ioctl("FWT_LIST: line is %s\n", in_str); | ||
621 | lbs_deb_ioctl("FWT_LIST: listing id:%i\n", le32_to_cpu(fwt_access.id)); | ||
622 | } | ||
623 | #endif | ||
624 | |||
625 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
626 | cmd_act_fwt_access_list, | ||
627 | cmd_option_waitforrsp, 0, (void *)&fwt_access); | ||
628 | |||
629 | if (ret == 0) | ||
630 | print_route(fwt_access, pbuf); | ||
631 | else | ||
632 | pbuf += sprintf(pbuf, " (null)"); | ||
633 | |||
634 | wrq->u.data.length = strlen(out_str); | ||
635 | if (copy_to_user(wrq->u.data.pointer, (char *)out_str, | ||
636 | wrq->u.data.length)) { | ||
637 | lbs_deb_ioctl("FWT_LIST: Copy to user failed!\n"); | ||
638 | ret = -EFAULT; | ||
639 | goto out; | ||
640 | } | ||
641 | |||
642 | ret = 0; | ||
643 | |||
644 | out: | ||
645 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
646 | return ret; | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * @brief List an entry from the FRT table | ||
651 | * @param priv A pointer to wlan_private structure | ||
652 | * @param req A pointer to ifreq structure | ||
653 | * @return 0 --success, otherwise fail | ||
654 | */ | ||
655 | static int wlan_fwt_list_route_ioctl(wlan_private * priv, struct ifreq *req) | ||
656 | { | ||
657 | struct iwreq *wrq = (struct iwreq *)req; | ||
658 | char in_str[64]; | ||
659 | static struct cmd_ds_fwt_access fwt_access; | ||
660 | char *ptr = in_str; | ||
661 | static char out_str[128]; | ||
662 | char *pbuf = out_str; | ||
663 | int ret; | ||
664 | |||
665 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
666 | |||
667 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) | ||
668 | return -EFAULT; | ||
669 | |||
670 | fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
671 | |||
672 | #ifdef DEBUG | ||
673 | { | ||
674 | lbs_deb_ioctl("FWT_LIST_ROUTE: line is %s\n", in_str); | ||
675 | lbs_deb_ioctl("FWT_LIST_ROUTE: listing id:%i\n", le32_to_cpu(fwt_access.id)); | ||
676 | } | ||
677 | #endif | ||
678 | |||
679 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
680 | cmd_act_fwt_access_list_route, | ||
681 | cmd_option_waitforrsp, 0, (void *)&fwt_access); | ||
682 | |||
683 | if (ret == 0) { | ||
684 | print_route(fwt_access, pbuf); | ||
685 | } else | ||
686 | pbuf += sprintf(pbuf, " (null)"); | ||
687 | |||
688 | wrq->u.data.length = strlen(out_str); | ||
689 | if (copy_to_user(wrq->u.data.pointer, (char *)out_str, | ||
690 | wrq->u.data.length)) { | ||
691 | lbs_deb_ioctl("FWT_LIST_ROUTE: Copy to user failed!\n"); | ||
692 | return -EFAULT; | ||
693 | } | ||
694 | |||
695 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | /** | ||
700 | * @brief List an entry from the FNT table | ||
701 | * @param priv A pointer to wlan_private structure | ||
702 | * @param req A pointer to ifreq structure | ||
703 | * @return 0 --success, otherwise fail | ||
704 | */ | ||
705 | static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req) | ||
706 | { | ||
707 | struct iwreq *wrq = (struct iwreq *)req; | ||
708 | char in_str[8]; | ||
709 | static struct cmd_ds_fwt_access fwt_access; | ||
710 | char *ptr = in_str; | ||
711 | static char out_str[128]; | ||
712 | char *pbuf = out_str; | ||
713 | int ret; | ||
714 | |||
715 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
716 | |||
717 | if (copy_from_user(in_str, wrq->u.data.pointer, sizeof(in_str))) | ||
718 | return -EFAULT; | ||
719 | |||
720 | memset(&fwt_access, 0, sizeof(fwt_access)); | ||
721 | fwt_access.id = cpu_to_le32(simple_strtoul(ptr, &ptr, 10)); | ||
722 | |||
723 | #ifdef DEBUG | ||
724 | { | ||
725 | lbs_deb_ioctl("FWT_LIST_NEIGHBOR: line is %s\n", in_str); | ||
726 | lbs_deb_ioctl("FWT_LIST_NEIGHBOR: listing id:%i\n", le32_to_cpu(fwt_access.id)); | ||
727 | } | ||
728 | #endif | ||
729 | |||
730 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
731 | cmd_act_fwt_access_list_neighbor, | ||
732 | cmd_option_waitforrsp, 0, | ||
733 | (void *)&fwt_access); | ||
734 | |||
735 | if (ret == 0) { | ||
736 | pbuf += sprintf(pbuf, " ra "); | ||
737 | pbuf += eth_addr2str(fwt_access.ra, pbuf); | ||
738 | pbuf += sprintf(pbuf, " slp %u", fwt_access.sleepmode); | ||
739 | pbuf += sprintf(pbuf, " snr %u", le32_to_cpu(fwt_access.snr)); | ||
740 | pbuf += sprintf(pbuf, " ref %u", le32_to_cpu(fwt_access.references)); | ||
741 | } else | ||
742 | pbuf += sprintf(pbuf, " (null)"); | ||
743 | |||
744 | wrq->u.data.length = strlen(out_str); | ||
745 | if (copy_to_user(wrq->u.data.pointer, (char *)out_str, | ||
746 | wrq->u.data.length)) { | ||
747 | lbs_deb_ioctl("FWT_LIST_NEIGHBOR: Copy to user failed!\n"); | ||
748 | return -EFAULT; | ||
749 | } | ||
750 | |||
751 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | /** | ||
756 | * @brief Cleans up the route (FRT) and neighbor (FNT) tables | ||
757 | * (Garbage Collection) | ||
758 | * @param priv A pointer to wlan_private structure | ||
759 | * @param req A pointer to ifreq structure | ||
760 | * @return 0 --success, otherwise fail | ||
761 | */ | ||
762 | static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req) | ||
763 | { | ||
764 | struct iwreq *wrq = (struct iwreq *)req; | ||
765 | static struct cmd_ds_fwt_access fwt_access; | ||
766 | int ret; | ||
767 | |||
768 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
769 | |||
770 | lbs_deb_ioctl("FWT: cleaning up\n"); | ||
771 | |||
772 | memset(&fwt_access, 0, sizeof(fwt_access)); | ||
773 | |||
774 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
775 | cmd_act_fwt_access_cleanup, | ||
776 | cmd_option_waitforrsp, 0, | ||
777 | (void *)&fwt_access); | ||
778 | |||
779 | if (ret == 0) | ||
780 | wrq->u.param.value = le32_to_cpu(fwt_access.references); | ||
781 | else | ||
782 | return -EFAULT; | ||
783 | |||
784 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
785 | return 0; | ||
786 | } | ||
787 | |||
788 | /** | ||
789 | * @brief Gets firmware internal time (debug purposes) | ||
790 | * @param priv A pointer to wlan_private structure | ||
791 | * @param req A pointer to ifreq structure | ||
792 | * @return 0 --success, otherwise fail | ||
793 | */ | ||
794 | static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req) | ||
795 | { | ||
796 | struct iwreq *wrq = (struct iwreq *)req; | ||
797 | static struct cmd_ds_fwt_access fwt_access; | ||
798 | int ret; | ||
799 | |||
800 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
801 | |||
802 | lbs_deb_ioctl("FWT: getting time\n"); | ||
803 | |||
804 | memset(&fwt_access, 0, sizeof(fwt_access)); | ||
805 | |||
806 | ret = libertas_prepare_and_send_command(priv, cmd_fwt_access, | ||
807 | cmd_act_fwt_access_time, | ||
808 | cmd_option_waitforrsp, 0, | ||
809 | (void *)&fwt_access); | ||
810 | |||
811 | if (ret == 0) | ||
812 | wrq->u.param.value = le32_to_cpu(fwt_access.references); | ||
813 | else | ||
814 | return -EFAULT; | ||
815 | |||
816 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
817 | return 0; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * @brief Gets mesh ttl from firmware | ||
822 | * @param priv A pointer to wlan_private structure | ||
823 | * @param req A pointer to ifreq structure | ||
824 | * @return 0 --success, otherwise fail | ||
825 | */ | ||
826 | static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req) | ||
827 | { | ||
828 | struct iwreq *wrq = (struct iwreq *)req; | ||
829 | struct cmd_ds_mesh_access mesh_access; | ||
830 | int ret; | ||
831 | |||
832 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
833 | |||
834 | memset(&mesh_access, 0, sizeof(mesh_access)); | ||
835 | |||
836 | ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, | ||
837 | cmd_act_mesh_get_ttl, | ||
838 | cmd_option_waitforrsp, 0, | ||
839 | (void *)&mesh_access); | ||
840 | |||
841 | if (ret == 0) | ||
842 | wrq->u.param.value = le32_to_cpu(mesh_access.data[0]); | ||
843 | else | ||
844 | return -EFAULT; | ||
845 | |||
846 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
847 | return 0; | ||
848 | } | ||
849 | |||
850 | /** | ||
851 | * @brief Gets mesh ttl from firmware | ||
852 | * @param priv A pointer to wlan_private structure | ||
853 | * @param ttl New ttl value | ||
854 | * @return 0 --success, otherwise fail | ||
855 | */ | ||
856 | static int wlan_mesh_set_ttl_ioctl(wlan_private * priv, int ttl) | ||
857 | { | ||
858 | struct cmd_ds_mesh_access mesh_access; | ||
859 | int ret; | ||
860 | |||
861 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
862 | |||
863 | if( (ttl > 0xff) || (ttl < 0) ) | ||
864 | return -EINVAL; | ||
865 | |||
866 | memset(&mesh_access, 0, sizeof(mesh_access)); | ||
867 | mesh_access.data[0] = cpu_to_le32(ttl); | ||
868 | |||
869 | ret = libertas_prepare_and_send_command(priv, cmd_mesh_access, | ||
870 | cmd_act_mesh_set_ttl, | ||
871 | cmd_option_waitforrsp, 0, | ||
872 | (void *)&mesh_access); | ||
873 | |||
874 | if (ret != 0) | ||
875 | ret = -EFAULT; | ||
876 | |||
877 | lbs_deb_leave(LBS_DEB_IOCTL); | ||
878 | return ret; | ||
879 | } | ||
880 | |||
881 | /** | ||
882 | * @brief ioctl function - entry point | ||
883 | * | ||
884 | * @param dev A pointer to net_device structure | ||
885 | * @param req A pointer to ifreq structure | ||
886 | * @param cmd command | ||
887 | * @return 0--success, otherwise fail | ||
888 | */ | ||
889 | int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd) | ||
890 | { | ||
891 | int subcmd = 0; | ||
892 | int idata = 0; | ||
893 | int *pdata; | ||
894 | int ret = 0; | ||
895 | wlan_private *priv = dev->priv; | ||
896 | wlan_adapter *adapter = priv->adapter; | ||
897 | struct iwreq *wrq = (struct iwreq *)req; | ||
898 | |||
899 | lbs_deb_enter(LBS_DEB_IOCTL); | ||
900 | |||
901 | lbs_deb_ioctl("libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd); | ||
902 | switch (cmd) { | ||
903 | case WLAN_SETNONE_GETNONE: /* set WPA mode on/off ioctl #20 */ | ||
904 | switch (wrq->u.data.flags) { | ||
905 | case WLAN_SUBCMD_BT_RESET: /* bt_reset */ | ||
906 | wlan_bt_reset_ioctl(priv); | ||
907 | break; | ||
908 | case WLAN_SUBCMD_FWT_RESET: /* fwt_reset */ | ||
909 | wlan_fwt_reset_ioctl(priv); | ||
910 | break; | ||
911 | } /* End of switch */ | ||
912 | break; | ||
913 | |||
914 | case WLAN_SETONEINT_GETNONE: | ||
915 | /* The first 4 bytes of req->ifr_data is sub-ioctl number | ||
916 | * after 4 bytes sits the payload. | ||
917 | */ | ||
918 | subcmd = wrq->u.data.flags; | ||
919 | if (!subcmd) | ||
920 | subcmd = (int)wrq->u.param.value; | ||
921 | |||
922 | switch (subcmd) { | ||
923 | case WLANSETREGION: | ||
924 | idata = SUBCMD_DATA(wrq); | ||
925 | ret = wlan_set_region(priv, (u16) idata); | ||
926 | break; | ||
927 | case WLAN_SUBCMD_MESH_SET_TTL: | ||
928 | idata = SUBCMD_DATA(wrq); | ||
929 | ret = wlan_mesh_set_ttl_ioctl(priv, idata); | ||
930 | break; | ||
931 | |||
932 | case WLAN_SUBCMD_BT_SET_INVERT: | ||
933 | ret = wlan_bt_set_invert_ioctl(priv, req); | ||
934 | break ; | ||
935 | |||
936 | default: | ||
937 | ret = -EOPNOTSUPP; | ||
938 | break; | ||
939 | } | ||
940 | |||
941 | break; | ||
942 | |||
943 | case WLAN_SET128CHAR_GET128CHAR: | ||
944 | switch ((int)wrq->u.data.flags) { | ||
945 | case WLAN_SUBCMD_BT_ADD: | ||
946 | ret = wlan_bt_add_ioctl(priv, req); | ||
947 | break; | ||
948 | case WLAN_SUBCMD_BT_DEL: | ||
949 | ret = wlan_bt_del_ioctl(priv, req); | ||
950 | break; | ||
951 | case WLAN_SUBCMD_BT_LIST: | ||
952 | ret = wlan_bt_list_ioctl(priv, req); | ||
953 | break; | ||
954 | case WLAN_SUBCMD_FWT_ADD: | ||
955 | ret = wlan_fwt_add_ioctl(priv, req); | ||
956 | break; | ||
957 | case WLAN_SUBCMD_FWT_DEL: | ||
958 | ret = wlan_fwt_del_ioctl(priv, req); | ||
959 | break; | ||
960 | case WLAN_SUBCMD_FWT_LOOKUP: | ||
961 | ret = wlan_fwt_lookup_ioctl(priv, req); | ||
962 | break; | ||
963 | case WLAN_SUBCMD_FWT_LIST_NEIGHBOR: | ||
964 | ret = wlan_fwt_list_neighbor_ioctl(priv, req); | ||
965 | break; | ||
966 | case WLAN_SUBCMD_FWT_LIST: | ||
967 | ret = wlan_fwt_list_ioctl(priv, req); | ||
968 | break; | ||
969 | case WLAN_SUBCMD_FWT_LIST_ROUTE: | ||
970 | ret = wlan_fwt_list_route_ioctl(priv, req); | ||
971 | break; | ||
972 | } | ||
973 | break; | ||
974 | |||
975 | case WLAN_SETNONE_GETONEINT: | ||
976 | switch (wrq->u.param.value) { | ||
977 | case WLANGETREGION: | ||
978 | pdata = (int *)wrq->u.name; | ||
979 | *pdata = (int)adapter->regioncode; | ||
980 | break; | ||
981 | case WLAN_SUBCMD_FWT_CLEANUP: /* fwt_cleanup */ | ||
982 | ret = wlan_fwt_cleanup_ioctl(priv, req); | ||
983 | break; | ||
984 | |||
985 | case WLAN_SUBCMD_FWT_TIME: /* fwt_time */ | ||
986 | ret = wlan_fwt_time_ioctl(priv, req); | ||
987 | break; | ||
988 | |||
989 | case WLAN_SUBCMD_MESH_GET_TTL: | ||
990 | ret = wlan_mesh_get_ttl_ioctl(priv, req); | ||
991 | break; | ||
992 | |||
993 | case WLAN_SUBCMD_BT_GET_INVERT: | ||
994 | ret = wlan_bt_get_invert_ioctl(priv, req); | ||
995 | break ; | ||
996 | |||
997 | default: | ||
998 | ret = -EOPNOTSUPP; | ||
999 | |||
1000 | } | ||
1001 | |||
1002 | break; | ||
1003 | |||
1004 | case WLAN_SET_GET_SIXTEEN_INT: | ||
1005 | switch ((int)wrq->u.data.flags) { | ||
1006 | case WLAN_LED_GPIO_CTRL: | ||
1007 | { | ||
1008 | int i; | ||
1009 | int data[16]; | ||
1010 | |||
1011 | struct cmd_ds_802_11_led_ctrl ctrl; | ||
1012 | struct mrvlietypes_ledgpio *gpio = | ||
1013 | (struct mrvlietypes_ledgpio *) ctrl.data; | ||
1014 | |||
1015 | memset(&ctrl, 0, sizeof(ctrl)); | ||
1016 | if (wrq->u.data.length > MAX_LEDS * 2) | ||
1017 | return -ENOTSUPP; | ||
1018 | if ((wrq->u.data.length % 2) != 0) | ||
1019 | return -ENOTSUPP; | ||
1020 | if (wrq->u.data.length == 0) { | ||
1021 | ctrl.action = | ||
1022 | cpu_to_le16 | ||
1023 | (cmd_act_get); | ||
1024 | } else { | ||
1025 | if (copy_from_user | ||
1026 | (data, wrq->u.data.pointer, | ||
1027 | sizeof(int) * | ||
1028 | wrq->u.data.length)) { | ||
1029 | lbs_deb_ioctl( | ||
1030 | "Copy from user failed\n"); | ||
1031 | return -EFAULT; | ||
1032 | } | ||
1033 | |||
1034 | ctrl.action = | ||
1035 | cpu_to_le16 | ||
1036 | (cmd_act_set); | ||
1037 | ctrl.numled = cpu_to_le16(0); | ||
1038 | gpio->header.type = | ||
1039 | cpu_to_le16(TLV_TYPE_LED_GPIO); | ||
1040 | gpio->header.len = wrq->u.data.length; | ||
1041 | for (i = 0; i < wrq->u.data.length; | ||
1042 | i += 2) { | ||
1043 | gpio->ledpin[i / 2].led = | ||
1044 | data[i]; | ||
1045 | gpio->ledpin[i / 2].pin = | ||
1046 | data[i + 1]; | ||
1047 | } | ||
1048 | } | ||
1049 | ret = | ||
1050 | libertas_prepare_and_send_command(priv, | ||
1051 | cmd_802_11_led_gpio_ctrl, | ||
1052 | 0, | ||
1053 | cmd_option_waitforrsp, | ||
1054 | 0, (void *)&ctrl); | ||
1055 | for (i = 0; i < gpio->header.len; i += 2) { | ||
1056 | data[i] = gpio->ledpin[i / 2].led; | ||
1057 | data[i + 1] = gpio->ledpin[i / 2].pin; | ||
1058 | } | ||
1059 | if (copy_to_user(wrq->u.data.pointer, data, | ||
1060 | sizeof(int) * | ||
1061 | gpio->header.len)) { | ||
1062 | lbs_deb_ioctl("Copy to user failed\n"); | ||
1063 | return -EFAULT; | ||
1064 | } | ||
1065 | |||
1066 | wrq->u.data.length = gpio->header.len; | ||
1067 | } | ||
1068 | break; | ||
1069 | } | ||
1070 | break; | ||
1071 | |||
1072 | default: | ||
1073 | ret = -EINVAL; | ||
1074 | break; | ||
1075 | } | ||
1076 | |||
1077 | lbs_deb_leave_args(LBS_DEB_IOCTL, "ret %d", ret); | ||
1078 | return ret; | ||
1079 | } | ||
1080 | |||
1081 | |||
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 623ab4b16973..4a59306a3f05 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -181,7 +181,8 @@ u16 libertas_region_code_to_index[MRVDRV_MAX_REGION_CODE] = | |||
181 | * @brief Get function for sysfs attribute anycast_mask | 181 | * @brief Get function for sysfs attribute anycast_mask |
182 | */ | 182 | */ |
183 | static ssize_t libertas_anycast_get(struct device * dev, | 183 | static ssize_t libertas_anycast_get(struct device * dev, |
184 | struct device_attribute *attr, char * buf) { | 184 | struct device_attribute *attr, char * buf) |
185 | { | ||
185 | struct cmd_ds_mesh_access mesh_access; | 186 | struct cmd_ds_mesh_access mesh_access; |
186 | 187 | ||
187 | memset(&mesh_access, 0, sizeof(mesh_access)); | 188 | memset(&mesh_access, 0, sizeof(mesh_access)); |
@@ -197,7 +198,8 @@ static ssize_t libertas_anycast_get(struct device * dev, | |||
197 | * @brief Set function for sysfs attribute anycast_mask | 198 | * @brief Set function for sysfs attribute anycast_mask |
198 | */ | 199 | */ |
199 | static ssize_t libertas_anycast_set(struct device * dev, | 200 | static ssize_t libertas_anycast_set(struct device * dev, |
200 | struct device_attribute *attr, const char * buf, size_t count) { | 201 | struct device_attribute *attr, const char * buf, size_t count) |
202 | { | ||
201 | struct cmd_ds_mesh_access mesh_access; | 203 | struct cmd_ds_mesh_access mesh_access; |
202 | uint32_t datum; | 204 | uint32_t datum; |
203 | 205 | ||
@@ -799,7 +801,6 @@ wlan_private *libertas_add_card(void *card, struct device *dmdev) | |||
799 | dev->open = wlan_open; | 801 | dev->open = wlan_open; |
800 | dev->hard_start_xmit = wlan_pre_start_xmit; | 802 | dev->hard_start_xmit = wlan_pre_start_xmit; |
801 | dev->stop = wlan_close; | 803 | dev->stop = wlan_close; |
802 | dev->do_ioctl = libertas_do_ioctl; | ||
803 | dev->set_mac_address = wlan_set_mac_address; | 804 | dev->set_mac_address = wlan_set_mac_address; |
804 | dev->tx_timeout = wlan_tx_timeout; | 805 | dev->tx_timeout = wlan_tx_timeout; |
805 | dev->get_stats = wlan_get_stats; | 806 | dev->get_stats = wlan_get_stats; |
@@ -918,7 +919,6 @@ int libertas_add_mesh(wlan_private *priv, struct device *dev) | |||
918 | mesh_dev->open = mesh_open; | 919 | mesh_dev->open = mesh_open; |
919 | mesh_dev->hard_start_xmit = mesh_pre_start_xmit; | 920 | mesh_dev->hard_start_xmit = mesh_pre_start_xmit; |
920 | mesh_dev->stop = mesh_close; | 921 | mesh_dev->stop = mesh_close; |
921 | mesh_dev->do_ioctl = libertas_do_ioctl; | ||
922 | mesh_dev->get_stats = wlan_get_stats; | 922 | mesh_dev->get_stats = wlan_get_stats; |
923 | mesh_dev->set_mac_address = wlan_set_mac_address; | 923 | mesh_dev->set_mac_address = wlan_set_mac_address; |
924 | mesh_dev->ethtool_ops = &libertas_ethtool_ops; | 924 | mesh_dev->ethtool_ops = &libertas_ethtool_ops; |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index 606af50fa09b..c3043dcb541e 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -215,38 +215,6 @@ done: | |||
215 | } | 215 | } |
216 | 216 | ||
217 | /** | 217 | /** |
218 | * @brief Post process the scan table after a new scan command has completed | ||
219 | * | ||
220 | * Inspect each entry of the scan table and try to find an entry that | ||
221 | * matches our current associated/joined network from the scan. If | ||
222 | * one is found, update the stored copy of the bssdescriptor for our | ||
223 | * current network. | ||
224 | * | ||
225 | * Debug dump the current scan table contents if compiled accordingly. | ||
226 | * | ||
227 | * @param priv A pointer to wlan_private structure | ||
228 | * | ||
229 | * @return void | ||
230 | */ | ||
231 | static void wlan_scan_process_results(wlan_private * priv) | ||
232 | { | ||
233 | wlan_adapter *adapter = priv->adapter; | ||
234 | struct bss_descriptor * iter_bss; | ||
235 | int i = 0; | ||
236 | |||
237 | if (adapter->connect_status == libertas_connected) | ||
238 | return; | ||
239 | |||
240 | mutex_lock(&adapter->lock); | ||
241 | list_for_each_entry (iter_bss, &adapter->network_list, list) { | ||
242 | lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", | ||
243 | i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, | ||
244 | escape_essid(iter_bss->ssid, iter_bss->ssid_len)); | ||
245 | } | ||
246 | mutex_unlock(&adapter->lock); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * @brief Create a channel list for the driver to scan based on region info | 218 | * @brief Create a channel list for the driver to scan based on region info |
251 | * | 219 | * |
252 | * Use the driver region/band information to construct a comprehensive list | 220 | * Use the driver region/band information to construct a comprehensive list |
@@ -791,6 +759,10 @@ int wlan_scan_networks(wlan_private * priv, | |||
791 | u8 scancurrentchanonly; | 759 | u8 scancurrentchanonly; |
792 | int maxchanperscan; | 760 | int maxchanperscan; |
793 | int ret; | 761 | int ret; |
762 | #ifdef CONFIG_LIBERTAS_DEBUG | ||
763 | struct bss_descriptor * iter_bss; | ||
764 | int i = 0; | ||
765 | #endif | ||
794 | 766 | ||
795 | lbs_deb_enter(LBS_DEB_ASSOC); | 767 | lbs_deb_enter(LBS_DEB_ASSOC); |
796 | 768 | ||
@@ -832,11 +804,16 @@ int wlan_scan_networks(wlan_private * priv, | |||
832 | puserscanin, | 804 | puserscanin, |
833 | full_scan); | 805 | full_scan); |
834 | 806 | ||
835 | /* Process the resulting scan table: | 807 | #ifdef CONFIG_LIBERTAS_DEBUG |
836 | * - Remove any bad ssids | 808 | /* Dump the scan table */ |
837 | * - Update our current BSS information from scan data | 809 | mutex_lock(&adapter->lock); |
838 | */ | 810 | list_for_each_entry (iter_bss, &adapter->network_list, list) { |
839 | wlan_scan_process_results(priv); | 811 | lbs_deb_scan("Scan:(%02d) " MAC_FMT ", RSSI[%03d], SSID[%s]\n", |
812 | i++, MAC_ARG(iter_bss->bssid), (s32) iter_bss->rssi, | ||
813 | escape_essid(iter_bss->ssid, iter_bss->ssid_len)); | ||
814 | } | ||
815 | mutex_unlock(&adapter->lock); | ||
816 | #endif | ||
840 | 817 | ||
841 | if (priv->adapter->connect_status == libertas_connected) { | 818 | if (priv->adapter->connect_status == libertas_connected) { |
842 | netif_carrier_on(priv->dev); | 819 | netif_carrier_on(priv->dev); |
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c index 8939251a2f4c..f42b796b5e47 100644 --- a/drivers/net/wireless/libertas/wext.c +++ b/drivers/net/wireless/libertas/wext.c | |||
@@ -913,148 +913,6 @@ out: | |||
913 | return 0; | 913 | return 0; |
914 | } | 914 | } |
915 | 915 | ||
916 | /* | ||
917 | * iwpriv settable callbacks | ||
918 | */ | ||
919 | |||
920 | static const iw_handler wlan_private_handler[] = { | ||
921 | NULL, /* SIOCIWFIRSTPRIV */ | ||
922 | }; | ||
923 | |||
924 | static const struct iw_priv_args wlan_private_args[] = { | ||
925 | /* | ||
926 | * { cmd, set_args, get_args, name } | ||
927 | */ | ||
928 | /* Using iwpriv sub-command feature */ | ||
929 | { | ||
930 | WLAN_SETONEINT_GETNONE, /* IOCTL: 24 */ | ||
931 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
932 | IW_PRIV_TYPE_NONE, | ||
933 | ""}, | ||
934 | { | ||
935 | WLANSETREGION, | ||
936 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
937 | IW_PRIV_TYPE_NONE, | ||
938 | "setregioncode"}, | ||
939 | { | ||
940 | WLAN_SUBCMD_MESH_SET_TTL, | ||
941 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
942 | IW_PRIV_TYPE_NONE, | ||
943 | "mesh_set_ttl"}, | ||
944 | { | ||
945 | WLAN_SETNONE_GETONEINT, | ||
946 | IW_PRIV_TYPE_NONE, | ||
947 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
948 | ""}, | ||
949 | { | ||
950 | WLANGETREGION, | ||
951 | IW_PRIV_TYPE_NONE, | ||
952 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
953 | "getregioncode"}, | ||
954 | { | ||
955 | WLAN_SUBCMD_FWT_CLEANUP, | ||
956 | IW_PRIV_TYPE_NONE, | ||
957 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
958 | "fwt_cleanup"}, | ||
959 | { | ||
960 | WLAN_SUBCMD_FWT_TIME, | ||
961 | IW_PRIV_TYPE_NONE, | ||
962 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
963 | "fwt_time"}, | ||
964 | { | ||
965 | WLAN_SUBCMD_MESH_GET_TTL, | ||
966 | IW_PRIV_TYPE_NONE, | ||
967 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
968 | "mesh_get_ttl"}, | ||
969 | { | ||
970 | WLAN_SETNONE_GETNONE, | ||
971 | IW_PRIV_TYPE_NONE, | ||
972 | IW_PRIV_TYPE_NONE, | ||
973 | ""}, | ||
974 | { | ||
975 | WLAN_SUBCMD_FWT_RESET, | ||
976 | IW_PRIV_TYPE_NONE, | ||
977 | IW_PRIV_TYPE_NONE, | ||
978 | "fwt_reset"}, | ||
979 | { | ||
980 | WLAN_SUBCMD_BT_RESET, | ||
981 | IW_PRIV_TYPE_NONE, | ||
982 | IW_PRIV_TYPE_NONE, | ||
983 | "bt_reset"}, | ||
984 | { | ||
985 | WLAN_SET128CHAR_GET128CHAR, | ||
986 | IW_PRIV_TYPE_CHAR | 128, | ||
987 | IW_PRIV_TYPE_CHAR | 128, | ||
988 | ""}, | ||
989 | /* BT Management */ | ||
990 | { | ||
991 | WLAN_SUBCMD_BT_ADD, | ||
992 | IW_PRIV_TYPE_CHAR | 128, | ||
993 | IW_PRIV_TYPE_CHAR | 128, | ||
994 | "bt_add"}, | ||
995 | { | ||
996 | WLAN_SUBCMD_BT_DEL, | ||
997 | IW_PRIV_TYPE_CHAR | 128, | ||
998 | IW_PRIV_TYPE_CHAR | 128, | ||
999 | "bt_del"}, | ||
1000 | { | ||
1001 | WLAN_SUBCMD_BT_LIST, | ||
1002 | IW_PRIV_TYPE_CHAR | 128, | ||
1003 | IW_PRIV_TYPE_CHAR | 128, | ||
1004 | "bt_list"}, | ||
1005 | { | ||
1006 | WLAN_SUBCMD_BT_SET_INVERT, | ||
1007 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
1008 | IW_PRIV_TYPE_NONE, | ||
1009 | "bt_set_invert"}, | ||
1010 | { | ||
1011 | WLAN_SUBCMD_BT_GET_INVERT, | ||
1012 | IW_PRIV_TYPE_NONE, | ||
1013 | IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | ||
1014 | "bt_get_invert"}, | ||
1015 | /* FWT Management */ | ||
1016 | { | ||
1017 | WLAN_SUBCMD_FWT_ADD, | ||
1018 | IW_PRIV_TYPE_CHAR | 128, | ||
1019 | IW_PRIV_TYPE_CHAR | 128, | ||
1020 | "fwt_add"}, | ||
1021 | { | ||
1022 | WLAN_SUBCMD_FWT_DEL, | ||
1023 | IW_PRIV_TYPE_CHAR | 128, | ||
1024 | IW_PRIV_TYPE_CHAR | 128, | ||
1025 | "fwt_del"}, | ||
1026 | { | ||
1027 | WLAN_SUBCMD_FWT_LOOKUP, | ||
1028 | IW_PRIV_TYPE_CHAR | 128, | ||
1029 | IW_PRIV_TYPE_CHAR | 128, | ||
1030 | "fwt_lookup"}, | ||
1031 | { | ||
1032 | WLAN_SUBCMD_FWT_LIST_NEIGHBOR, | ||
1033 | IW_PRIV_TYPE_CHAR | 128, | ||
1034 | IW_PRIV_TYPE_CHAR | 128, | ||
1035 | "fwt_list_neigh"}, | ||
1036 | { | ||
1037 | WLAN_SUBCMD_FWT_LIST, | ||
1038 | IW_PRIV_TYPE_CHAR | 128, | ||
1039 | IW_PRIV_TYPE_CHAR | 128, | ||
1040 | "fwt_list"}, | ||
1041 | { | ||
1042 | WLAN_SUBCMD_FWT_LIST_ROUTE, | ||
1043 | IW_PRIV_TYPE_CHAR | 128, | ||
1044 | IW_PRIV_TYPE_CHAR | 128, | ||
1045 | "fwt_list_route"}, | ||
1046 | { | ||
1047 | WLAN_SET_GET_SIXTEEN_INT, | ||
1048 | IW_PRIV_TYPE_INT | 16, | ||
1049 | IW_PRIV_TYPE_INT | 16, | ||
1050 | ""}, | ||
1051 | { | ||
1052 | WLAN_LED_GPIO_CTRL, | ||
1053 | IW_PRIV_TYPE_INT | 16, | ||
1054 | IW_PRIV_TYPE_INT | 16, | ||
1055 | "ledgpio"}, | ||
1056 | }; | ||
1057 | |||
1058 | static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) | 916 | static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev) |
1059 | { | 917 | { |
1060 | enum { | 918 | enum { |
@@ -2444,22 +2302,12 @@ static const iw_handler mesh_wlan_handler[] = { | |||
2444 | }; | 2302 | }; |
2445 | struct iw_handler_def libertas_handler_def = { | 2303 | struct iw_handler_def libertas_handler_def = { |
2446 | .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), | 2304 | .num_standard = sizeof(wlan_handler) / sizeof(iw_handler), |
2447 | .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), | ||
2448 | .num_private_args = sizeof(wlan_private_args) / | ||
2449 | sizeof(struct iw_priv_args), | ||
2450 | .standard = (iw_handler *) wlan_handler, | 2305 | .standard = (iw_handler *) wlan_handler, |
2451 | .private = (iw_handler *) wlan_private_handler, | ||
2452 | .private_args = (struct iw_priv_args *)wlan_private_args, | ||
2453 | .get_wireless_stats = wlan_get_wireless_stats, | 2306 | .get_wireless_stats = wlan_get_wireless_stats, |
2454 | }; | 2307 | }; |
2455 | 2308 | ||
2456 | struct iw_handler_def mesh_handler_def = { | 2309 | struct iw_handler_def mesh_handler_def = { |
2457 | .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), | 2310 | .num_standard = sizeof(mesh_wlan_handler) / sizeof(iw_handler), |
2458 | .num_private = sizeof(wlan_private_handler) / sizeof(iw_handler), | ||
2459 | .num_private_args = sizeof(wlan_private_args) / | ||
2460 | sizeof(struct iw_priv_args), | ||
2461 | .standard = (iw_handler *) mesh_wlan_handler, | 2311 | .standard = (iw_handler *) mesh_wlan_handler, |
2462 | .private = (iw_handler *) wlan_private_handler, | ||
2463 | .private_args = (struct iw_priv_args *)wlan_private_args, | ||
2464 | .get_wireless_stats = wlan_get_wireless_stats, | 2312 | .get_wireless_stats = wlan_get_wireless_stats, |
2465 | }; | 2313 | }; |
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h index d555056b25b7..3d5196c9553a 100644 --- a/drivers/net/wireless/libertas/wext.h +++ b/drivers/net/wireless/libertas/wext.h | |||
@@ -7,45 +7,6 @@ | |||
7 | #define SUBCMD_OFFSET 4 | 7 | #define SUBCMD_OFFSET 4 |
8 | #define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) | 8 | #define SUBCMD_DATA(x) *((int *)(x->u.name + SUBCMD_OFFSET)) |
9 | 9 | ||
10 | /** PRIVATE CMD ID */ | ||
11 | #define WLANIOCTL SIOCIWFIRSTPRIV | ||
12 | |||
13 | #define WLAN_SETNONE_GETNONE (WLANIOCTL + 8) | ||
14 | #define WLAN_SUBCMD_BT_RESET 13 | ||
15 | #define WLAN_SUBCMD_FWT_RESET 14 | ||
16 | |||
17 | #define WLAN_SETNONE_GETONEINT (WLANIOCTL + 15) | ||
18 | #define WLANGETREGION 1 | ||
19 | |||
20 | #define WLAN_SUBCMD_FWT_CLEANUP 15 | ||
21 | #define WLAN_SUBCMD_FWT_TIME 16 | ||
22 | #define WLAN_SUBCMD_MESH_GET_TTL 17 | ||
23 | #define WLAN_SUBCMD_BT_GET_INVERT 18 | ||
24 | |||
25 | #define WLAN_SETONEINT_GETNONE (WLANIOCTL + 24) | ||
26 | #define WLANSETREGION 8 | ||
27 | #define WLAN_SUBCMD_MESH_SET_TTL 18 | ||
28 | #define WLAN_SUBCMD_BT_SET_INVERT 19 | ||
29 | |||
30 | #define WLAN_SET128CHAR_GET128CHAR (WLANIOCTL + 25) | ||
31 | #define WLAN_SUBCMD_BT_ADD 18 | ||
32 | #define WLAN_SUBCMD_BT_DEL 19 | ||
33 | #define WLAN_SUBCMD_BT_LIST 20 | ||
34 | #define WLAN_SUBCMD_FWT_ADD 21 | ||
35 | #define WLAN_SUBCMD_FWT_DEL 22 | ||
36 | #define WLAN_SUBCMD_FWT_LOOKUP 23 | ||
37 | #define WLAN_SUBCMD_FWT_LIST_NEIGHBOR 24 | ||
38 | #define WLAN_SUBCMD_FWT_LIST 25 | ||
39 | #define WLAN_SUBCMD_FWT_LIST_ROUTE 26 | ||
40 | |||
41 | #define WLAN_SET_GET_SIXTEEN_INT (WLANIOCTL + 29) | ||
42 | #define WLAN_LED_GPIO_CTRL 5 | ||
43 | |||
44 | #define WLAN_LINKMODE_802_3 0 | ||
45 | #define WLAN_LINKMODE_802_11 2 | ||
46 | #define WLAN_RADIOMODE_NONE 0 | ||
47 | #define WLAN_RADIOMODE_RADIOTAP 2 | ||
48 | |||
49 | /** wlan_ioctl_regrdwr */ | 10 | /** wlan_ioctl_regrdwr */ |
50 | struct wlan_ioctl_regrdwr { | 11 | struct wlan_ioctl_regrdwr { |
51 | /** Which register to access */ | 12 | /** Which register to access */ |
@@ -57,9 +18,13 @@ struct wlan_ioctl_regrdwr { | |||
57 | u32 value; | 18 | u32 value; |
58 | }; | 19 | }; |
59 | 20 | ||
21 | #define WLAN_LINKMODE_802_3 0 | ||
22 | #define WLAN_LINKMODE_802_11 2 | ||
23 | #define WLAN_RADIOMODE_NONE 0 | ||
24 | #define WLAN_RADIOMODE_RADIOTAP 2 | ||
25 | |||
60 | extern struct iw_handler_def libertas_handler_def; | 26 | extern struct iw_handler_def libertas_handler_def; |
61 | extern struct iw_handler_def mesh_handler_def; | 27 | extern struct iw_handler_def mesh_handler_def; |
62 | int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int i); | ||
63 | int wlan_radio_ioctl(wlan_private * priv, u8 option); | 28 | int wlan_radio_ioctl(wlan_private * priv, u8 option); |
64 | 29 | ||
65 | #endif /* _WLAN_WEXT_H_ */ | 30 | #endif /* _WLAN_WEXT_H_ */ |